blob: cff47e613fa0dd3220b7c07ab6598c4787dc23d4 [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 Pedrol9d1cdb12019-09-25 17:47:02 +020025#include "tbf_ul.h"
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010026#include "gprs_debug.h"
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +010027#include "pcu_utils.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020028#include "gprs_bssgp_pcu.h"
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020029#include "pcu_l1_if.h"
aravind sirsikarf2761382016-10-25 12:45:24 +053030#include "decoding.h"
Max1187a772018-01-26 13:31:42 +010031#include <gprs_rlcmac.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010032
33extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020034#include "pcu_vty.h"
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020035#include "coding_scheme.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020036
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010037#include <osmocom/core/application.h>
38#include <osmocom/core/msgb.h>
39#include <osmocom/core/talloc.h>
40#include <osmocom/core/utils.h>
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020041#include <osmocom/vty/vty.h>
Aravind Sirsikar505a86d2016-07-26 18:26:21 +053042#include <osmocom/gprs/protocol/gsm_04_60.h>
bhargava959d1de2016-08-17 15:17:21 +053043#include <osmocom/gsm/l1sap.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010044}
45
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020046#include <errno.h>
47
Philippd935d882016-11-07 13:07:36 +010048#define DUMMY_FN 2654167
49
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010050void *tall_pcu_ctx;
51int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010052bool spoof_mnc_3_digits = false;
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010053
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +070054/* Measurements shared by all unit tests */
55static struct pcu_l1_meas meas;
56
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070057static int bts_handle_rach(BTS *bts, uint16_t ra, uint32_t Fn, int16_t qta)
58{
59 struct rach_ind_params rip = {
60 .burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
61 .is_11bit = false,
62 .ra = ra,
63 .trx_nr = 0,
64 .ts_nr = 0,
65 .rfn = Fn,
66 .qta = qta,
67 };
68
69 return bts->rcv_rach(&rip);
70}
71
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010072static void check_tbf(gprs_rlcmac_tbf *tbf)
73{
74 OSMO_ASSERT(tbf);
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020075 if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE))
Maxee5be3a2017-12-20 17:31:13 +010076 OSMO_ASSERT(tbf->timers_pending(T3191) || tbf->timers_pending(T3193));
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020077 if (tbf->state_is(GPRS_RLCMAC_RELEASING))
Maxee5be3a2017-12-20 17:31:13 +010078 OSMO_ASSERT(tbf->timers_pending(T_MAX));
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010079}
80
Jacob Erlbeckac89a552015-06-29 14:18:46 +020081static void test_tbf_base()
82{
83
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020084 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020085
86 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
87 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
88
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020089 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020090}
91
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010092static void test_tbf_tlli_update()
93{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +010094 the_pcu->bts = bts_alloc(the_pcu);
95 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck93990462015-05-15 15:50:43 +020096 GprsMs *ms, *ms_new;
97
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020098 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +010099
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100100 the_pcu->alloc_algorithm = alloc_algorithm_a;
101 the_bts->bts_data()->trx[0].pdch[2].enable();
102 the_bts->bts_data()->trx[0].pdch[3].enable();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100103
104 /*
105 * Make a uplink and downlink allocation
106 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100107 ms = the_bts->ms_alloc(0, 0);
108 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts->bts_data(),
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200109 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200110 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200111 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200112 dl_tbf->set_ta(4);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100113 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200114 OSMO_ASSERT(dl_tbf->ms() == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100115
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100116 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts->bts_data(),
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200117 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200118 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200119 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100120 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200121 OSMO_ASSERT(ul_tbf->ms() == ms);
122
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100123 OSMO_ASSERT(the_bts->ms_by_tlli(0x2342) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100124
125 /*
126 * Now check.. that DL changes and that the timing advance
127 * has changed.
128 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200129 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100130
Jacob Erlbeck93990462015-05-15 15:50:43 +0200131 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100132 ms_new = the_bts->ms_by_tlli(0x2342);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200133 OSMO_ASSERT(ms == ms_new);
134
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100135 ms_new = the_bts->ms_by_tlli(0x4232);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200136 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100137 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
138 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200139
140 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200141 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100142 ms_new = the_bts->ms_by_tlli(0x2342);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200143 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100144
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100145 ms_new = the_bts->ms_by_tlli(0x4232);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200146 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100147 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200148
149 OSMO_ASSERT(ul_tbf->ta() == 4);
150 OSMO_ASSERT(dl_tbf->ta() == 4);
151
152 ul_tbf->set_ta(6);
153
154 OSMO_ASSERT(ul_tbf->ta() == 6);
155 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100156
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200157 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100158 TALLOC_FREE(the_pcu->bts);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100159}
160
Daniel Willmann510d7d32014-08-15 18:19:41 +0200161static uint8_t llc_data[200];
162
Maxa2961182018-01-25 19:47:28 +0100163/* override, requires '-Wl,--wrap=pcu_sock_send' */
164int __real_pcu_sock_send(struct msgb *msg);
165int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200166{
167 return 0;
168}
169
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200170static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100171{
172 gprs_rlcmac_bts *bts;
173 gprs_rlcmac_trx *trx;
174
175 bts = the_bts->bts_data();
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100176 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200177 bts->initial_cs_dl = cs;
178 bts->initial_cs_ul = cs;
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200179 osmo_tdef_set(bts->T_defs_pcu, -2030, 0, OSMO_TDEF_S);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200180 osmo_tdef_set(bts->T_defs_pcu, -2031, 0, OSMO_TDEF_S);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100181 trx = &bts->trx[0];
182
183 trx->pdch[ts_no].enable();
Philippd935d882016-11-07 13:07:36 +0100184 the_bts->set_current_frame_number(DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100185}
186
187static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100188 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100189{
190 gprs_rlcmac_bts *bts;
191 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
196 bts = the_bts->bts_data();
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200197 ms = the_bts->ms_alloc(ms_class, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100198
199 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
200 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200201 dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100202 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200203 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100204 check_tbf(dl_tbf);
205
206 /* "Establish" the DL TBF */
Max0e599802018-01-23 20:09:06 +0100207 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
Max2399b1d2018-01-12 15:48:12 +0100208 TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_FLOW);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100209 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100210 check_tbf(dl_tbf);
211
212 *trx_no_ = trx_no;
213
214 return dl_tbf;
215}
216
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200217static unsigned fn2bn(unsigned fn)
218{
219 return (fn % 52) / 4;
220}
221
222static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
223{
224 unsigned bn = fn2bn(fn) + blocks;
225 fn = fn - (fn % 52);
226 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200227 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200228}
229
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200230static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200231 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200232 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100233{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200234 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200235 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200236 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200237 bn += 1;
238 if (block_nr)
239 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100240}
241
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200242static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200243 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200244{
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200245 request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200246 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200247}
248
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100249enum test_tbf_final_ack_mode {
250 TEST_MODE_STANDARD,
251 TEST_MODE_REVERSE_FREE
252};
253
254static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200255{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100256 the_pcu->bts = bts_alloc(the_pcu);
257 BTS *the_bts = the_pcu->bts;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100258 uint8_t ts_no = 4;
259 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200260 uint8_t ms_class = 45;
261 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100262 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100263 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200264 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200265 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200266
267 uint8_t rbb[64/8];
268
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200269 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100270
Daniel Willmann510d7d32014-08-15 18:19:41 +0200271 gprs_rlcmac_dl_tbf *dl_tbf;
272 gprs_rlcmac_tbf *new_tbf;
273
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100274 setup_bts(the_bts, ts_no);
275 dl_tbf = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200276 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200277 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200278
279 for (i = 0; i < sizeof(llc_data); i++)
280 llc_data[i] = i%256;
281
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100282 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100283 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
284 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200285
286
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100287 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200288 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200289 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200290 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200291 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200292 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200293
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100294 OSMO_ASSERT(dl_tbf->have_data());
295 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200296
297 /* Queue a final ACK */
298 memset(rbb, 0, sizeof(rbb));
299 /* Receive a final ACK */
Max7df82d42017-12-15 11:14:30 +0100300 dl_tbf->rcvd_dl_ack(true, 1, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200301
302 /* Clean up and ensure tbfs are in the correct state */
303 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100304 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100305 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200306 OSMO_ASSERT(new_tbf != dl_tbf);
307 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100308 check_tbf(dl_tbf);
Max0e599802018-01-23 20:09:06 +0100309 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100310 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100311 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100312 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100313 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100314 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100315 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100316 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100317 } else {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100318 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100319 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100320 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100321 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100322 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100323 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
324 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100325 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100326
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100327 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200328 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200329}
330
Max7d32f552017-12-15 11:25:14 +0100331/* Receive an ACK */
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200332#define RCV_ACK(fin, tbf, rbb) do { \
333 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
334 tbf->rcvd_dl_ack(fin, w->v_s(), rbb); \
Max7d32f552017-12-15 11:25:14 +0100335 if (!fin) \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200336 OSMO_ASSERT(w->window_empty()); \
Max7d32f552017-12-15 11:25:14 +0100337 } while(0)
338
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100339static void test_tbf_delayed_release()
340{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100341 the_pcu->bts = bts_alloc(the_pcu);
342 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100343 gprs_rlcmac_bts *bts;
344 uint8_t ts_no = 4;
345 unsigned i;
346 uint8_t ms_class = 45;
347 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100348 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200349 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200350 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100351
352 uint8_t rbb[64/8];
353
354 gprs_rlcmac_dl_tbf *dl_tbf;
355
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200356 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100357
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100358 bts = the_bts->bts_data();
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100359
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100360 setup_bts(the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200361 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100362
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100363 dl_tbf = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200364 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100365
366 for (i = 0; i < sizeof(llc_data); i++)
367 llc_data[i] = i%256;
368
369 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
370
371 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100372 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
373 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100374
375 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
376
377 /* Drain the queue */
378 while (dl_tbf->have_data())
379 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200380 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100381
382 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
383
384 /* ACK all blocks */
385 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100386
387 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100388
389 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200390 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100391
Max7d32f552017-12-15 11:25:14 +0100392 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100393
394 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200395 dl_tbf_idle_msec = osmo_tdef_get(bts->T_defs_pcu, -2031, OSMO_TDEF_MS, -1);
396 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200397 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100398
399 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FINISHED));
400
Max7d32f552017-12-15 11:25:14 +0100401 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100402
403 /* Clean up and ensure tbfs are in the correct state */
404 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +0100405 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100406 check_tbf(dl_tbf);
407 tbf_free(dl_tbf);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100408 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200409 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100410}
411
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200412static void test_tbf_imsi()
413{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100414 the_pcu->bts = bts_alloc(the_pcu);
415 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200416 uint8_t ts_no = 4;
417 uint8_t ms_class = 45;
418 uint8_t trx_no;
419 GprsMs *ms1, *ms2;
420
421 gprs_rlcmac_dl_tbf *dl_tbf[2];
422
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200423 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200424
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100425 setup_bts(the_bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200426
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100427 dl_tbf[0] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
428 dl_tbf[1] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200429
430 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
431 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
432
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100433 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100434 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200435 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100436 ms2 = the_bts->ms_store().get_ms(0xf1000001);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200437 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100438 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200439 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200440
441 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100442 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100443 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200444 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100445 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200446 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100447 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200448 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200449
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100450 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200451 {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100452 ms_ref(ms2);
453 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100454 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200455 OSMO_ASSERT(ms1 != NULL);
456 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100457 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
458 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
459 ms_unref(ms2);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200460 }
461
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100462 ms2 = the_bts->ms_store().get_ms(0xf1000001);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200463 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200464
465 tbf_free(dl_tbf[1]);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100466 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200467 OSMO_ASSERT(ms1 == NULL);
468
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100469 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200470 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200471}
472
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200473static void test_tbf_exhaustion()
474{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100475 the_pcu->bts = bts_alloc(the_pcu);
476 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200477 gprs_rlcmac_bts *bts;
478 unsigned i;
479 uint8_t ts_no = 4;
480 uint8_t ms_class = 45;
481 int rc = 0;
482
483 uint8_t buf[256] = {0};
484
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200485 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200486
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100487 bts = the_bts->bts_data();
488 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
489 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200490 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
491 abort();
492 }
493
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100494 setup_bts(the_bts, ts_no);
Alexander Couzens290d9032020-09-16 21:52:02 +0200495 gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200496
497 for (i = 0; i < 1024; i++) {
498 uint32_t tlli = 0xc0000000 + i;
499 char imsi[16] = {0};
500 unsigned delay_csec = 1000;
501
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200502 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200503
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100504 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200505 delay_csec, buf, sizeof(buf));
506
507 if (rc < 0)
508 break;
509 }
510
511 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200512 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200513
Alexander Couzens290d9032020-09-16 21:52:02 +0200514 gprs_bssgp_destroy(bts);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100515 TALLOC_FREE(the_pcu->bts);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200516}
517
Jacob Erlbeck41168642015-06-12 13:41:00 +0200518static void test_tbf_dl_llc_loss()
519{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100520 the_pcu->bts = bts_alloc(the_pcu);
521 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck41168642015-06-12 13:41:00 +0200522 gprs_rlcmac_bts *bts;
523 uint8_t ts_no = 4;
524 uint8_t ms_class = 45;
525 int rc = 0;
526 uint32_t tlli = 0xc0123456;
527 const char *imsi = "001001000123456";
528 unsigned delay_csec = 1000;
529 GprsMs *ms;
530
531 uint8_t buf[19];
532
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100533 bts = the_bts->bts_data();
534 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
535 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200536 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
537 abort();
538 }
539
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200540 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200541
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100542 setup_bts(the_bts, ts_no);
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200543 /* keep the MS object 10 seconds */
544 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200545
Alexander Couzens290d9032020-09-16 21:52:02 +0200546 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200547
548 /* Handle LLC frame 1 */
549 memset(buf, 1, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100550 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200551 delay_csec, buf, sizeof(buf));
552 OSMO_ASSERT(rc >= 0);
553
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100554 ms = the_bts->ms_store().get_ms(0, 0, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200555 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100556 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
557 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200558
559 /* Handle LLC frame 2 */
560 memset(buf, 2, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100561 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200562 delay_csec, buf, sizeof(buf));
563 OSMO_ASSERT(rc >= 0);
564
565 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100566 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200567
568 /* Handle LLC frame 3 */
569 memset(buf, 3, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100570 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200571 delay_csec, buf, sizeof(buf));
572 OSMO_ASSERT(rc >= 0);
573
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100574 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200575
576 /* Get first BSN */
577 struct msgb *msg;
578 int fn = 0;
579 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100580 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
581 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
582 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
583 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
584 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
585 { 0x07, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
586 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
587 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200588
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100589 while (ms_dl_tbf(ms)->have_data()) {
590 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, 7);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200591 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100592 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200593 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100594
Jacob Erlbeck41168642015-06-12 13:41:00 +0200595 expected_data += 1;
596 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200597 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200598
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200599 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200600
Alexander Couzens290d9032020-09-16 21:52:02 +0200601 gprs_bssgp_destroy(bts);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100602 TALLOC_FREE(the_pcu->bts);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200603}
604
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200605static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
606 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200607{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200608 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200609 int tfi = 0;
610 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200611 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200612 struct gprs_rlcmac_pdch *pdch;
613
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200614 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200615
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +0700616 bts_handle_rach(the_bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200617
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200618 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200619 OSMO_ASSERT(ul_tbf != NULL);
620
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200621 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200622
623 uint8_t data_msg[23] = {
624 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
625 uint8_t(1 | (tfi << 2)),
626 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200627 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
628 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200629 };
630
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200631 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
632 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200633
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200634 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200635 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200636
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200637 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200638}
639
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200640static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
641 RlcMacUplink_t *ulreq, unsigned fn)
642{
643 bitvec *rlc_block;
644 uint8_t buf[64];
645 int num_bytes;
646 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200647
Alexander Couzensccde5c92017-02-04 03:10:08 +0100648 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200649
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100650 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200651 num_bytes = bitvec_pack(rlc_block, &buf[0]);
652 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
653 bitvec_free(rlc_block);
654
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200655 the_bts->set_current_block_frame_number(fn, 0);
656
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200657 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
658 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
659}
660
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200661static void send_control_ack(gprs_rlcmac_tbf *tbf)
662{
663 RlcMacUplink_t ulreq = {0};
664
665 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100666 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200667
668 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
669 Packet_Control_Acknowledgement_t *ctrl_ack =
670 &ulreq.u.Packet_Control_Acknowledgement;
671
672 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
673 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100674 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200675 &ulreq, tbf->poll_fn);
676}
677
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530678static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
679 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
680 uint8_t ms_class, uint8_t egprs_ms_class)
681{
682 GprsMs *ms;
683 uint32_t rach_fn = *fn - 51;
684 uint32_t sba_fn = *fn + 52;
685 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100686 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530687 gprs_rlcmac_ul_tbf *ul_tbf;
688 struct gprs_rlcmac_pdch *pdch;
689 gprs_rlcmac_bts *bts;
690 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530691 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530692
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530693 bts = the_bts->bts_data();
694
695 /* needed to set last_rts_fn in the PDCH object */
696 request_dl_rlc_block(bts, trx_no, ts_no, fn);
697
698 /*
699 * simulate RACH, this sends an Immediate
700 * Assignment Uplink on the AGCH
701 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +0700702 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530703
704 /* get next free TFI */
705 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
706
707 /* fake a resource request */
708 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
709 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
710 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
711 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100712 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
713 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530714 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100715 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530716 MS_RA_capability_value[0].u.Content.
717 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100718 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530719 MS_RA_capability_value[0].u.Content.Multislot_capability.
720 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100721 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530722 MS_RA_capability_value[0].u.Content.Multislot_capability.
723 GPRS_multislot_class = ms_class;
724 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100725 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530726 MS_RA_capability_value[0].u.Content.
727 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100728 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530729 MS_RA_capability_value[0].u.Content.
730 Multislot_capability.EGPRS_multislot_class = ms_class;
731 }
732
733 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
734
735 /* check the TBF */
736 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
737 OSMO_ASSERT(ul_tbf);
738 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
739
740 /* send packet uplink assignment */
741 *fn = sba_fn;
742 request_dl_rlc_block(ul_tbf, fn);
743
744 /* send real acknowledgement */
745 send_control_ack(ul_tbf);
746
747 check_tbf(ul_tbf);
748 /* send fake data */
749 uint8_t data_msg[42] = {
750 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100751 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530752 1, /* BSN:7, E:1 */
753 };
754
755 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
756 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
757
758 ms = the_bts->ms_by_tlli(tlli);
759 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100760 OSMO_ASSERT(ms_ta(ms) == qta/4);
761 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530762
763 /*
764 * TS 44.060, B.8.1
765 * first seg received first, later second seg
766 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530767 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
768 egprs3->si = 0;
769 egprs3->r = 1;
770 egprs3->cv = 7;
771 egprs3->tfi_hi = tfi & 0x03;
772 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
773 egprs3->bsn1_hi = 1;
774 egprs3->bsn1_lo = 0;
775 egprs3->cps_hi = 1;
776 data_msg[3] = 0xff;
777 egprs3->pi = 0;
778 egprs3->cps_lo = 1;
779 egprs3->rsb = 0;
780 egprs3->spb = 0;
781 egprs3->pi = 0;
782
783 pdch->rcv_block(data_msg, 42, *fn, &meas);
784
785 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
786
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100787 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x87, 0xb0, 0x06,
Maxd3a0d912019-03-05 16:15:01 +0100788 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
789 };
790
791 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200792 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100793 return NULL;
794 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530795
796 egprs3->si = 0;
797 egprs3->r = 1;
798 egprs3->cv = 7;
799 egprs3->tfi_hi = tfi & 0x03;
800 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
801 egprs3->bsn1_hi = 4;
802 egprs3->bsn1_lo = 0;
803 egprs3->cps_hi = 1;
804 data_msg[3] = 0xff;
805 egprs3->pi = 0;
806 egprs3->cps_lo = 1;
807 egprs3->rsb = 0;
808 egprs3->spb = 0;
809
810 pdch->rcv_block(data_msg, 42, *fn, &meas);
811
812 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
813
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100814 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x88, 0xb0, 0x06, 0x8b,
Maxd3a0d912019-03-05 16:15:01 +0100815 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
816 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530817
Maxd3a0d912019-03-05 16:15:01 +0100818 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200819 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100820 return NULL;
821 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530822 return ul_tbf;
823}
824
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530825static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
826 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
827 uint8_t ms_class, uint8_t egprs_ms_class)
828{
829 GprsMs *ms;
830 uint32_t rach_fn = *fn - 51;
831 uint32_t sba_fn = *fn + 52;
832 uint8_t trx_no = 0;
833 int tfi = 0, i = 0;
834 gprs_rlcmac_ul_tbf *ul_tbf;
835 struct gprs_rlcmac_pdch *pdch;
836 gprs_rlcmac_bts *bts;
837 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530838 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530839
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530840 bts = the_bts->bts_data();
841
842 /* needed to set last_rts_fn in the PDCH object */
843 request_dl_rlc_block(bts, trx_no, ts_no, fn);
844
845 /*
846 * simulate RACH, this sends an Immediate
847 * Assignment Uplink on the AGCH
848 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +0700849 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530850
851 /* get next free TFI */
852 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
853
854 /* fake a resource request */
855 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
856 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
857 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
858 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100859 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
860 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530861 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100862 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530863 MS_RA_capability_value[0].u.Content.
864 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100865 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530866 MS_RA_capability_value[0].u.Content.Multislot_capability.
867 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100868 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530869 MS_RA_capability_value[0].u.Content.Multislot_capability.
870 GPRS_multislot_class = ms_class;
871 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100872 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530873 MS_RA_capability_value[0].u.Content.
874 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100875 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530876 MS_RA_capability_value[0].u.Content.
877 Multislot_capability.EGPRS_multislot_class = ms_class;
878 }
879
880 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
881
882 /* check the TBF */
883 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
884 OSMO_ASSERT(ul_tbf != NULL);
885 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
886
887 /* send packet uplink assignment */
888 *fn = sba_fn;
889 request_dl_rlc_block(ul_tbf, fn);
890
891 /* send real acknowledgement */
892 send_control_ack(ul_tbf);
893
894 check_tbf(ul_tbf);
895
896 /* send fake data */
897 uint8_t data_msg[42] = {
898 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
899 uint8_t(0 | (tfi << 1)),
900 uint8_t(1), /* BSN:7, E:1 */
901 };
902
903 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
904 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
905
906 ms = the_bts->ms_by_tlli(tlli);
907 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100908 OSMO_ASSERT(ms_ta(ms) == qta/4);
909 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530910
911 /*
912 * TS 44.060, B.8.1
913 * first seg received first, later second seg
914 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530915 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
916 egprs3->si = 1;
917 egprs3->r = 1;
918 egprs3->cv = 7;
919 egprs3->tfi_hi = tfi & 0x03;
920 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
921 egprs3->bsn1_hi = 1;
922 egprs3->bsn1_lo = 0;
923 egprs3->cps_hi = 1;
924 data_msg[3] = 0xff;
925 egprs3->pi = 0;
926 egprs3->cps_lo = 1;
927 egprs3->rsb = 0;
928 egprs3->spb = 2;
929 egprs3->pi = 0;
930
931 pdch->rcv_block(data_msg, 42, *fn, &meas);
932
933 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
934
935 /* check the status of the block */
936 OSMO_ASSERT(block->spb_status.block_status_ul ==
937 EGPRS_RESEG_FIRST_SEG_RXD);
938
939 egprs3->si = 1;
940 egprs3->r = 1;
941 egprs3->cv = 7;
942 egprs3->tfi_hi = tfi & 0x03;
943 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
944 egprs3->bsn1_hi = 1;
945 egprs3->bsn1_lo = 0;
946 egprs3->cps_hi = 1;
947 data_msg[3] = 0xff;
948 egprs3->pi = 0;
949 egprs3->cps_lo = 1;
950 egprs3->rsb = 0;
951 egprs3->spb = 3;
952
953 pdch->rcv_block(data_msg, 42, *fn, &meas);
954
955 /* check the status of the block */
956 OSMO_ASSERT(block->spb_status.block_status_ul ==
957 EGPRS_RESEG_DEFAULT);
958 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100959 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530960 /* Assembled MCS is MCS6. so the size is 74 */
961 OSMO_ASSERT(block->len == 74);
962
963 /*
964 * TS 44.060, B.8.1
965 * second seg first, later first seg
966 */
967 memset(data_msg, 0, sizeof(data_msg));
968
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530969 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
970 egprs3->si = 1;
971 egprs3->r = 1;
972 egprs3->cv = 7;
973 egprs3->tfi_hi = tfi & 0x03;
974 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
975 egprs3->bsn1_hi = 2;
976 egprs3->bsn1_lo = 0;
977 egprs3->cps_hi = 1;
978 data_msg[3] = 0xff;
979 egprs3->pi = 0;
980 egprs3->cps_lo = 1;
981 egprs3->rsb = 0;
982 egprs3->spb = 3;
983 egprs3->pi = 0;
984
985 pdch->rcv_block(data_msg, 42, *fn, &meas);
986
987 block = ul_tbf->m_rlc.block(2);
988 /* check the status of the block */
989 OSMO_ASSERT(block->spb_status.block_status_ul ==
990 EGPRS_RESEG_SECOND_SEG_RXD);
991
992 egprs3->si = 1;
993 egprs3->r = 1;
994 egprs3->cv = 7;
995 egprs3->tfi_hi = tfi & 0x03;
996 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
997 egprs3->bsn1_hi = 2;
998 egprs3->bsn1_lo = 0;
999 egprs3->cps_hi = 1;
1000 data_msg[3] = 0xff;
1001 egprs3->pi = 0;
1002 egprs3->cps_lo = 1;
1003 egprs3->rsb = 0;
1004 egprs3->spb = 2;
1005 egprs3->pi = 0;
1006
1007 pdch->rcv_block(data_msg, 42, *fn, &meas);
1008
1009 /* check the status of the block */
1010 OSMO_ASSERT(block->spb_status.block_status_ul ==
1011 EGPRS_RESEG_DEFAULT);
1012 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001013 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301014 /* Assembled MCS is MCS6. so the size is 74 */
1015 OSMO_ASSERT(block->len == 74);
1016
1017 /*
1018 * TS 44.060, B.8.1
1019 * Error scenario with spb as 1
1020 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301021 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1022 egprs3->si = 1;
1023 egprs3->r = 1;
1024 egprs3->cv = 7;
1025 egprs3->tfi_hi = tfi & 0x03;
1026 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1027 egprs3->bsn1_hi = 3;
1028 egprs3->bsn1_lo = 0;
1029 egprs3->cps_hi = 1;
1030 data_msg[3] = 0xff;
1031 egprs3->pi = 0;
1032 egprs3->cps_lo = 1;
1033 egprs3->rsb = 0;
1034 egprs3->spb = 1;
1035 egprs3->pi = 0;
1036
1037 pdch->rcv_block(data_msg, 42, *fn, &meas);
1038
1039 block = ul_tbf->m_rlc.block(3);
1040 /* check the status of the block */
1041 OSMO_ASSERT(block->spb_status.block_status_ul ==
1042 EGPRS_RESEG_DEFAULT);
1043 /*
1044 * TS 44.060, B.8.1
1045 * comparison of rlc_data for multiple scenarios
1046 * Receive First, the second(BSN 3)
1047 * Receive First, First then Second(BSN 4)
1048 * Receive Second then First(BSN 5)
1049 * after above 3 scenarios are triggered,
1050 * rlc_data of all 3 BSN are compared
1051 */
1052
1053 /* Initialize the data_msg */
1054 for (i = 0; i < 42; i++)
1055 data_msg[i] = i;
1056
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301057 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1058 egprs3->si = 1;
1059 egprs3->r = 1;
1060 egprs3->cv = 7;
1061 egprs3->tfi_hi = tfi & 0x03;
1062 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1063 egprs3->bsn1_hi = 3;
1064 egprs3->bsn1_lo = 0;
1065 egprs3->cps_hi = 1;
1066 data_msg[3] = 0xff;
1067 egprs3->pi = 0;
1068 egprs3->cps_lo = 1;
1069 egprs3->rsb = 0;
1070 egprs3->spb = 2;
1071 egprs3->pi = 0;
1072
1073 pdch->rcv_block(data_msg, 42, *fn, &meas);
1074
1075 block = ul_tbf->m_rlc.block(3);
1076 /* check the status of the block */
1077 OSMO_ASSERT(block->spb_status.block_status_ul ==
1078 EGPRS_RESEG_FIRST_SEG_RXD);
1079
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301080 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1081 egprs3->si = 1;
1082 egprs3->r = 1;
1083 egprs3->cv = 7;
1084 egprs3->tfi_hi = tfi & 0x03;
1085 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1086 egprs3->bsn1_hi = 3;
1087 egprs3->bsn1_lo = 0;
1088 egprs3->cps_hi = 1;
1089 data_msg[3] = 0xff;
1090 egprs3->pi = 0;
1091 egprs3->cps_lo = 1;
1092 egprs3->rsb = 0;
1093 egprs3->spb = 3;
1094 egprs3->pi = 0;
1095
1096 pdch->rcv_block(data_msg, 42, *fn, &meas);
1097
1098 block = ul_tbf->m_rlc.block(3);
1099 /* check the status of the block */
1100 OSMO_ASSERT(block->spb_status.block_status_ul ==
1101 EGPRS_RESEG_DEFAULT);
1102 /* Assembled MCS is MCS6. so the size is 74 */
1103 OSMO_ASSERT(block->len == 74);
1104 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001105 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301106
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301107 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1108 egprs3->si = 1;
1109 egprs3->r = 1;
1110 egprs3->cv = 7;
1111 egprs3->tfi_hi = tfi & 0x03;
1112 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1113 egprs3->bsn1_hi = 4;
1114 egprs3->bsn1_lo = 0;
1115 egprs3->cps_hi = 1;
1116 data_msg[3] = 0xff;
1117 egprs3->pi = 0;
1118 egprs3->cps_lo = 1;
1119 egprs3->rsb = 0;
1120 egprs3->spb = 2;
1121 egprs3->pi = 0;
1122
1123 pdch->rcv_block(data_msg, 42, *fn, &meas);
1124
1125 block = ul_tbf->m_rlc.block(4);
1126 /* check the status of the block */
1127 OSMO_ASSERT(block->spb_status.block_status_ul ==
1128 EGPRS_RESEG_FIRST_SEG_RXD);
1129
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301130 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1131 egprs3->si = 1;
1132 egprs3->r = 1;
1133 egprs3->cv = 7;
1134 egprs3->tfi_hi = tfi & 0x03;
1135 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1136 egprs3->bsn1_hi = 4;
1137 egprs3->bsn1_lo = 0;
1138 egprs3->cps_hi = 1;
1139 data_msg[3] = 0xff;
1140 egprs3->pi = 0;
1141 egprs3->cps_lo = 1;
1142 egprs3->rsb = 0;
1143 egprs3->spb = 2;
1144 egprs3->pi = 0;
1145
1146 pdch->rcv_block(data_msg, 42, *fn, &meas);
1147
1148 block = ul_tbf->m_rlc.block(4);
1149 /* check the status of the block */
1150 OSMO_ASSERT(block->spb_status.block_status_ul ==
1151 EGPRS_RESEG_FIRST_SEG_RXD);
1152
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301153 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1154 egprs3->si = 1;
1155 egprs3->r = 1;
1156 egprs3->cv = 7;
1157 egprs3->tfi_hi = tfi & 0x03;
1158 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1159 egprs3->bsn1_hi = 4;
1160 egprs3->bsn1_lo = 0;
1161 egprs3->cps_hi = 1;
1162 data_msg[3] = 0xff;
1163 egprs3->pi = 0;
1164 egprs3->cps_lo = 1;
1165 egprs3->rsb = 0;
1166 egprs3->spb = 3;
1167 egprs3->pi = 0;
1168
1169 pdch->rcv_block(data_msg, 42, *fn, &meas);
1170
1171 block = ul_tbf->m_rlc.block(4);
1172 /* check the status of the block */
1173 OSMO_ASSERT(block->spb_status.block_status_ul ==
1174 EGPRS_RESEG_DEFAULT);
1175 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001176 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301177 /* Assembled MCS is MCS6. so the size is 74 */
1178 OSMO_ASSERT(block->len == 74);
1179
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301180 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1181 egprs3->si = 1;
1182 egprs3->r = 1;
1183 egprs3->cv = 7;
1184 egprs3->tfi_hi = tfi & 0x03;
1185 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1186 egprs3->bsn1_hi = 5;
1187 egprs3->bsn1_lo = 0;
1188 egprs3->cps_hi = 1;
1189 data_msg[3] = 0xff;
1190 egprs3->pi = 0;
1191 egprs3->cps_lo = 1;
1192 egprs3->rsb = 0;
1193 egprs3->spb = 3;
1194 egprs3->pi = 0;
1195
1196 pdch->rcv_block(data_msg, 42, *fn, &meas);
1197
1198 block = ul_tbf->m_rlc.block(5);
1199 /* check the status of the block */
1200 OSMO_ASSERT(block->spb_status.block_status_ul ==
1201 EGPRS_RESEG_SECOND_SEG_RXD);
1202
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301203 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1204 egprs3->si = 1;
1205 egprs3->r = 1;
1206 egprs3->cv = 7;
1207 egprs3->tfi_hi = tfi & 0x03;
1208 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1209 egprs3->bsn1_hi = 5;
1210 egprs3->bsn1_lo = 0;
1211 egprs3->cps_hi = 1;
1212 data_msg[3] = 0xff;
1213 egprs3->pi = 0;
1214 egprs3->cps_lo = 1;
1215 egprs3->rsb = 0;
1216 egprs3->spb = 2;
1217 egprs3->pi = 0;
1218
1219 pdch->rcv_block(data_msg, 42, *fn, &meas);
1220
1221 block = ul_tbf->m_rlc.block(5);
1222
1223 /* check the status of the block */
1224 OSMO_ASSERT(block->spb_status.block_status_ul ==
1225 EGPRS_RESEG_DEFAULT);
1226 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001227 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301228 /* Assembled MCS is MCS6. so the size is 74 */
1229 OSMO_ASSERT(block->len == 74);
1230
1231 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1232 ul_tbf->m_rlc.block(4)->len);
1233 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1234 ul_tbf->m_rlc.block(3)->len);
1235
1236 /* Compare the spb status of each BSNs(3,4,5). should be same */
1237 OSMO_ASSERT(
1238 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1239 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1240 OSMO_ASSERT(
1241 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1242 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1243
1244 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1245 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1246 ul_tbf->m_rlc.block(4)->cs_last);
1247 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1248 ul_tbf->m_rlc.block(3)->cs_last);
1249
1250 /* Compare the data of each BSNs(3,4,5). should be same */
1251 OSMO_ASSERT(
1252 !memcmp(ul_tbf->m_rlc.block(5)->block,
1253 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1254 ));
1255 OSMO_ASSERT(
1256 !memcmp(ul_tbf->m_rlc.block(5)->block,
1257 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1258 ));
1259
1260 return ul_tbf;
1261}
1262
sivasankari1d8744c2017-01-24 15:53:35 +05301263static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,
1264 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1265 uint8_t ms_class, uint8_t egprs_ms_class)
1266{
sivasankari1d8744c2017-01-24 15:53:35 +05301267 uint32_t rach_fn = *fn - 51;
1268 uint32_t sba_fn = *fn + 52;
1269 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001270 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301271 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301272 gprs_rlcmac_bts *bts;
1273 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301274
sivasankari1d8744c2017-01-24 15:53:35 +05301275 bts = the_bts->bts_data();
1276
1277 /* needed to set last_rts_fn in the PDCH object */
1278 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1279
1280 /*
1281 * simulate RACH, this sends an Immediate
1282 * Assignment Uplink on the AGCH
1283 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +07001284 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301285
1286 /* get next free TFI */
1287 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
1288
1289 /* fake a resource request */
1290 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1291 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1292 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1293 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001294 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1295 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301296 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001297 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301298 MS_RA_capability_value[0].u.Content.
1299 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001300 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301301 MS_RA_capability_value[0].u.Content.Multislot_capability.
1302 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001303 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301304 MS_RA_capability_value[0].u.Content.Multislot_capability.
1305 GPRS_multislot_class = ms_class;
1306 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001307 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301308 MS_RA_capability_value[0].u.Content.
1309 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001310 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301311 MS_RA_capability_value[0].u.Content.
1312 Multislot_capability.EGPRS_multislot_class = ms_class;
1313 }
1314 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
1315
1316 /* check the TBF */
1317 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1318 /* send packet uplink assignment */
1319 *fn = sba_fn;
1320 request_dl_rlc_block(ul_tbf, fn);
1321
1322 /* send real acknowledgement */
1323 send_control_ack(ul_tbf);
1324
1325 check_tbf(ul_tbf);
1326
1327 return ul_tbf;
1328}
1329
1330static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *the_bts,
1331 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1332 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1333{
1334 OSMO_ASSERT(ul_tbf);
1335 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1336 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301337 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001338 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301339 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301340
1341 /* send fake data with cv=0*/
1342 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1343 uint8_t data[49] = {0};
1344
1345 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1346
1347 /*header_construction */
1348 memset(data, 0x2b, sizeof(data));
1349 /* Message with CRBB */
1350 for (int i = 0 ; i < 80; i++) {
1351 hdr3->r = 0;
1352 hdr3->si = 0;
1353 hdr3->cv = 10;
1354 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1355 hdr3->tfi_lo = tfi & 0x7;
1356 hdr3->bsn1_hi = ((i * 2)&0x1f);
1357 hdr3->bsn1_lo = ((i * 2)/32);
1358 hdr3->cps_hi = 0;
1359 hdr3->cps_lo = 0;
1360 hdr3->spb = 0;
1361 hdr3->rsb = 0;
1362 hdr3->pi = 0;
1363 hdr3->spare = 0;
1364 hdr3->dummy = 1;
1365 data[4] = 0x0;
1366 data[5] = 0x0;
1367 data[6] = 0x2b;
1368 data[7] = 0x2b;
1369 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1370 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1371 }
1372 ul_tbf->create_ul_ack(*fn, ts_no);
1373 memset(data, 0x2b, sizeof(data));
1374 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1375 hdr3->r = 0;
1376 hdr3->si = 0;
1377 hdr3->cv = 0;
1378 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1379 hdr3->tfi_lo = tfi & 0x7;
1380 hdr3->bsn1_hi = 0;
1381 hdr3->bsn1_lo = 2;
1382 hdr3->cps_hi = 0;
1383 hdr3->cps_lo = 0;
1384 hdr3->spb = 0;
1385 hdr3->rsb = 0;
1386 hdr3->pi = 0;
1387 hdr3->spare = 0;
1388 hdr3->dummy = 1;
1389 data[4] = 0x0;
1390 data[5] = 0x2b;
1391 data[6] = 0x2b;
1392 data[7] = 0x2b;
1393
1394 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1395 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1396
1397 request_dl_rlc_block(ul_tbf, fn);
1398
1399 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001400 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301401
1402 ms = the_bts->ms_by_tlli(tlli);
1403 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001404 OSMO_ASSERT(ms_ta(ms) == qta/4);
1405 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301406
1407 return ul_tbf;
1408}
1409
1410static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS *the_bts,
1411 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1412 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1413{
1414 OSMO_ASSERT(ul_tbf);
1415 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1416 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301417 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001418 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301419 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301420
1421 check_tbf(ul_tbf);
1422 /* send fake data with cv=0*/
1423 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1424 uint8_t data[49] = {0};
1425
1426 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1427
1428 /*header_construction */
1429 memset(data, 0x2b, sizeof(data));
1430
1431 /* Message with URBB & URBB length */
1432 for (int i = 0 ; i < 20; i++) {
1433 hdr3->r = 0;
1434 hdr3->si = 0;
1435 hdr3->cv = 10;
1436 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1437 hdr3->tfi_lo = tfi & 0x7;
1438 hdr3->bsn1_hi = ((i * 2)&0x1f);
1439 hdr3->bsn1_lo = ((i * 2)/32);
1440 hdr3->cps_hi = 0;
1441 hdr3->cps_lo = 0;
1442 hdr3->spb = 0;
1443 hdr3->rsb = 0;
1444 hdr3->pi = 0;
1445 hdr3->spare = 0;
1446 hdr3->dummy = 1;
1447 data[4] = 0x0;
1448 data[5] = 0x0;
1449 data[6] = 0x2b;
1450 data[7] = 0x2b;
1451 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1452 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1453 }
1454 ul_tbf->create_ul_ack(*fn, ts_no);
1455 memset(data, 0x2b, sizeof(data));
1456 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1457 hdr3->r = 0;
1458 hdr3->si = 0;
1459 hdr3->cv = 0;
1460 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1461 hdr3->tfi_lo = tfi & 0x7;
1462 hdr3->bsn1_hi = 0;
1463 hdr3->bsn1_lo = 2;
1464 hdr3->cps_hi = 0;
1465 hdr3->cps_lo = 0;
1466 hdr3->spb = 0;
1467 hdr3->rsb = 0;
1468 hdr3->pi = 0;
1469 hdr3->spare = 0;
1470 hdr3->dummy = 1;
1471 data[4] = 0x0;
1472 data[5] = 0x2b;
1473 data[6] = 0x2b;
1474 data[7] = 0x2b;
1475
1476 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1477 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +02001478 ul_tbf->create_ul_ack(*fn, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301479
1480 request_dl_rlc_block(ul_tbf, fn);
1481
1482 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001483 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301484
1485 ms = the_bts->ms_by_tlli(tlli);
1486 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001487 OSMO_ASSERT(ms_ta(ms) == qta/4);
1488 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301489
1490 return ul_tbf;
1491}
1492
1493static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,
1494 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1495 uint8_t ms_class, uint8_t egprs_ms_class)
1496{
1497 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301498 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001499 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301500 gprs_rlcmac_ul_tbf *ul_tbf;
1501 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301502
1503 /* check the TBF */
1504 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1505 OSMO_ASSERT(ul_tbf);
1506 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1507
1508 /* send fake data with cv=0*/
1509 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1510 uint8_t data[49] = {0};
1511
1512 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1513
1514 /*header_construction */
1515 memset(data, 0x2b, sizeof(data));
1516
1517 /* Message with CRBB */
1518 for (int i = 80 ; i < 160; i++) {
1519 hdr3->r = 0;
1520 hdr3->si = 0;
1521 hdr3->cv = 10;
1522 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1523 hdr3->tfi_lo = tfi & 0x7;
1524 hdr3->bsn1_hi = ((i)&0x1f);
1525 hdr3->bsn1_lo = ((i)/32);
1526 hdr3->cps_hi = 0;
1527 hdr3->cps_lo = 0;
1528 hdr3->spb = 0;
1529 hdr3->rsb = 0;
1530 hdr3->pi = 0;
1531 hdr3->spare = 0;
1532 hdr3->dummy = 1;
1533 data[4] = 0x0;
1534 data[5] = 0x0;
1535 data[6] = 0x2b;
1536 data[7] = 0x2b;
1537 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1538 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1539 }
1540 ul_tbf->create_ul_ack(*fn, ts_no);
1541 memset(data, 0x2b, sizeof(data));
1542 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1543 hdr3->r = 0;
1544 hdr3->si = 0;
1545 hdr3->cv = 0;
1546 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1547 hdr3->tfi_lo = tfi & 0x7;
1548 hdr3->bsn1_hi = 0;
1549 hdr3->bsn1_lo = 2;
1550 hdr3->cps_hi = 0;
1551 hdr3->cps_lo = 0;
1552 hdr3->spb = 0;
1553 hdr3->rsb = 0;
1554 hdr3->pi = 0;
1555 hdr3->spare = 0;
1556 hdr3->dummy = 1;
1557 data[4] = 0x0;
1558 data[5] = 0x2b;
1559 data[6] = 0x2b;
1560 data[7] = 0x2b;
1561
1562 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1563 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1564
1565 request_dl_rlc_block(ul_tbf, fn);
1566
1567 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001568 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301569
1570 ms = the_bts->ms_by_tlli(tlli);
1571 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001572 OSMO_ASSERT(ms_ta(ms) == qta/4);
1573 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301574
1575 return ul_tbf;
1576}
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001577static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
1578 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001579 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001580{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001581 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001582 uint32_t rach_fn = *fn - 51;
1583 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001584 uint8_t trx_no = 0;
1585 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001586 gprs_rlcmac_ul_tbf *ul_tbf;
1587 struct gprs_rlcmac_pdch *pdch;
1588 gprs_rlcmac_bts *bts;
1589 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001590
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001591 bts = the_bts->bts_data();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001592
1593 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001594 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001595
bhargava959d1de2016-08-17 15:17:21 +05301596 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +07001597 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001598
1599 /* get next free TFI */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001600 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001601
1602 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001603 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1604 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1605 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1606 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001607 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1608 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001609 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001610 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001611 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001612 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001613 MS_RA_capability_value[0].u.Content.Multislot_capability.
1614 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001615 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001616 MS_RA_capability_value[0].u.Content.Multislot_capability.
1617 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001618 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001619 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001620 MS_RA_capability_value[0].u.Content.Multislot_capability.
1621 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001622 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001623 MS_RA_capability_value[0].u.Content.Multislot_capability.
1624 EGPRS_multislot_class = ms_class;
1625 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001626
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001627 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001628
1629 /* check the TBF */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001630 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001631 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001632 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001633
1634 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001635 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001636 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001637
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001638 /* send real acknowledgement */
1639 send_control_ack(ul_tbf);
1640
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001641 check_tbf(ul_tbf);
1642
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001643 /* send fake data */
1644 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001645 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1646 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001647 uint8_t(1), /* BSN:7, E:1 */
1648 };
1649
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001650 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001651 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001652
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001653 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001654 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001655 OSMO_ASSERT(ms_ta(ms) == qta/4);
1656 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001657
1658 return ul_tbf;
1659}
1660
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001661static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,
1662 const uint8_t *data, unsigned data_size)
1663{
1664 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001665
1666 ms = the_bts->ms_store().get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001667
Jacob Erlbeck14e00f82015-11-27 18:10:39 +01001668 gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001669 1000, data, data_size);
1670
1671 ms = the_bts->ms_by_imsi(imsi);
1672 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001673 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001674
1675 if (imsi[0] && strcmp(imsi, "000") != 0) {
1676 ms2 = the_bts->ms_by_tlli(tlli);
1677 OSMO_ASSERT(ms == ms2);
1678 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001679}
1680
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001681static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,
1682 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001683{
1684 gprs_rlcmac_dl_tbf *dl_tbf;
1685 GprsMs *ms;
1686 unsigned ts_no;
1687
1688 ms = the_bts->ms_by_tlli(tlli);
1689 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001690 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001691 OSMO_ASSERT(dl_tbf);
1692
1693 while (dl_tbf->have_data()) {
1694 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001695 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1696 if (!(slots & (1 << ts_no)))
1697 continue;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001698 gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
Max878bd1f2016-07-20 13:05:05 +02001699 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001700 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001701 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001702 *fn = fn_add_blocks(*fn, 1);
1703 }
1704}
1705
Max4c112dc2018-02-01 16:49:23 +01001706static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1707{
1708 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1709 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001710 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 +01001711}
1712
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001713static void test_tbf_single_phase()
1714{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001715 the_pcu->bts = bts_alloc(the_pcu);
1716 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001717 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001718 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001719 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001720 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001721 uint16_t qta = 31;
1722 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001723
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001724 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001725
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001726 setup_bts(the_bts, ts_no);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001727
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001728 ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001729
Max4c112dc2018-02-01 16:49:23 +01001730 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001731 send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001732
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001733 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001734 TALLOC_FREE(the_pcu->bts);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001735}
1736
sivasankari1d8744c2017-01-24 15:53:35 +05301737static void test_tbf_egprs_two_phase_puan(void)
1738{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001739 the_pcu->bts = bts_alloc(the_pcu);
1740 BTS *the_bts = the_pcu->bts;
sivasankari1d8744c2017-01-24 15:53:35 +05301741 int ts_no = 7;
1742 uint32_t fn = 2654218;
1743 uint16_t qta = 31;
1744 uint32_t tlli = 0xf1223344;
1745 const char *imsi = "0011223344";
1746 uint8_t ms_class = 1;
1747 gprs_rlcmac_bts *bts;
1748 uint8_t egprs_ms_class = 1;
1749 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301750 uint8_t test_data[256];
1751
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001752 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301753
1754 memset(test_data, 1, sizeof(test_data));
1755
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001756 setup_bts(the_bts, ts_no, 4);
1757 the_bts->bts_data()->initial_mcs_dl = 9;
1758 bts = the_bts->bts_data();
sivasankari1d8744c2017-01-24 15:53:35 +05301759 bts->ws_base = 128;
1760 bts->ws_pdch = 64;
1761
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001762 ul_tbf = establish_ul_tbf(the_bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301763 /* Function to generate URBB with no length */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001764 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(the_bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301765 qta, ms_class, egprs_ms_class, ul_tbf);
1766
Max4c112dc2018-02-01 16:49:23 +01001767 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001768 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301769
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001770 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301771 /* Function to generate URBB with length */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001772 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(the_bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301773 qta, ms_class, egprs_ms_class, ul_tbf);
1774
Max4c112dc2018-02-01 16:49:23 +01001775 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001776 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301777
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001778 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301779 /* Function to generate CRBB */
1780 bts->ws_base = 128;
1781 bts->ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001782 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(the_bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301783 qta, ms_class, egprs_ms_class);
1784
Max4c112dc2018-02-01 16:49:23 +01001785 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001786 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301787
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001788 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001789 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301790}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301791/*
1792 * Trigger rach for single block
1793 */
1794static void test_immediate_assign_rej_single_block()
1795{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001796 the_pcu->bts = bts_alloc(the_pcu);
1797 BTS *the_bts = the_pcu->bts;
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301798 uint32_t fn = 2654218;
1799 uint16_t qta = 31;
1800 int ts_no = 7;
1801
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001802 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301803
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001804 setup_bts(the_bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301805
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001806 the_bts->bts_data()->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301807
1808 uint32_t rach_fn = fn - 51;
1809
1810 int rc = 0;
1811
1812 /*
1813 * simulate RACH, sends an Immediate Assignment
1814 * Uplink reject on the AGCH
1815 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001816 rc = bts_handle_rach(the_bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301817
1818 OSMO_ASSERT(rc == -EINVAL);
1819
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001820 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001821 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301822}
1823
1824/*
1825 * Trigger rach till resources(USF) exhaust
1826 */
1827static void test_immediate_assign_rej_multi_block()
1828{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001829 the_pcu->bts = bts_alloc(the_pcu);
1830 BTS *the_bts = the_pcu->bts;
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301831 uint32_t fn = 2654218;
1832 uint16_t qta = 31;
1833 int ts_no = 7;
1834
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001835 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301836
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001837 setup_bts(the_bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301838
1839 uint32_t rach_fn = fn - 51;
1840
1841 int rc = 0;
1842
1843 /*
1844 * simulate RACH, sends an Immediate Assignment Uplink
1845 * reject on the AGCH
1846 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001847 rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);
1848 rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);
1849 rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);
1850 rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);
1851 rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);
1852 rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);
1853 rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);
1854 rc = bts_handle_rach(the_bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301855
1856 OSMO_ASSERT(rc == -EBUSY);
1857
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001858 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001859 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301860}
1861
1862static void test_immediate_assign_rej()
1863{
1864 test_immediate_assign_rej_multi_block();
1865 test_immediate_assign_rej_single_block();
1866}
1867
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001868static void test_tbf_two_phase()
1869{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001870 the_pcu->bts = bts_alloc(the_pcu);
1871 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001872 int ts_no = 7;
1873 uint32_t fn = 2654218;
1874 uint16_t qta = 31;
1875 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001876 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001877 uint8_t ms_class = 1;
1878 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001879
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001880 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001881
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001882 setup_bts(the_bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001883
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001884 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001885 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001886
Max4c112dc2018-02-01 16:49:23 +01001887 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001888 send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001889
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001890 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001891 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001892}
1893
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001894static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001895{
1896 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001897 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 +01001898}
1899
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001900static void test_tbf_ra_update_rach()
1901{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001902 the_pcu->bts = bts_alloc(the_pcu);
1903 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001904 int ts_no = 7;
1905 uint32_t fn = 2654218;
1906 uint16_t qta = 31;
1907 uint32_t tlli1 = 0xf1223344;
1908 uint32_t tlli2 = 0xf5667788;
1909 const char *imsi = "0011223344";
1910 uint8_t ms_class = 1;
1911 gprs_rlcmac_ul_tbf *ul_tbf;
1912 GprsMs *ms, *ms1, *ms2;
1913
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001914 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001915
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001916 setup_bts(the_bts, ts_no, 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001917
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001918 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001919 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001920
1921 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001922 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001923
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001924 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001925 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001926
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001927 /* Send Packet Downlink Assignment to MS */
1928 request_dl_rlc_block(ul_tbf, &fn);
1929
1930 /* Ack it */
1931 send_control_ack(ul_tbf);
1932
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001933 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001934 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001935 transmit_dl_data(the_bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001936 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001937
1938 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001939 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001940 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001941
1942 ms2 = ul_tbf->ms();
1943
1944 /* The PCU cannot know yet, that both TBF belong to the same MS */
1945 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01001946 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001947
1948 /* Send some downlink data along with the new TLLI and the IMSI so that
1949 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001950 send_dl_data(the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001951
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001952 ms = the_bts->ms_by_imsi(imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001953 OSMO_ASSERT(ms == ms2);
1954
Max4c112dc2018-02-01 16:49:23 +01001955 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001956
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001957 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001958 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001959 ms = the_bts->ms_by_tlli(tlli2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001960 OSMO_ASSERT(ms == ms2);
1961
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001962 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001963 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001964}
1965
1966static void test_tbf_dl_flow_and_rach_two_phase()
1967{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001968 the_pcu->bts = bts_alloc(the_pcu);
1969 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001970 int ts_no = 7;
1971 uint32_t fn = 2654218;
1972 uint16_t qta = 31;
1973 uint32_t tlli1 = 0xf1223344;
1974 const char *imsi = "0011223344";
1975 uint8_t ms_class = 1;
1976 gprs_rlcmac_ul_tbf *ul_tbf;
1977 gprs_rlcmac_dl_tbf *dl_tbf;
1978 GprsMs *ms, *ms1, *ms2;
1979
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001980 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001981
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001982 setup_bts(the_bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001983
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001984 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001985 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001986
1987 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001988 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001989
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001990 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1991 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01001992 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001993
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001994 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
1995 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001996 OSMO_ASSERT(dl_tbf != NULL);
1997
1998 /* Get rid of old UL TBF */
1999 tbf_free(ul_tbf);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002000 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002001 OSMO_ASSERT(ms1 == ms);
2002
2003 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002004 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002005 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002006
2007 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002008 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002009
2010 /* This should be the same MS object */
2011 OSMO_ASSERT(ms2 == ms1);
2012
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002013 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002014 OSMO_ASSERT(ms2 == ms);
2015
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002016 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002017 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002018
2019 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002020 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002021
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002022 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002023 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002024}
2025
2026
2027static void test_tbf_dl_flow_and_rach_single_phase()
2028{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002029 the_pcu->bts = bts_alloc(the_pcu);
2030 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002031 int ts_no = 7;
2032 uint32_t fn = 2654218;
2033 uint16_t qta = 31;
2034 uint32_t tlli1 = 0xf1223344;
2035 const char *imsi = "0011223344";
2036 uint8_t ms_class = 1;
2037 gprs_rlcmac_ul_tbf *ul_tbf;
2038 gprs_rlcmac_dl_tbf *dl_tbf;
2039 GprsMs *ms, *ms1, *ms2;
2040
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002041 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002042
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002043 setup_bts(the_bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002044
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002045 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002046 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002047
2048 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002049 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002050
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002051 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2052 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002053 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002054
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002055 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2056 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002057 OSMO_ASSERT(dl_tbf != NULL);
2058
2059 /* Get rid of old UL TBF */
2060 tbf_free(ul_tbf);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002061 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002062 OSMO_ASSERT(ms1 == ms);
2063
2064 /* Now establish a new UL TBF */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002065 ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002066
2067 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002068 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002069
2070 /* There should be a different MS object */
2071 OSMO_ASSERT(ms2 != ms1);
2072
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002073 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002074 OSMO_ASSERT(ms2 == ms);
2075 OSMO_ASSERT(ms1 != ms);
2076
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002077 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002078 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002079
2080 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002081 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002082
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002083 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002084 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002085}
2086
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002087static void test_tbf_dl_reuse()
2088{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002089 the_pcu->bts = bts_alloc(the_pcu);
2090 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002091 int ts_no = 7;
2092 uint32_t fn = 2654218;
2093 uint16_t qta = 31;
2094 uint32_t tlli1 = 0xf1223344;
2095 const char *imsi = "0011223344";
2096 uint8_t ms_class = 1;
2097 gprs_rlcmac_ul_tbf *ul_tbf;
2098 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2099 GprsMs *ms1, *ms2;
2100 unsigned i;
2101 RlcMacUplink_t ulreq = {0};
2102
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002103 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002104
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002105 setup_bts(the_bts, ts_no, 1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002106
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002107 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002108 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002109
2110 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002111 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002112
2113 /* Send some LLC frames */
2114 for (i = 0; i < 40; i++) {
2115 char buf[32];
2116 int rc;
2117
2118 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2119 OSMO_ASSERT(rc > 0);
2120
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002121 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002122 }
2123
Max4c112dc2018-02-01 16:49:23 +01002124 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002125
2126 /* Send Packet Downlink Assignment to MS */
2127 request_dl_rlc_block(ul_tbf, &fn);
2128
2129 /* Ack it */
2130 send_control_ack(ul_tbf);
2131
2132 /* Transmit all data */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002133 transmit_dl_data(the_bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002134 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2135 OSMO_ASSERT(ms_dl_tbf(ms1));
2136 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002137
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002138 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002139
2140 /* Send some LLC frames */
2141 for (i = 0; i < 10; i++) {
2142 char buf[32];
2143 int rc;
2144
2145 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2146 OSMO_ASSERT(rc > 0);
2147
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002148 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002149 }
2150
2151 /* Fake Final DL Ack/Nack */
2152 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2153 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2154
2155 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2156 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2157 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2158
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002159 send_ul_mac_block(the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002160
2161 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2162
2163 request_dl_rlc_block(dl_tbf1, &fn);
2164
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002165 ms2 = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002166 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002167 OSMO_ASSERT(ms_dl_tbf(ms2));
2168 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002169
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002170 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002171
2172 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2173
2174 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02002175 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002176
2177 /* Transmit all data */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002178 transmit_dl_data(the_bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002179 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2180 OSMO_ASSERT(ms_dl_tbf(ms2));
2181 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002182
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002183 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002184 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002185}
2186
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002187static void test_tbf_gprs_egprs()
2188{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002189 the_pcu->bts = bts_alloc(the_pcu);
2190 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002191 gprs_rlcmac_bts *bts;
2192 uint8_t ts_no = 4;
2193 uint8_t ms_class = 45;
2194 int rc = 0;
2195 uint32_t tlli = 0xc0006789;
2196 const char *imsi = "001001123456789";
2197 unsigned delay_csec = 1000;
2198
2199 uint8_t buf[256] = {0};
2200
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002201 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002202
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002203 bts = the_bts->bts_data();
2204 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2205 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002206 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2207 abort();
2208 }
2209
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002210 setup_bts(the_bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002211
2212 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002213
Alexander Couzens290d9032020-09-16 21:52:02 +02002214 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002215
2216 /* Does not support EGPRS */
2217 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
2218 delay_csec, buf, sizeof(buf));
2219
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002220 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002221 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002222
Alexander Couzens290d9032020-09-16 21:52:02 +02002223 gprs_bssgp_destroy(bts);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002224 TALLOC_FREE(the_pcu->bts);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002225}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002226
Max4c112dc2018-02-01 16:49:23 +01002227static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
2228 bool free, bool end)
2229{
Alexander Couzens290d9032020-09-16 21:52:02 +02002230 gprs_rlcmac_bts *bts = dl_tbf->bts->bts_data();
Max4c112dc2018-02-01 16:49:23 +01002231 if (!dl_tbf) {
2232 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2233 return;
2234 }
2235
2236 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2237 dl_tbf->dl_slots(),
2238 pcu_bitcount(dl_tbf->dl_slots()),
2239 dl_tbf->window_size());
2240
2241 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2242 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2243 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2244
2245 fprintf(stderr, "\n");
2246
2247 if (free)
2248 tbf_free(dl_tbf);
2249
2250 if (end) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002251 fprintf(stderr, "=== end %s ===\n", test);
Alexander Couzens290d9032020-09-16 21:52:02 +02002252 gprs_bssgp_destroy(bts);
Max4c112dc2018-02-01 16:49:23 +01002253 }
2254}
2255
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002256static void test_tbf_ws()
2257{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002258 the_pcu->bts = bts_alloc(the_pcu);
2259 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002260 gprs_rlcmac_bts *bts;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002261 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002262 uint8_t ts_no = 4;
2263 uint8_t ms_class = 12;
2264 gprs_rlcmac_dl_tbf *dl_tbf;
2265
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002266 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002267
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002268 bts = the_bts->bts_data();
2269 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2270 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002271 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2272 abort();
2273 }
2274
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002275 setup_bts(the_bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002276
2277 bts->ws_base = 128;
2278 bts->ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002279 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002280 bts->trx[0].pdch[2].enable();
2281 bts->trx[0].pdch[3].enable();
2282 bts->trx[0].pdch[4].enable();
2283 bts->trx[0].pdch[5].enable();
2284
Alexander Couzens290d9032020-09-16 21:52:02 +02002285 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002286
2287 /* Does no support EGPRS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002288 ms = the_bts->ms_alloc(ms_class, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002289 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002290
2291 ws_check(dl_tbf, __func__, 4, 64, true, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002292
2293 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002294
2295 /* Does support EGPRS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002296 ms = the_bts->ms_alloc(ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002297 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002298
Max4c112dc2018-02-01 16:49:23 +01002299 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002300 TALLOC_FREE(the_pcu->bts);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002301}
2302
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302303static void test_tbf_update_ws(void)
2304{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002305 the_pcu->bts = bts_alloc(the_pcu);
2306 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302307 gprs_rlcmac_bts *bts;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002308 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302309 uint8_t ts_no = 4;
2310 uint8_t ms_class = 11;
2311 gprs_rlcmac_dl_tbf *dl_tbf;
2312
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002313 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302314
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002315 bts = the_bts->bts_data();
2316 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2317 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002318 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2319 abort();
2320 }
2321
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002322 setup_bts(the_bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302323
2324 bts->ws_base = 128;
2325 bts->ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002326 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302327 bts->trx[0].pdch[2].enable();
2328 bts->trx[0].pdch[3].enable();
2329 bts->trx[0].pdch[4].enable();
2330 bts->trx[0].pdch[5].enable();
2331
Alexander Couzens290d9032020-09-16 21:52:02 +02002332 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302333
2334 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302335
2336 /* Does support EGPRS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002337 ms = the_bts->ms_alloc(ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002338 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302339
Max4c112dc2018-02-01 16:49:23 +01002340 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302341
2342 dl_tbf->update();
2343
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302344 /* window size should be 384 */
Max4c112dc2018-02-01 16:49:23 +01002345 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002346 TALLOC_FREE(the_pcu->bts);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302347}
2348
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302349static void test_tbf_puan_urbb_len(void)
2350{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002351 the_pcu->bts = bts_alloc(the_pcu);
2352 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302353 int ts_no = 7;
2354 uint32_t fn = 2654218;
2355 uint16_t qta = 31;
2356 uint32_t tlli = 0xf1223344;
2357 const char *imsi = "0011223344";
2358 uint8_t ms_class = 1;
2359 uint8_t egprs_ms_class = 1;
2360 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302361 uint8_t test_data[256];
2362
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002363 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302364
2365 memset(test_data, 1, sizeof(test_data));
2366
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002367 setup_bts(the_bts, ts_no, 4);
2368 the_bts->bts_data()->initial_mcs_dl = 9;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302369
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002370 ul_tbf = puan_urbb_len_issue(the_bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302371 ms_class, egprs_ms_class);
2372
Max4c112dc2018-02-01 16:49:23 +01002373 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002374 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302375
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002376 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002377 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302378}
2379
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302380static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
2381 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2382 uint8_t ms_class, uint8_t egprs_ms_class)
2383{
2384 GprsMs *ms;
2385 uint32_t rach_fn = *fn - 51;
2386 uint32_t sba_fn = *fn + 52;
2387 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002388 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302389 gprs_rlcmac_ul_tbf *ul_tbf;
2390 struct gprs_rlcmac_pdch *pdch;
2391 gprs_rlcmac_bts *bts;
2392 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302393 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302394 Packet_Resource_Request_t *presreq = NULL;
2395 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2396 Multislot_capability_t *pmultislotcap = NULL;
2397
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302398 bts = the_bts->bts_data();
2399
2400 /* needed to set last_rts_fn in the PDCH object */
2401 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2402
2403 /*
2404 * simulate RACH, this sends an Immediate
2405 * Assignment Uplink on the AGCH
2406 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +07002407 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302408
2409 /* get next free TFI */
2410 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
2411
2412 /* fake a resource request */
2413 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2414 presreq = &ulreq.u.Packet_Resource_Request;
2415 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2416 presreq->ID.UnionType = 1; /* != 0 */
2417 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002418 presreq->Exist_MS_Radio_Access_capability2 = 1;
2419 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302420 pmsradiocap->Count_MS_RA_capability_value = 1;
2421 pmsradiocap->MS_RA_capability_value[0].u.Content.
2422 Exist_Multislot_capability = 1;
2423 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2424 u.Content.Multislot_capability;
2425
2426 pmultislotcap->Exist_GPRS_multislot_class = 1;
2427 pmultislotcap->GPRS_multislot_class = ms_class;
2428 if (egprs_ms_class) {
2429 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2430 pmultislotcap->EGPRS_multislot_class = ms_class;
2431 }
2432
2433 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
2434
2435 /* check the TBF */
2436 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
2437 OSMO_ASSERT(ul_tbf);
2438 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2439
2440 /* send packet uplink assignment */
2441 *fn = sba_fn;
2442 request_dl_rlc_block(ul_tbf, fn);
2443
2444 /* send real acknowledgement */
2445 send_control_ack(ul_tbf);
2446
2447 check_tbf(ul_tbf);
2448
2449 uint8_t data_msg[49] = {0};
2450
2451 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
2452
2453 ms = the_bts->ms_by_tlli(tlli);
2454 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002455 OSMO_ASSERT(ms_ta(ms) == qta/4);
2456 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302457
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302458 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2459 egprs3->si = 0;
2460 egprs3->r = 1;
2461 egprs3->cv = 7;
2462 egprs3->tfi_hi = tfi & 0x03;
2463 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2464 egprs3->bsn1_hi = 0;
2465 egprs3->bsn1_lo = 0;
2466 egprs3->cps_hi = 1;
2467 data_msg[3] = 0xff;
2468 egprs3->pi = 0;
2469 egprs3->cps_lo = 1;
2470 egprs3->rsb = 0;
2471 egprs3->spb = 0;
2472 egprs3->pi = 0;
2473 pdch->rcv_block(data_msg, 49, *fn, &meas);
2474
2475 egprs3->bsn1_hi = 1;
2476 egprs3->bsn1_lo = 0;
2477 data_msg[3] = 0x7f;
2478 egprs3->cps_lo = 1;
2479 egprs3->rsb = 0;
2480 egprs3->spb = 0;
2481 egprs3->pi = 0;
2482 data_msg[4] = 0x2;
2483 data_msg[5] = 0x0;
2484 pdch->rcv_block(data_msg, 49, *fn, &meas);
2485
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302486 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302487
2488 return ul_tbf;
2489}
2490
2491static void test_tbf_li_decoding(void)
2492{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002493 the_pcu->bts = bts_alloc(the_pcu);
2494 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302495 int ts_no = 7;
2496 uint32_t fn = 2654218;
2497 uint16_t qta = 31;
2498 uint32_t tlli = 0xf1223344;
2499 const char *imsi = "0011223344";
2500 uint8_t ms_class = 1;
2501 uint8_t egprs_ms_class = 1;
2502 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302503 uint8_t test_data[256];
2504
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002505 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302506
2507 memset(test_data, 1, sizeof(test_data));
2508
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002509 setup_bts(the_bts, ts_no, 4);
2510 the_bts->bts_data()->initial_mcs_dl = 9;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302511
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002512 ul_tbf = tbf_li_decoding(the_bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302513 ms_class, egprs_ms_class);
2514
Max4c112dc2018-02-01 16:49:23 +01002515 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002516 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302517
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002518 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002519 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302520}
2521
aravind sirsikarf2761382016-10-25 12:45:24 +05302522/*
2523 * Test that a bit within the uncompressed bitmap whose BSN is not within
2524 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2525 * version 7.27.0 Release 7.
2526 */
2527static void test_tbf_epdan_out_of_rx_window(void)
2528{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002529 the_pcu->bts = bts_alloc(the_pcu);
2530 BTS *the_bts = the_pcu->bts;
aravind sirsikarf2761382016-10-25 12:45:24 +05302531 gprs_rlcmac_bts *bts;
2532 uint8_t ms_class = 11;
2533 uint8_t egprs_ms_class = 11;
2534 uint8_t trx_no;
2535 uint32_t tlli = 0xffeeddcc;
2536 gprs_rlcmac_dl_tbf *dl_tbf;
2537 int ts_no = 4;
2538 bitvec *block;
2539 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2540 bitvec bits;
2541 int bsn_begin, bsn_end;
2542 EGPRS_PD_AckNack_t *ack_nack;
2543 RlcMacUplink_t ul_control_block;
2544 gprs_rlc_v_b *prlcmvb;
2545 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002546 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302547
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302548 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2549
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002550 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302551
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002552 bts = the_bts->bts_data();
aravind sirsikarf2761382016-10-25 12:45:24 +05302553
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002554 setup_bts(the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02002555 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302556 /* ARQ II */
2557 bts->dl_arq_type = EGPRS_ARQ2;
2558
2559 /*
2560 * Simulate a message captured during over-the-air testing,
2561 * where the following values were observed:
2562 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2563 */
2564 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2565 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2566 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2568
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002569 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
aravind sirsikarf2761382016-10-25 12:45:24 +05302570 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002571 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302572 prlcmvb = &prlcdlwindow->m_v_b;
2573 prlcdlwindow->m_v_s = 1288;
2574 prlcdlwindow->m_v_a = 1176;
2575 prlcdlwindow->set_sns(2048);
2576 prlcdlwindow->set_ws(480);
2577 prlcmvb->mark_unacked(1176);
2578 prlcmvb->mark_unacked(1177);
2579 prlcmvb->mark_unacked(1286);
2580 prlcmvb->mark_unacked(1287);
2581
2582 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2583
Alexander Couzensccde5c92017-02-04 03:10:08 +01002584 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302585
2586 bitvec_unpack(block, data_msg);
2587
2588 bits.data = bits_data;
2589 bits.data_len = sizeof(bits_data);
2590 bits.cur_bit = 0;
2591
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002592 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2593 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302594
2595 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2596
2597 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2598 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2599 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2600 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2601
2602 Decoding::decode_egprs_acknack_bits(
2603 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002604 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302605
2606 dl_tbf->rcvd_dl_ack(
2607 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2608 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302609
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302610 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2611 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2612 OSMO_ASSERT(prlcmvb->is_acked(1286));
2613 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302614
2615 bitvec_free(block);
2616 tbf_free(dl_tbf);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002617 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002618 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302619}
2620
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302621static void test_tbf_egprs_two_phase_spb(void)
2622{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002623 the_pcu->bts = bts_alloc(the_pcu);
2624 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302625 int ts_no = 7;
2626 uint32_t fn = 2654218;
2627 uint16_t qta = 31;
2628 uint32_t tlli = 0xf1223344;
2629 const char *imsi = "0011223344";
2630 uint8_t ms_class = 1;
2631 uint8_t egprs_ms_class = 1;
2632 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302633 uint8_t test_data[256];
2634
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002635 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302636
2637 memset(test_data, 1, sizeof(test_data));
2638
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002639 setup_bts(the_bts, ts_no, 4);
2640 the_bts->bts_data()->initial_mcs_dl = 9;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302641
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002642 ul_tbf = establish_ul_tbf_two_phase_spb(the_bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302643 ms_class, egprs_ms_class);
2644
Max4c112dc2018-02-01 16:49:23 +01002645 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002646 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302647
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002648 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002649 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302650}
2651
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002652static void test_tbf_egprs_two_phase()
2653{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002654 the_pcu->bts = bts_alloc(the_pcu);
2655 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002656 int ts_no = 7;
2657 uint32_t fn = 2654218;
2658 uint16_t qta = 31;
2659 uint32_t tlli = 0xf1223344;
2660 const char *imsi = "0011223344";
2661 uint8_t ms_class = 1;
2662 uint8_t egprs_ms_class = 1;
2663 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002664 uint8_t test_data[256];
2665
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002666 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002667
2668 memset(test_data, 1, sizeof(test_data));
2669
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002670 setup_bts(the_bts, ts_no, 4);
2671 the_bts->bts_data()->initial_mcs_dl = 9;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002672
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002673 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002674 ms_class, egprs_ms_class);
2675
Max4c112dc2018-02-01 16:49:23 +01002676 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002677 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002678
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002679 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002680 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002681}
2682
2683static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
2684{
2685 unsigned i;
2686 uint8_t ms_class = 11;
2687 uint8_t egprs_ms_class = 11;
2688 uint32_t fn = 0;
2689 uint8_t trx_no;
2690 uint32_t tlli = 0xffeeddcc;
2691 uint8_t test_data[512];
2692
2693 uint8_t rbb[64/8];
2694
2695 gprs_rlcmac_dl_tbf *dl_tbf;
2696
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002697 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002698
2699 memset(test_data, 1, sizeof(test_data));
2700 the_bts->bts_data()->initial_mcs_dl = mcs;
2701
2702 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2703 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2704
2705 for (i = 0; i < sizeof(llc_data); i++)
2706 llc_data[i] = i%256;
2707
2708 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2709
2710 /* Schedule a small LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002711 dl_tbf->append_data(1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002712
2713 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2714
2715 /* Drain the queue */
2716 while (dl_tbf->have_data())
2717 /* Request to send one RLC/MAC block */
2718 request_dl_rlc_block(dl_tbf, &fn);
2719
2720 /* Schedule a large LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002721 dl_tbf->append_data(1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002722
2723 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2724
2725 /* Drain the queue */
2726 while (dl_tbf->have_data())
2727 /* Request to send one RLC/MAC block */
2728 request_dl_rlc_block(dl_tbf, &fn);
2729
2730 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2731
Max7d32f552017-12-15 11:25:14 +01002732 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002733
2734 /* Clean up and ensure tbfs are in the correct state */
2735 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002736 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002737 check_tbf(dl_tbf);
2738 tbf_free(dl_tbf);
2739}
2740
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302741static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
2742 int mcs)
2743{
2744 unsigned i;
2745 uint8_t ms_class = 11;
2746 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302747 uint8_t trx_no;
2748 uint32_t tlli = 0xffeeddcc;
2749 uint8_t test_data[512];
2750
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302751 gprs_rlcmac_dl_tbf *dl_tbf;
2752
2753 memset(test_data, 1, sizeof(test_data));
2754 the_bts->bts_data()->initial_mcs_dl = mcs;
2755
2756 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2757 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2758
2759 for (i = 0; i < sizeof(test_data); i++)
2760 test_data[i] = i%256;
2761
2762 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2763
2764 /* Schedule a LLC frame
2765 * passing only 100 bytes, since it is enough to construct
2766 * 2 RLC data blocks. Which are enough to test Header Type 1
2767 * cases
2768 */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002769 dl_tbf->append_data(1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302770
2771 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2772
2773 return dl_tbf;
2774
2775}
2776
2777static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2778{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302779 uint8_t rbb[64/8];
2780
Max7d32f552017-12-15 11:25:14 +01002781 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302782
2783 /* Clean up and ensure tbfs are in the correct state */
2784 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002785 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302786 check_tbf(dl_tbf);
2787 tbf_free(dl_tbf);
2788
2789}
2790
Max7d32f552017-12-15 11:25:14 +01002791#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002792 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2793 w->m_v_b.mark_nacked(x); \
2794 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002795 } while(0)
2796
2797#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002798 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2799 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002800 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002801 } while(0)
2802
2803#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002804 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2805 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002806 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002807 } while(0)
2808
2809#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
2810 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
2811 OSMO_ASSERT(m); \
2812 if (check_unacked) \
2813 CHECK_UNACKED(tbf, cs, 0); \
2814 else \
2815 CHECK_NACKED(tbf, cs, 0); \
2816 } while(0)
2817
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302818static void egprs_spb_to_normal_validation(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002819 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302820{
2821 uint32_t fn = 0;
2822 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302823 uint16_t bsn1, bsn2, bsn3;
2824 struct msgb *msg;
2825 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2826 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2827
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002828 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302829
2830 dl_tbf = tbf_init(the_bts, mcs);
2831
2832 /*
2833 * Table 10.4.8a.3.1 of 44.060.
2834 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2835 * (MCS5, MCS6) to (MCS2, MCS3) transition
2836 */
2837 if (!(mcs == 6 && demanded_mcs == 3))
2838 return;
2839
2840 fn = fn_add_blocks(fn, 1);
2841 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002842 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302843
2844 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01002845 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01002846
2847 NACK(dl_tbf, 0);
2848
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302849 OSMO_ASSERT(bsn1 == 0);
2850
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002851 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302852
2853 fn = fn_add_blocks(fn, 1);
2854
2855 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002856 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302857 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2858 == EGPRS_RESEG_FIRST_SEG_SENT);
2859
2860 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2861 OSMO_ASSERT(egprs3->spb == 2);
2862
2863 /* Table 10.4.8a.3.1 of 44.060 */
2864 OSMO_ASSERT(egprs3->cps == 3);
2865
2866 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002867 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302868 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2869 == EGPRS_RESEG_SECOND_SEG_SENT);
2870
2871 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2872 /* Table 10.4.8a.3.1 of 44.060 */
2873 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01002874 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302875 OSMO_ASSERT(bsn2 == bsn1);
2876
2877 /* Table 10.4.8a.3.1 of 44.060 */
2878 OSMO_ASSERT(egprs3->cps == 3);
2879
2880 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002881 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302882
Max7d32f552017-12-15 11:25:14 +01002883 NACK(dl_tbf, 0);
2884
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302885 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2886 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2887
2888 /* Table 10.4.8a.3.1 of 44.060 */
2889 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01002890 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302891 OSMO_ASSERT(bsn3 == bsn2);
2892
2893 tbf_cleanup(dl_tbf);
2894}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002895
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302896static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002897 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302898{
2899 uint32_t fn = 0;
2900 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302901 struct msgb *msg;
2902 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2903
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002904 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302905
2906 dl_tbf = tbf_init(the_bts, mcs);
2907
2908 /*
2909 * Table 10.4.8a.3.1 of 44.060.
2910 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2911 * (MCS5, MCS6) to (MCS2, MCS3) transition
2912 */
2913 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2914 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2915 * dated 2016-02-07 23:45:40 (UTC)
2916 */
2917 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2918 ((mcs == 6) && (demanded_mcs == 3)) ||
2919 ((mcs == 4) && (demanded_mcs == 1))))
2920 return;
2921
2922 fn = fn_add_blocks(fn, 1);
2923 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002924 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302925
Max7d32f552017-12-15 11:25:14 +01002926 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302927
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002928 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302929
2930 fn = fn_add_blocks(fn, 1);
2931
2932 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002933 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302934 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2935 == EGPRS_RESEG_FIRST_SEG_SENT);
2936
2937 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2938 OSMO_ASSERT(egprs3->spb == 2);
2939
2940 /* Table 10.4.8a.3.1 of 44.060 */
2941 switch (demanded_mcs) {
2942 case 3:
2943 OSMO_ASSERT(egprs3->cps == 3);
2944 break;
2945 case 2:
2946 OSMO_ASSERT(egprs3->cps == 9);
2947 break;
2948 case 1:
2949 OSMO_ASSERT(egprs3->cps == 11);
2950 break;
2951 default:
2952 OSMO_ASSERT(false);
2953 break;
2954 }
2955
2956 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002957 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302958 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2959 == EGPRS_RESEG_SECOND_SEG_SENT);
2960
2961 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2962 /* Table 10.4.8a.3.1 of 44.060 */
2963 OSMO_ASSERT(egprs3->spb == 3);
2964
2965 /* Table 10.4.8a.3.1 of 44.060 */
2966 switch (demanded_mcs) {
2967 case 3:
2968 OSMO_ASSERT(egprs3->cps == 3);
2969 break;
2970 case 2:
2971 OSMO_ASSERT(egprs3->cps == 9);
2972 break;
2973 case 1:
2974 OSMO_ASSERT(egprs3->cps == 11);
2975 break;
2976 default:
2977 OSMO_ASSERT(false);
2978 break;
2979 }
2980 tbf_cleanup(dl_tbf);
2981}
2982
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302983static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002984 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302985{
2986 uint32_t fn = 0;
2987 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302988 struct msgb *msg;
2989
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002990 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302991
2992 dl_tbf = tbf_init(the_bts, mcs);
2993
2994 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
2995 * The MCS transition are referred from table Table 8.1.1.2
2996 * of TS 44.060
2997 */
2998 /* TODO: Need to support of MCS8 -> MCS6 transistion
2999 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3000 * dated 2016-02-07 23:45:40 (UTC)
3001 */
3002 if (((mcs == 9) && (demanded_mcs < 9)) ||
3003 ((mcs == 7) && (demanded_mcs < 7))) {
3004 fn = fn_add_blocks(fn, 1);
3005 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003006 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3007 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303008
Max7d32f552017-12-15 11:25:14 +01003009 NACK(dl_tbf, 0);
3010 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303011
3012 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003013 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303014
3015 fn = fn_add_blocks(fn, 1);
3016 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003017 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3018 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303019
3020 fn = fn_add_blocks(fn, 1);
3021 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003022 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3023 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303024 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3025 ((mcs == 6) && (demanded_mcs > 8))) {
3026 fn = fn_add_blocks(fn, 1);
3027 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003028 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303029
3030 fn = fn_add_blocks(fn, 1);
3031 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003032 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3033 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303034
Max7d32f552017-12-15 11:25:14 +01003035 NACK(dl_tbf, 0);
3036 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303037
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003038 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303039
3040 fn = fn_add_blocks(fn, 1);
3041 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003042 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3043 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303044 } else if (mcs > 6) {
3045 /* No Mcs change cases are handled here for mcs > MCS6*/
3046 fn = fn_add_blocks(fn, 1);
3047 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003048 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3049 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303050
Max7d32f552017-12-15 11:25:14 +01003051 NACK(dl_tbf, 0);
3052 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303053
3054 fn = fn_add_blocks(fn, 1);
3055 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003056 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3057 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303058 } else {
3059
3060 /* No MCS change cases are handled here for mcs <= MCS6*/
3061 fn = fn_add_blocks(fn, 1);
3062 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003063 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303064
Max7d32f552017-12-15 11:25:14 +01003065 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303066
3067 fn = fn_add_blocks(fn, 1);
3068 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003069 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303070 }
3071
3072 tbf_cleanup(dl_tbf);
3073}
3074
3075static void test_tbf_egprs_retx_dl(void)
3076{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003077 the_pcu->bts = bts_alloc(the_pcu);
3078 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303079 gprs_rlcmac_bts *bts;
3080 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303081
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003082 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303083
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003084 bts = the_bts->bts_data();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303085 bts->cs_downgrade_threshold = 0;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003086 setup_bts(the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02003087 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303088 /* ARQ II */
3089 bts->dl_arq_type = EGPRS_ARQ2;
3090
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303091
3092 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003093 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 6);
3094 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 1, 9);
3095 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 2, 8);
3096 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 5, 7);
3097 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 9);
3098 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 7, 5);
3099 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303100
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003101 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003102 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303103}
3104
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303105static void test_tbf_egprs_spb_dl(void)
3106{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003107 the_pcu->bts = bts_alloc(the_pcu);
3108 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303109 gprs_rlcmac_bts *bts;
3110 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303111
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003112 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303113
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003114 bts = the_bts->bts_data();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303115 bts->cs_downgrade_threshold = 0;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003116 setup_bts(the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02003117 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303118
3119 /* ARQ I resegmentation support */
3120 bts->dl_arq_type = EGPRS_ARQ1;
3121
3122 /*
3123 * First parameter is current MCS, second one is demanded_mcs
3124 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3125 * rest scenarios has been integration tested
3126 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003127 establish_and_use_egprs_dl_tbf_for_spb(the_bts, 6, 3);
3128 establish_and_use_egprs_dl_tbf_for_spb(the_bts, 5, 2);
3129 establish_and_use_egprs_dl_tbf_for_spb(the_bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303130 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003131 egprs_spb_to_normal_validation(the_bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303132
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003133 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003134 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303135}
3136
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003137static void test_tbf_egprs_dl()
3138{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003139 the_pcu->bts = bts_alloc(the_pcu);
3140 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003141 gprs_rlcmac_bts *bts;
3142 uint8_t ts_no = 4;
3143 int i;
3144
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003145 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003146
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003147 bts = the_bts->bts_data();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003148
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003149 setup_bts(the_bts, ts_no);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +02003150 OSMO_ASSERT(osmo_tdef_set(bts->T_defs_pcu, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303151 /* ARQ II */
3152 bts->dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003153
3154 for (i = 1; i <= 9; i++)
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003155 establish_and_use_egprs_dl_tbf(the_bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003156
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003157 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003158 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003159}
3160
3161
3162
aravind sirsikare9a138e2017-01-24 12:36:08 +05303163static void test_packet_access_rej_prr_no_other_tbfs()
3164{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003165 the_pcu->bts = bts_alloc(the_pcu);
3166 BTS *the_bts = the_pcu->bts;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303167 uint32_t fn = 2654218;
3168 int ts_no = 7;
3169 uint8_t trx_no = 0;
3170 uint32_t tlli = 0xffeeddcc;
3171 struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
3172
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003173 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303174
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003175 setup_bts(the_bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303176
3177 int rc = 0;
3178
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003179 ul_tbf = handle_tbf_reject(the_bts->bts_data(), NULL, tlli,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303180 trx_no, ts_no);
3181
3182 OSMO_ASSERT(ul_tbf != 0);
3183
3184 /* trigger packet access reject */
3185 uint8_t bn = fn2bn(fn);
3186
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003187 rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
aravind sirsikare9a138e2017-01-24 12:36:08 +05303188 trx_no, ts_no, fn, bn);
3189
3190 OSMO_ASSERT(rc == 0);
3191
3192 ul_tbf->handle_timeout();
3193
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003194 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003195 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303196}
3197
3198static void test_packet_access_rej_prr()
3199{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003200 the_pcu->bts = bts_alloc(the_pcu);
3201 BTS *the_bts = the_pcu->bts;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303202 uint32_t fn = 2654218;
3203 uint16_t qta = 31;
3204 int ts_no = 7;
3205 uint8_t trx_no = 0;
3206 RlcMacUplink_t ulreq = {0};
3207 Packet_Resource_Request_t *presreq = NULL;
3208 uint8_t ms_class = 11;
3209 uint8_t egprs_ms_class = 11;
3210 uint32_t rach_fn = fn - 51;
3211 uint32_t sba_fn = fn + 52;
3212 uint32_t tlli = 0xffeeddcc;
3213 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3214 Multislot_capability_t *pmultislotcap = NULL;
3215
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003216 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303217
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003218 setup_bts(the_bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303219
3220 int rc = 0;
3221
3222 /*
3223 * Trigger rach till resources(USF) exhaust
3224 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003225 rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);
3226 rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);
3227 rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);
3228 rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);
3229 rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);
3230 rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);
3231 rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303232
3233 /* fake a resource request */
3234 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3235 presreq = &ulreq.u.Packet_Resource_Request;
3236 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3237 presreq->ID.UnionType = 1; /* != 0 */
3238 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01003239 presreq->Exist_MS_Radio_Access_capability2 = 1;
3240 pmsradiocap = &presreq->MS_Radio_Access_capability2;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303241 pmsradiocap->Count_MS_RA_capability_value = 1;
3242 pmsradiocap->MS_RA_capability_value[0].u.Content.
3243 Exist_Multislot_capability = 1;
3244 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3245 u.Content.Multislot_capability;
3246
3247 pmultislotcap->Exist_GPRS_multislot_class = 1;
3248 pmultislotcap->GPRS_multislot_class = ms_class;
3249 if (egprs_ms_class) {
3250 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3251 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3252 }
3253
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003254 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303255
3256 /* trigger packet access reject */
3257 uint8_t bn = fn2bn(fn);
3258
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003259 rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
aravind sirsikare9a138e2017-01-24 12:36:08 +05303260 trx_no, ts_no, fn, bn);
3261
3262 OSMO_ASSERT(rc == 0);
3263
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003264 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003265 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303266}
3267
aravind sirsikared3413e2016-11-11 17:15:10 +05303268void test_packet_access_rej_epdan()
3269{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003270 the_pcu->bts = bts_alloc(the_pcu);
3271 BTS *the_bts = the_pcu->bts;
aravind sirsikared3413e2016-11-11 17:15:10 +05303272 uint32_t tlli = 0xffeeddcc;
Maxd3a0d912019-03-05 16:15:01 +01003273 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x41, 0x4b,
3274 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3275 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3276 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303277
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003278 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003279 setup_bts(the_bts, 4);
3280 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(the_bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303281
3282 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3283
3284 struct msgb *msg = dl_tbf->create_packet_access_reject();
3285
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003286 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303287 osmo_hexdump(msg->data, 23));
3288
Maxd3a0d912019-03-05 16:15:01 +01003289 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003290 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003291
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003292 TALLOC_FREE(the_pcu->bts);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003293 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303294}
3295
3296
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003297int main(int argc, char **argv)
3298{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003299 struct vty_app_info pcu_vty_info = {0};
3300
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003301 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3302 if (!tall_pcu_ctx)
3303 abort();
3304
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003305 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003306 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003307 log_set_use_color(osmo_stderr_target, 0);
3308 log_set_print_filename(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003309 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003310 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003311 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003312
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003313 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003314 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003315 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003316
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003317 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003318 pcu_l1_meas_set_link_qual(&meas, 12);
3319 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003320
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003321 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003322 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003323 test_tbf_final_ack(TEST_MODE_STANDARD);
3324 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003325 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003326 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003327 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003328 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003329 test_tbf_single_phase();
3330 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003331 test_tbf_ra_update_rach();
3332 test_tbf_dl_flow_and_rach_two_phase();
3333 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003334 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003335 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003336 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003337 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303338 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003339 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303340 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303341 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303342 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303343 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303344 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303345 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303346 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303347 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303348 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303349 test_packet_access_rej_prr();
3350 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003351
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003352
3353 talloc_free(the_pcu);
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003354 if (getenv("TALLOC_REPORT_FULL"))
3355 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003356 return EXIT_SUCCESS;
3357}
3358
3359/*
3360 * stubs that should not be reached
3361 */
3362extern "C" {
3363void l1if_pdch_req() { abort(); }
3364void l1if_connect_pdch() { abort(); }
3365void l1if_close_pdch() { abort(); }
3366void l1if_open_pdch() { abort(); }
3367}