blob: 1b85201531441d928c3b8e9332efc0b4a8ad4197 [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 Pedrol47f15fb2021-01-14 14:28:26 +010094 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +010095 the_pcu->bts = bts_alloc(the_pcu);
96 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck93990462015-05-15 15:50:43 +020097 GprsMs *ms, *ms_new;
98
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020099 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100100
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100101 the_pcu->alloc_algorithm = alloc_algorithm_a;
102 the_bts->bts_data()->trx[0].pdch[2].enable();
103 the_bts->bts_data()->trx[0].pdch[3].enable();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100104
105 /*
106 * Make a uplink and downlink allocation
107 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100108 ms = the_bts->ms_alloc(0, 0);
109 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts->bts_data(),
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200110 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200111 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200112 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200113 dl_tbf->set_ta(4);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100114 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200115 OSMO_ASSERT(dl_tbf->ms() == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100116
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100117 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts->bts_data(),
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200118 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200119 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200120 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100121 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200122 OSMO_ASSERT(ul_tbf->ms() == ms);
123
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100124 OSMO_ASSERT(the_bts->ms_by_tlli(0x2342) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100125
126 /*
127 * Now check.. that DL changes and that the timing advance
128 * has changed.
129 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200130 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100131
Jacob Erlbeck93990462015-05-15 15:50:43 +0200132 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100133 ms_new = the_bts->ms_by_tlli(0x2342);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200134 OSMO_ASSERT(ms == ms_new);
135
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100136 ms_new = the_bts->ms_by_tlli(0x4232);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200137 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100138 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
139 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200140
141 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200142 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100143 ms_new = the_bts->ms_by_tlli(0x2342);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200144 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100145
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100146 ms_new = the_bts->ms_by_tlli(0x4232);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200147 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100148 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200149
150 OSMO_ASSERT(ul_tbf->ta() == 4);
151 OSMO_ASSERT(dl_tbf->ta() == 4);
152
153 ul_tbf->set_ta(6);
154
155 OSMO_ASSERT(ul_tbf->ta() == 6);
156 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100157
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200158 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100159 TALLOC_FREE(the_pcu);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100160}
161
Daniel Willmann510d7d32014-08-15 18:19:41 +0200162static uint8_t llc_data[200];
163
Maxa2961182018-01-25 19:47:28 +0100164/* override, requires '-Wl,--wrap=pcu_sock_send' */
165int __real_pcu_sock_send(struct msgb *msg);
166int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200167{
168 return 0;
169}
170
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200171static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100172{
173 gprs_rlcmac_bts *bts;
174 gprs_rlcmac_trx *trx;
175
176 bts = the_bts->bts_data();
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100177 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200178 bts->initial_cs_dl = cs;
179 bts->initial_cs_ul = cs;
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100180 osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S);
181 osmo_tdef_set(the_pcu->T_defs, -2031, 0, OSMO_TDEF_S);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100182 trx = &bts->trx[0];
183
184 trx->pdch[ts_no].enable();
Philippd935d882016-11-07 13:07:36 +0100185 the_bts->set_current_frame_number(DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100186}
187
188static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100189 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100190{
191 gprs_rlcmac_bts *bts;
192 int tfi;
193 uint8_t trx_no;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200194 GprsMs *ms;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100195 gprs_rlcmac_dl_tbf *dl_tbf;
196
197 bts = the_bts->bts_data();
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200198 ms = the_bts->ms_alloc(ms_class, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100199
200 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
201 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200202 dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100203 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200204 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100205 check_tbf(dl_tbf);
206
207 /* "Establish" the DL TBF */
Max0e599802018-01-23 20:09:06 +0100208 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
Max2399b1d2018-01-12 15:48:12 +0100209 TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_FLOW);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100210 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100211 check_tbf(dl_tbf);
212
213 *trx_no_ = trx_no;
214
215 return dl_tbf;
216}
217
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200218static unsigned fn2bn(unsigned fn)
219{
220 return (fn % 52) / 4;
221}
222
223static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
224{
225 unsigned bn = fn2bn(fn) + blocks;
226 fn = fn - (fn % 52);
227 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200228 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200229}
230
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200231static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200232 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200233 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100234{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200235 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200236 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200237 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200238 bn += 1;
239 if (block_nr)
240 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100241}
242
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200243static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200244 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200245{
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200246 request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200247 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200248}
249
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100250enum test_tbf_final_ack_mode {
251 TEST_MODE_STANDARD,
252 TEST_MODE_REVERSE_FREE
253};
254
255static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200256{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100257 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100258 the_pcu->bts = bts_alloc(the_pcu);
259 BTS *the_bts = the_pcu->bts;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100260 uint8_t ts_no = 4;
261 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200262 uint8_t ms_class = 45;
263 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100264 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100265 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200266 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200267 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200268
269 uint8_t rbb[64/8];
270
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200271 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100272
Daniel Willmann510d7d32014-08-15 18:19:41 +0200273 gprs_rlcmac_dl_tbf *dl_tbf;
274 gprs_rlcmac_tbf *new_tbf;
275
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100276 setup_bts(the_bts, ts_no);
277 dl_tbf = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200278 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200279 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200280
281 for (i = 0; i < sizeof(llc_data); i++)
282 llc_data[i] = i%256;
283
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100284 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100285 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
286 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200287
288
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100289 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200290 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200291 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200292 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200293 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200294 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200295
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100296 OSMO_ASSERT(dl_tbf->have_data());
297 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200298
299 /* Queue a final ACK */
300 memset(rbb, 0, sizeof(rbb));
301 /* Receive a final ACK */
Max7df82d42017-12-15 11:14:30 +0100302 dl_tbf->rcvd_dl_ack(true, 1, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200303
304 /* Clean up and ensure tbfs are in the correct state */
305 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100306 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100307 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200308 OSMO_ASSERT(new_tbf != dl_tbf);
309 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100310 check_tbf(dl_tbf);
Max0e599802018-01-23 20:09:06 +0100311 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100312 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100313 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100314 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100315 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100316 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100317 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100318 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100319 } else {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100320 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100321 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100322 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100323 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100324 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100325 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
326 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100327 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100328
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100329 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200330 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200331}
332
Max7d32f552017-12-15 11:25:14 +0100333/* Receive an ACK */
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200334#define RCV_ACK(fin, tbf, rbb) do { \
335 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
336 tbf->rcvd_dl_ack(fin, w->v_s(), rbb); \
Max7d32f552017-12-15 11:25:14 +0100337 if (!fin) \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200338 OSMO_ASSERT(w->window_empty()); \
Max7d32f552017-12-15 11:25:14 +0100339 } while(0)
340
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100341static void test_tbf_delayed_release()
342{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100343 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100344 the_pcu->bts = bts_alloc(the_pcu);
345 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100346 uint8_t ts_no = 4;
347 unsigned i;
348 uint8_t ms_class = 45;
349 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100350 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200351 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200352 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100353
354 uint8_t rbb[64/8];
355
356 gprs_rlcmac_dl_tbf *dl_tbf;
357
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200358 fprintf(stderr, "=== start %s ===\n", __func__);
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 Pedrol924aaad2021-01-14 12:01:42 +0100361 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -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 Pedrol924aaad2021-01-14 12:01:42 +0100395 dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200396 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 Pedrol47f15fb2021-01-14 14:28:26 +0100408 TALLOC_FREE(the_pcu);
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 Pedrol47f15fb2021-01-14 14:28:26 +0100414 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100415 the_pcu->bts = bts_alloc(the_pcu);
416 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200417 uint8_t ts_no = 4;
418 uint8_t ms_class = 45;
419 uint8_t trx_no;
420 GprsMs *ms1, *ms2;
421
422 gprs_rlcmac_dl_tbf *dl_tbf[2];
423
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200424 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200425
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100426 setup_bts(the_bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200427
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100428 dl_tbf[0] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
429 dl_tbf[1] = create_dl_tbf(the_bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200430
431 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
432 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
433
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100434 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100435 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200436 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100437 ms2 = the_bts->ms_store().get_ms(0xf1000001);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200438 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100439 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200440 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200441
442 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100443 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100444 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200445 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100446 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200447 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100448 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200449 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200450
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100451 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200452 {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100453 ms_ref(ms2);
454 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100455 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200456 OSMO_ASSERT(ms1 != NULL);
457 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100458 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
459 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
460 ms_unref(ms2);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200461 }
462
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100463 ms2 = the_bts->ms_store().get_ms(0xf1000001);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200464 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200465
466 tbf_free(dl_tbf[1]);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100467 ms1 = the_bts->ms_store().get_ms(0, 0, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200468 OSMO_ASSERT(ms1 == NULL);
469
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100470 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200471 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200472}
473
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200474static void test_tbf_exhaustion()
475{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100476 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100477 the_pcu->bts = bts_alloc(the_pcu);
478 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200479 gprs_rlcmac_bts *bts;
480 unsigned i;
481 uint8_t ts_no = 4;
482 uint8_t ms_class = 45;
483 int rc = 0;
484
485 uint8_t buf[256] = {0};
486
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200487 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200488
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100489 bts = the_bts->bts_data();
490 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
491 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200492 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
493 abort();
494 }
495
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100496 setup_bts(the_bts, ts_no);
Alexander Couzens290d9032020-09-16 21:52:02 +0200497 gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200498
499 for (i = 0; i < 1024; i++) {
500 uint32_t tlli = 0xc0000000 + i;
501 char imsi[16] = {0};
502 unsigned delay_csec = 1000;
503
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200504 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200505
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100506 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200507 delay_csec, buf, sizeof(buf));
508
509 if (rc < 0)
510 break;
511 }
512
513 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200514 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200515
Alexander Couzens290d9032020-09-16 21:52:02 +0200516 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100517 TALLOC_FREE(the_pcu);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200518}
519
Jacob Erlbeck41168642015-06-12 13:41:00 +0200520static void test_tbf_dl_llc_loss()
521{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100522 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100523 the_pcu->bts = bts_alloc(the_pcu);
524 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck41168642015-06-12 13:41:00 +0200525 gprs_rlcmac_bts *bts;
526 uint8_t ts_no = 4;
527 uint8_t ms_class = 45;
528 int rc = 0;
529 uint32_t tlli = 0xc0123456;
530 const char *imsi = "001001000123456";
531 unsigned delay_csec = 1000;
532 GprsMs *ms;
533
534 uint8_t buf[19];
535
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100536 bts = the_bts->bts_data();
537 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
538 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200539 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
540 abort();
541 }
542
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200543 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200544
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100545 setup_bts(the_bts, ts_no);
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200546 /* keep the MS object 10 seconds */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100547 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200548
Alexander Couzens290d9032020-09-16 21:52:02 +0200549 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200550
551 /* Handle LLC frame 1 */
552 memset(buf, 1, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100553 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200554 delay_csec, buf, sizeof(buf));
555 OSMO_ASSERT(rc >= 0);
556
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100557 ms = the_bts->ms_store().get_ms(0, 0, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200558 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100559 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
560 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200561
562 /* Handle LLC frame 2 */
563 memset(buf, 2, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100564 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200565 delay_csec, buf, sizeof(buf));
566 OSMO_ASSERT(rc >= 0);
567
568 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100569 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200570
571 /* Handle LLC frame 3 */
572 memset(buf, 3, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100573 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200574 delay_csec, buf, sizeof(buf));
575 OSMO_ASSERT(rc >= 0);
576
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100577 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200578
579 /* Get first BSN */
580 struct msgb *msg;
581 int fn = 0;
582 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100583 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
584 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
585 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
586 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
587 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
588 { 0x07, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
589 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
590 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200591
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100592 while (ms_dl_tbf(ms)->have_data()) {
593 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, 7);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200594 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100595 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200596 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100597
Jacob Erlbeck41168642015-06-12 13:41:00 +0200598 expected_data += 1;
599 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200600 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200601
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200602 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200603
Alexander Couzens290d9032020-09-16 21:52:02 +0200604 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100605 TALLOC_FREE(the_pcu);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200606}
607
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200608static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
609 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200610{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200611 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200612 int tfi = 0;
613 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200614 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200615 struct gprs_rlcmac_pdch *pdch;
616
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200617 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200618
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +0700619 bts_handle_rach(the_bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200620
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200621 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200622 OSMO_ASSERT(ul_tbf != NULL);
623
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200624 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200625
626 uint8_t data_msg[23] = {
627 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
628 uint8_t(1 | (tfi << 2)),
629 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200630 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
631 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200632 };
633
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200634 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
635 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200636
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200637 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200638 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200639
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200640 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200641}
642
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200643static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
644 RlcMacUplink_t *ulreq, unsigned fn)
645{
646 bitvec *rlc_block;
647 uint8_t buf[64];
648 int num_bytes;
649 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200650
Alexander Couzensccde5c92017-02-04 03:10:08 +0100651 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200652
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100653 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200654 num_bytes = bitvec_pack(rlc_block, &buf[0]);
655 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
656 bitvec_free(rlc_block);
657
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200658 the_bts->set_current_block_frame_number(fn, 0);
659
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200660 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
661 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
662}
663
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200664static void send_control_ack(gprs_rlcmac_tbf *tbf)
665{
666 RlcMacUplink_t ulreq = {0};
667
668 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100669 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200670
671 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
672 Packet_Control_Acknowledgement_t *ctrl_ack =
673 &ulreq.u.Packet_Control_Acknowledgement;
674
675 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
676 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100677 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200678 &ulreq, tbf->poll_fn);
679}
680
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530681static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
682 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
683 uint8_t ms_class, uint8_t egprs_ms_class)
684{
685 GprsMs *ms;
686 uint32_t rach_fn = *fn - 51;
687 uint32_t sba_fn = *fn + 52;
688 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100689 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530690 gprs_rlcmac_ul_tbf *ul_tbf;
691 struct gprs_rlcmac_pdch *pdch;
692 gprs_rlcmac_bts *bts;
693 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530694 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530695
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530696 bts = the_bts->bts_data();
697
698 /* needed to set last_rts_fn in the PDCH object */
699 request_dl_rlc_block(bts, trx_no, ts_no, fn);
700
701 /*
702 * simulate RACH, this sends an Immediate
703 * Assignment Uplink on the AGCH
704 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +0700705 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530706
707 /* get next free TFI */
708 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
709
710 /* fake a resource request */
711 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
712 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
713 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
714 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100715 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
716 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530717 Count_MS_RA_capability_value = 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.
720 Exist_Multislot_capability = 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 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100724 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530725 MS_RA_capability_value[0].u.Content.Multislot_capability.
726 GPRS_multislot_class = ms_class;
727 if (egprs_ms_class) {
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.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100731 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530732 MS_RA_capability_value[0].u.Content.
733 Multislot_capability.EGPRS_multislot_class = ms_class;
734 }
735
736 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
737
738 /* check the TBF */
739 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
740 OSMO_ASSERT(ul_tbf);
741 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
742
743 /* send packet uplink assignment */
744 *fn = sba_fn;
745 request_dl_rlc_block(ul_tbf, fn);
746
747 /* send real acknowledgement */
748 send_control_ack(ul_tbf);
749
750 check_tbf(ul_tbf);
751 /* send fake data */
752 uint8_t data_msg[42] = {
753 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100754 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530755 1, /* BSN:7, E:1 */
756 };
757
758 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
759 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
760
761 ms = the_bts->ms_by_tlli(tlli);
762 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100763 OSMO_ASSERT(ms_ta(ms) == qta/4);
764 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530765
766 /*
767 * TS 44.060, B.8.1
768 * first seg received first, later second seg
769 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530770 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
771 egprs3->si = 0;
772 egprs3->r = 1;
773 egprs3->cv = 7;
774 egprs3->tfi_hi = tfi & 0x03;
775 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
776 egprs3->bsn1_hi = 1;
777 egprs3->bsn1_lo = 0;
778 egprs3->cps_hi = 1;
779 data_msg[3] = 0xff;
780 egprs3->pi = 0;
781 egprs3->cps_lo = 1;
782 egprs3->rsb = 0;
783 egprs3->spb = 0;
784 egprs3->pi = 0;
785
786 pdch->rcv_block(data_msg, 42, *fn, &meas);
787
788 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
789
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100790 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x87, 0xb0, 0x06,
Maxd3a0d912019-03-05 16:15:01 +0100791 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
792 };
793
794 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200795 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100796 return NULL;
797 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530798
799 egprs3->si = 0;
800 egprs3->r = 1;
801 egprs3->cv = 7;
802 egprs3->tfi_hi = tfi & 0x03;
803 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
804 egprs3->bsn1_hi = 4;
805 egprs3->bsn1_lo = 0;
806 egprs3->cps_hi = 1;
807 data_msg[3] = 0xff;
808 egprs3->pi = 0;
809 egprs3->cps_lo = 1;
810 egprs3->rsb = 0;
811 egprs3->spb = 0;
812
813 pdch->rcv_block(data_msg, 42, *fn, &meas);
814
815 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
816
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100817 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x88, 0xb0, 0x06, 0x8b,
Maxd3a0d912019-03-05 16:15:01 +0100818 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
819 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530820
Maxd3a0d912019-03-05 16:15:01 +0100821 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200822 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100823 return NULL;
824 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530825 return ul_tbf;
826}
827
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530828static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
829 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
830 uint8_t ms_class, uint8_t egprs_ms_class)
831{
832 GprsMs *ms;
833 uint32_t rach_fn = *fn - 51;
834 uint32_t sba_fn = *fn + 52;
835 uint8_t trx_no = 0;
836 int tfi = 0, i = 0;
837 gprs_rlcmac_ul_tbf *ul_tbf;
838 struct gprs_rlcmac_pdch *pdch;
839 gprs_rlcmac_bts *bts;
840 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530841 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530842
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530843 bts = the_bts->bts_data();
844
845 /* needed to set last_rts_fn in the PDCH object */
846 request_dl_rlc_block(bts, trx_no, ts_no, fn);
847
848 /*
849 * simulate RACH, this sends an Immediate
850 * Assignment Uplink on the AGCH
851 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +0700852 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530853
854 /* get next free TFI */
855 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
856
857 /* fake a resource request */
858 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
859 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
860 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
861 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100862 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
863 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530864 Count_MS_RA_capability_value = 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.
867 Exist_Multislot_capability = 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 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100871 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530872 MS_RA_capability_value[0].u.Content.Multislot_capability.
873 GPRS_multislot_class = ms_class;
874 if (egprs_ms_class) {
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.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100878 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530879 MS_RA_capability_value[0].u.Content.
880 Multislot_capability.EGPRS_multislot_class = ms_class;
881 }
882
883 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
884
885 /* check the TBF */
886 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
887 OSMO_ASSERT(ul_tbf != NULL);
888 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
889
890 /* send packet uplink assignment */
891 *fn = sba_fn;
892 request_dl_rlc_block(ul_tbf, fn);
893
894 /* send real acknowledgement */
895 send_control_ack(ul_tbf);
896
897 check_tbf(ul_tbf);
898
899 /* send fake data */
900 uint8_t data_msg[42] = {
901 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
902 uint8_t(0 | (tfi << 1)),
903 uint8_t(1), /* BSN:7, E:1 */
904 };
905
906 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
907 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
908
909 ms = the_bts->ms_by_tlli(tlli);
910 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100911 OSMO_ASSERT(ms_ta(ms) == qta/4);
912 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530913
914 /*
915 * TS 44.060, B.8.1
916 * first seg received first, later second seg
917 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530918 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
919 egprs3->si = 1;
920 egprs3->r = 1;
921 egprs3->cv = 7;
922 egprs3->tfi_hi = tfi & 0x03;
923 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
924 egprs3->bsn1_hi = 1;
925 egprs3->bsn1_lo = 0;
926 egprs3->cps_hi = 1;
927 data_msg[3] = 0xff;
928 egprs3->pi = 0;
929 egprs3->cps_lo = 1;
930 egprs3->rsb = 0;
931 egprs3->spb = 2;
932 egprs3->pi = 0;
933
934 pdch->rcv_block(data_msg, 42, *fn, &meas);
935
936 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
937
938 /* check the status of the block */
939 OSMO_ASSERT(block->spb_status.block_status_ul ==
940 EGPRS_RESEG_FIRST_SEG_RXD);
941
942 egprs3->si = 1;
943 egprs3->r = 1;
944 egprs3->cv = 7;
945 egprs3->tfi_hi = tfi & 0x03;
946 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
947 egprs3->bsn1_hi = 1;
948 egprs3->bsn1_lo = 0;
949 egprs3->cps_hi = 1;
950 data_msg[3] = 0xff;
951 egprs3->pi = 0;
952 egprs3->cps_lo = 1;
953 egprs3->rsb = 0;
954 egprs3->spb = 3;
955
956 pdch->rcv_block(data_msg, 42, *fn, &meas);
957
958 /* check the status of the block */
959 OSMO_ASSERT(block->spb_status.block_status_ul ==
960 EGPRS_RESEG_DEFAULT);
961 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100962 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530963 /* Assembled MCS is MCS6. so the size is 74 */
964 OSMO_ASSERT(block->len == 74);
965
966 /*
967 * TS 44.060, B.8.1
968 * second seg first, later first seg
969 */
970 memset(data_msg, 0, sizeof(data_msg));
971
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530972 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
973 egprs3->si = 1;
974 egprs3->r = 1;
975 egprs3->cv = 7;
976 egprs3->tfi_hi = tfi & 0x03;
977 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
978 egprs3->bsn1_hi = 2;
979 egprs3->bsn1_lo = 0;
980 egprs3->cps_hi = 1;
981 data_msg[3] = 0xff;
982 egprs3->pi = 0;
983 egprs3->cps_lo = 1;
984 egprs3->rsb = 0;
985 egprs3->spb = 3;
986 egprs3->pi = 0;
987
988 pdch->rcv_block(data_msg, 42, *fn, &meas);
989
990 block = ul_tbf->m_rlc.block(2);
991 /* check the status of the block */
992 OSMO_ASSERT(block->spb_status.block_status_ul ==
993 EGPRS_RESEG_SECOND_SEG_RXD);
994
995 egprs3->si = 1;
996 egprs3->r = 1;
997 egprs3->cv = 7;
998 egprs3->tfi_hi = tfi & 0x03;
999 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1000 egprs3->bsn1_hi = 2;
1001 egprs3->bsn1_lo = 0;
1002 egprs3->cps_hi = 1;
1003 data_msg[3] = 0xff;
1004 egprs3->pi = 0;
1005 egprs3->cps_lo = 1;
1006 egprs3->rsb = 0;
1007 egprs3->spb = 2;
1008 egprs3->pi = 0;
1009
1010 pdch->rcv_block(data_msg, 42, *fn, &meas);
1011
1012 /* check the status of the block */
1013 OSMO_ASSERT(block->spb_status.block_status_ul ==
1014 EGPRS_RESEG_DEFAULT);
1015 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001016 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301017 /* Assembled MCS is MCS6. so the size is 74 */
1018 OSMO_ASSERT(block->len == 74);
1019
1020 /*
1021 * TS 44.060, B.8.1
1022 * Error scenario with spb as 1
1023 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301024 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1025 egprs3->si = 1;
1026 egprs3->r = 1;
1027 egprs3->cv = 7;
1028 egprs3->tfi_hi = tfi & 0x03;
1029 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1030 egprs3->bsn1_hi = 3;
1031 egprs3->bsn1_lo = 0;
1032 egprs3->cps_hi = 1;
1033 data_msg[3] = 0xff;
1034 egprs3->pi = 0;
1035 egprs3->cps_lo = 1;
1036 egprs3->rsb = 0;
1037 egprs3->spb = 1;
1038 egprs3->pi = 0;
1039
1040 pdch->rcv_block(data_msg, 42, *fn, &meas);
1041
1042 block = ul_tbf->m_rlc.block(3);
1043 /* check the status of the block */
1044 OSMO_ASSERT(block->spb_status.block_status_ul ==
1045 EGPRS_RESEG_DEFAULT);
1046 /*
1047 * TS 44.060, B.8.1
1048 * comparison of rlc_data for multiple scenarios
1049 * Receive First, the second(BSN 3)
1050 * Receive First, First then Second(BSN 4)
1051 * Receive Second then First(BSN 5)
1052 * after above 3 scenarios are triggered,
1053 * rlc_data of all 3 BSN are compared
1054 */
1055
1056 /* Initialize the data_msg */
1057 for (i = 0; i < 42; i++)
1058 data_msg[i] = i;
1059
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301060 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1061 egprs3->si = 1;
1062 egprs3->r = 1;
1063 egprs3->cv = 7;
1064 egprs3->tfi_hi = tfi & 0x03;
1065 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1066 egprs3->bsn1_hi = 3;
1067 egprs3->bsn1_lo = 0;
1068 egprs3->cps_hi = 1;
1069 data_msg[3] = 0xff;
1070 egprs3->pi = 0;
1071 egprs3->cps_lo = 1;
1072 egprs3->rsb = 0;
1073 egprs3->spb = 2;
1074 egprs3->pi = 0;
1075
1076 pdch->rcv_block(data_msg, 42, *fn, &meas);
1077
1078 block = ul_tbf->m_rlc.block(3);
1079 /* check the status of the block */
1080 OSMO_ASSERT(block->spb_status.block_status_ul ==
1081 EGPRS_RESEG_FIRST_SEG_RXD);
1082
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301083 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1084 egprs3->si = 1;
1085 egprs3->r = 1;
1086 egprs3->cv = 7;
1087 egprs3->tfi_hi = tfi & 0x03;
1088 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1089 egprs3->bsn1_hi = 3;
1090 egprs3->bsn1_lo = 0;
1091 egprs3->cps_hi = 1;
1092 data_msg[3] = 0xff;
1093 egprs3->pi = 0;
1094 egprs3->cps_lo = 1;
1095 egprs3->rsb = 0;
1096 egprs3->spb = 3;
1097 egprs3->pi = 0;
1098
1099 pdch->rcv_block(data_msg, 42, *fn, &meas);
1100
1101 block = ul_tbf->m_rlc.block(3);
1102 /* check the status of the block */
1103 OSMO_ASSERT(block->spb_status.block_status_ul ==
1104 EGPRS_RESEG_DEFAULT);
1105 /* Assembled MCS is MCS6. so the size is 74 */
1106 OSMO_ASSERT(block->len == 74);
1107 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001108 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301109
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301110 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1111 egprs3->si = 1;
1112 egprs3->r = 1;
1113 egprs3->cv = 7;
1114 egprs3->tfi_hi = tfi & 0x03;
1115 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1116 egprs3->bsn1_hi = 4;
1117 egprs3->bsn1_lo = 0;
1118 egprs3->cps_hi = 1;
1119 data_msg[3] = 0xff;
1120 egprs3->pi = 0;
1121 egprs3->cps_lo = 1;
1122 egprs3->rsb = 0;
1123 egprs3->spb = 2;
1124 egprs3->pi = 0;
1125
1126 pdch->rcv_block(data_msg, 42, *fn, &meas);
1127
1128 block = ul_tbf->m_rlc.block(4);
1129 /* check the status of the block */
1130 OSMO_ASSERT(block->spb_status.block_status_ul ==
1131 EGPRS_RESEG_FIRST_SEG_RXD);
1132
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301133 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1134 egprs3->si = 1;
1135 egprs3->r = 1;
1136 egprs3->cv = 7;
1137 egprs3->tfi_hi = tfi & 0x03;
1138 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1139 egprs3->bsn1_hi = 4;
1140 egprs3->bsn1_lo = 0;
1141 egprs3->cps_hi = 1;
1142 data_msg[3] = 0xff;
1143 egprs3->pi = 0;
1144 egprs3->cps_lo = 1;
1145 egprs3->rsb = 0;
1146 egprs3->spb = 2;
1147 egprs3->pi = 0;
1148
1149 pdch->rcv_block(data_msg, 42, *fn, &meas);
1150
1151 block = ul_tbf->m_rlc.block(4);
1152 /* check the status of the block */
1153 OSMO_ASSERT(block->spb_status.block_status_ul ==
1154 EGPRS_RESEG_FIRST_SEG_RXD);
1155
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301156 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1157 egprs3->si = 1;
1158 egprs3->r = 1;
1159 egprs3->cv = 7;
1160 egprs3->tfi_hi = tfi & 0x03;
1161 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1162 egprs3->bsn1_hi = 4;
1163 egprs3->bsn1_lo = 0;
1164 egprs3->cps_hi = 1;
1165 data_msg[3] = 0xff;
1166 egprs3->pi = 0;
1167 egprs3->cps_lo = 1;
1168 egprs3->rsb = 0;
1169 egprs3->spb = 3;
1170 egprs3->pi = 0;
1171
1172 pdch->rcv_block(data_msg, 42, *fn, &meas);
1173
1174 block = ul_tbf->m_rlc.block(4);
1175 /* check the status of the block */
1176 OSMO_ASSERT(block->spb_status.block_status_ul ==
1177 EGPRS_RESEG_DEFAULT);
1178 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001179 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301180 /* Assembled MCS is MCS6. so the size is 74 */
1181 OSMO_ASSERT(block->len == 74);
1182
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301183 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1184 egprs3->si = 1;
1185 egprs3->r = 1;
1186 egprs3->cv = 7;
1187 egprs3->tfi_hi = tfi & 0x03;
1188 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1189 egprs3->bsn1_hi = 5;
1190 egprs3->bsn1_lo = 0;
1191 egprs3->cps_hi = 1;
1192 data_msg[3] = 0xff;
1193 egprs3->pi = 0;
1194 egprs3->cps_lo = 1;
1195 egprs3->rsb = 0;
1196 egprs3->spb = 3;
1197 egprs3->pi = 0;
1198
1199 pdch->rcv_block(data_msg, 42, *fn, &meas);
1200
1201 block = ul_tbf->m_rlc.block(5);
1202 /* check the status of the block */
1203 OSMO_ASSERT(block->spb_status.block_status_ul ==
1204 EGPRS_RESEG_SECOND_SEG_RXD);
1205
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301206 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1207 egprs3->si = 1;
1208 egprs3->r = 1;
1209 egprs3->cv = 7;
1210 egprs3->tfi_hi = tfi & 0x03;
1211 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1212 egprs3->bsn1_hi = 5;
1213 egprs3->bsn1_lo = 0;
1214 egprs3->cps_hi = 1;
1215 data_msg[3] = 0xff;
1216 egprs3->pi = 0;
1217 egprs3->cps_lo = 1;
1218 egprs3->rsb = 0;
1219 egprs3->spb = 2;
1220 egprs3->pi = 0;
1221
1222 pdch->rcv_block(data_msg, 42, *fn, &meas);
1223
1224 block = ul_tbf->m_rlc.block(5);
1225
1226 /* check the status of the block */
1227 OSMO_ASSERT(block->spb_status.block_status_ul ==
1228 EGPRS_RESEG_DEFAULT);
1229 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001230 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301231 /* Assembled MCS is MCS6. so the size is 74 */
1232 OSMO_ASSERT(block->len == 74);
1233
1234 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1235 ul_tbf->m_rlc.block(4)->len);
1236 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1237 ul_tbf->m_rlc.block(3)->len);
1238
1239 /* Compare the spb status of each BSNs(3,4,5). should be same */
1240 OSMO_ASSERT(
1241 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1242 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1243 OSMO_ASSERT(
1244 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1245 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1246
1247 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1248 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1249 ul_tbf->m_rlc.block(4)->cs_last);
1250 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1251 ul_tbf->m_rlc.block(3)->cs_last);
1252
1253 /* Compare the data of each BSNs(3,4,5). should be same */
1254 OSMO_ASSERT(
1255 !memcmp(ul_tbf->m_rlc.block(5)->block,
1256 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1257 ));
1258 OSMO_ASSERT(
1259 !memcmp(ul_tbf->m_rlc.block(5)->block,
1260 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1261 ));
1262
1263 return ul_tbf;
1264}
1265
sivasankari1d8744c2017-01-24 15:53:35 +05301266static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,
1267 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1268 uint8_t ms_class, uint8_t egprs_ms_class)
1269{
sivasankari1d8744c2017-01-24 15:53:35 +05301270 uint32_t rach_fn = *fn - 51;
1271 uint32_t sba_fn = *fn + 52;
1272 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001273 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301274 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301275 gprs_rlcmac_bts *bts;
1276 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301277
sivasankari1d8744c2017-01-24 15:53:35 +05301278 bts = the_bts->bts_data();
1279
1280 /* needed to set last_rts_fn in the PDCH object */
1281 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1282
1283 /*
1284 * simulate RACH, this sends an Immediate
1285 * Assignment Uplink on the AGCH
1286 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +07001287 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301288
1289 /* get next free TFI */
1290 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
1291
1292 /* fake a resource request */
1293 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1294 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1295 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1296 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001297 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1298 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301299 Count_MS_RA_capability_value = 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.
1302 Exist_Multislot_capability = 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 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001306 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301307 MS_RA_capability_value[0].u.Content.Multislot_capability.
1308 GPRS_multislot_class = ms_class;
1309 if (egprs_ms_class) {
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.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001313 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301314 MS_RA_capability_value[0].u.Content.
1315 Multislot_capability.EGPRS_multislot_class = ms_class;
1316 }
1317 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
1318
1319 /* check the TBF */
1320 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1321 /* send packet uplink assignment */
1322 *fn = sba_fn;
1323 request_dl_rlc_block(ul_tbf, fn);
1324
1325 /* send real acknowledgement */
1326 send_control_ack(ul_tbf);
1327
1328 check_tbf(ul_tbf);
1329
1330 return ul_tbf;
1331}
1332
1333static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *the_bts,
1334 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1335 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1336{
1337 OSMO_ASSERT(ul_tbf);
1338 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1339 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301340 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001341 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301342 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301343
1344 /* send fake data with cv=0*/
1345 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1346 uint8_t data[49] = {0};
1347
1348 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1349
1350 /*header_construction */
1351 memset(data, 0x2b, sizeof(data));
1352 /* Message with CRBB */
1353 for (int i = 0 ; i < 80; i++) {
1354 hdr3->r = 0;
1355 hdr3->si = 0;
1356 hdr3->cv = 10;
1357 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1358 hdr3->tfi_lo = tfi & 0x7;
1359 hdr3->bsn1_hi = ((i * 2)&0x1f);
1360 hdr3->bsn1_lo = ((i * 2)/32);
1361 hdr3->cps_hi = 0;
1362 hdr3->cps_lo = 0;
1363 hdr3->spb = 0;
1364 hdr3->rsb = 0;
1365 hdr3->pi = 0;
1366 hdr3->spare = 0;
1367 hdr3->dummy = 1;
1368 data[4] = 0x0;
1369 data[5] = 0x0;
1370 data[6] = 0x2b;
1371 data[7] = 0x2b;
1372 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1373 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1374 }
1375 ul_tbf->create_ul_ack(*fn, ts_no);
1376 memset(data, 0x2b, sizeof(data));
1377 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1378 hdr3->r = 0;
1379 hdr3->si = 0;
1380 hdr3->cv = 0;
1381 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1382 hdr3->tfi_lo = tfi & 0x7;
1383 hdr3->bsn1_hi = 0;
1384 hdr3->bsn1_lo = 2;
1385 hdr3->cps_hi = 0;
1386 hdr3->cps_lo = 0;
1387 hdr3->spb = 0;
1388 hdr3->rsb = 0;
1389 hdr3->pi = 0;
1390 hdr3->spare = 0;
1391 hdr3->dummy = 1;
1392 data[4] = 0x0;
1393 data[5] = 0x2b;
1394 data[6] = 0x2b;
1395 data[7] = 0x2b;
1396
1397 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1398 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1399
1400 request_dl_rlc_block(ul_tbf, fn);
1401
1402 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001403 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301404
1405 ms = the_bts->ms_by_tlli(tlli);
1406 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001407 OSMO_ASSERT(ms_ta(ms) == qta/4);
1408 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301409
1410 return ul_tbf;
1411}
1412
1413static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS *the_bts,
1414 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1415 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1416{
1417 OSMO_ASSERT(ul_tbf);
1418 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1419 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301420 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001421 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301422 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301423
1424 check_tbf(ul_tbf);
1425 /* send fake data with cv=0*/
1426 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1427 uint8_t data[49] = {0};
1428
1429 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1430
1431 /*header_construction */
1432 memset(data, 0x2b, sizeof(data));
1433
1434 /* Message with URBB & URBB length */
1435 for (int i = 0 ; i < 20; i++) {
1436 hdr3->r = 0;
1437 hdr3->si = 0;
1438 hdr3->cv = 10;
1439 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1440 hdr3->tfi_lo = tfi & 0x7;
1441 hdr3->bsn1_hi = ((i * 2)&0x1f);
1442 hdr3->bsn1_lo = ((i * 2)/32);
1443 hdr3->cps_hi = 0;
1444 hdr3->cps_lo = 0;
1445 hdr3->spb = 0;
1446 hdr3->rsb = 0;
1447 hdr3->pi = 0;
1448 hdr3->spare = 0;
1449 hdr3->dummy = 1;
1450 data[4] = 0x0;
1451 data[5] = 0x0;
1452 data[6] = 0x2b;
1453 data[7] = 0x2b;
1454 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1455 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1456 }
1457 ul_tbf->create_ul_ack(*fn, ts_no);
1458 memset(data, 0x2b, sizeof(data));
1459 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1460 hdr3->r = 0;
1461 hdr3->si = 0;
1462 hdr3->cv = 0;
1463 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1464 hdr3->tfi_lo = tfi & 0x7;
1465 hdr3->bsn1_hi = 0;
1466 hdr3->bsn1_lo = 2;
1467 hdr3->cps_hi = 0;
1468 hdr3->cps_lo = 0;
1469 hdr3->spb = 0;
1470 hdr3->rsb = 0;
1471 hdr3->pi = 0;
1472 hdr3->spare = 0;
1473 hdr3->dummy = 1;
1474 data[4] = 0x0;
1475 data[5] = 0x2b;
1476 data[6] = 0x2b;
1477 data[7] = 0x2b;
1478
1479 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1480 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +02001481 ul_tbf->create_ul_ack(*fn, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301482
1483 request_dl_rlc_block(ul_tbf, fn);
1484
1485 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001486 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301487
1488 ms = the_bts->ms_by_tlli(tlli);
1489 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001490 OSMO_ASSERT(ms_ta(ms) == qta/4);
1491 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301492
1493 return ul_tbf;
1494}
1495
1496static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,
1497 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1498 uint8_t ms_class, uint8_t egprs_ms_class)
1499{
1500 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301501 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001502 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301503 gprs_rlcmac_ul_tbf *ul_tbf;
1504 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301505
1506 /* check the TBF */
1507 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
1508 OSMO_ASSERT(ul_tbf);
1509 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1510
1511 /* send fake data with cv=0*/
1512 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1513 uint8_t data[49] = {0};
1514
1515 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1516
1517 /*header_construction */
1518 memset(data, 0x2b, sizeof(data));
1519
1520 /* Message with CRBB */
1521 for (int i = 80 ; i < 160; i++) {
1522 hdr3->r = 0;
1523 hdr3->si = 0;
1524 hdr3->cv = 10;
1525 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1526 hdr3->tfi_lo = tfi & 0x7;
1527 hdr3->bsn1_hi = ((i)&0x1f);
1528 hdr3->bsn1_lo = ((i)/32);
1529 hdr3->cps_hi = 0;
1530 hdr3->cps_lo = 0;
1531 hdr3->spb = 0;
1532 hdr3->rsb = 0;
1533 hdr3->pi = 0;
1534 hdr3->spare = 0;
1535 hdr3->dummy = 1;
1536 data[4] = 0x0;
1537 data[5] = 0x0;
1538 data[6] = 0x2b;
1539 data[7] = 0x2b;
1540 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1541 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1542 }
1543 ul_tbf->create_ul_ack(*fn, ts_no);
1544 memset(data, 0x2b, sizeof(data));
1545 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1546 hdr3->r = 0;
1547 hdr3->si = 0;
1548 hdr3->cv = 0;
1549 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1550 hdr3->tfi_lo = tfi & 0x7;
1551 hdr3->bsn1_hi = 0;
1552 hdr3->bsn1_lo = 2;
1553 hdr3->cps_hi = 0;
1554 hdr3->cps_lo = 0;
1555 hdr3->spb = 0;
1556 hdr3->rsb = 0;
1557 hdr3->pi = 0;
1558 hdr3->spare = 0;
1559 hdr3->dummy = 1;
1560 data[4] = 0x0;
1561 data[5] = 0x2b;
1562 data[6] = 0x2b;
1563 data[7] = 0x2b;
1564
1565 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
1566 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1567
1568 request_dl_rlc_block(ul_tbf, fn);
1569
1570 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001571 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301572
1573 ms = the_bts->ms_by_tlli(tlli);
1574 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001575 OSMO_ASSERT(ms_ta(ms) == qta/4);
1576 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301577
1578 return ul_tbf;
1579}
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001580static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts,
1581 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001582 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001583{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001584 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001585 uint32_t rach_fn = *fn - 51;
1586 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001587 uint8_t trx_no = 0;
1588 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001589 gprs_rlcmac_ul_tbf *ul_tbf;
1590 struct gprs_rlcmac_pdch *pdch;
1591 gprs_rlcmac_bts *bts;
1592 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001593
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001594 bts = the_bts->bts_data();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001595
1596 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001597 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001598
bhargava959d1de2016-08-17 15:17:21 +05301599 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +07001600 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001601
1602 /* get next free TFI */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001603 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001604
1605 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001606 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1607 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1608 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1609 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001610 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1611 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001612 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001613 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001614 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 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 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001618 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001619 MS_RA_capability_value[0].u.Content.Multislot_capability.
1620 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001621 if (egprs_ms_class) {
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 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001625 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001626 MS_RA_capability_value[0].u.Content.Multislot_capability.
1627 EGPRS_multislot_class = ms_class;
1628 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001629
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001630 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001631
1632 /* check the TBF */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001633 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001634 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001635 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001636
1637 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001638 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001639 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001640
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001641 /* send real acknowledgement */
1642 send_control_ack(ul_tbf);
1643
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001644 check_tbf(ul_tbf);
1645
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001646 /* send fake data */
1647 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001648 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1649 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001650 uint8_t(1), /* BSN:7, E:1 */
1651 };
1652
Jacob Erlbeck56f99d12015-08-20 15:55:56 +02001653 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001654 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001655
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001656 ms = the_bts->ms_by_tlli(tlli);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001657 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001658 OSMO_ASSERT(ms_ta(ms) == qta/4);
1659 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001660
1661 return ul_tbf;
1662}
1663
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001664static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi,
1665 const uint8_t *data, unsigned data_size)
1666{
1667 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001668
1669 ms = the_bts->ms_store().get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001670
Jacob Erlbeck14e00f82015-11-27 18:10:39 +01001671 gprs_rlcmac_dl_tbf::handle(the_bts->bts_data(), tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001672 1000, data, data_size);
1673
1674 ms = the_bts->ms_by_imsi(imsi);
1675 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001676 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001677
1678 if (imsi[0] && strcmp(imsi, "000") != 0) {
1679 ms2 = the_bts->ms_by_tlli(tlli);
1680 OSMO_ASSERT(ms == ms2);
1681 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001682}
1683
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001684static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn,
1685 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001686{
1687 gprs_rlcmac_dl_tbf *dl_tbf;
1688 GprsMs *ms;
1689 unsigned ts_no;
1690
1691 ms = the_bts->ms_by_tlli(tlli);
1692 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001693 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001694 OSMO_ASSERT(dl_tbf);
1695
1696 while (dl_tbf->have_data()) {
1697 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001698 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1699 if (!(slots & (1 << ts_no)))
1700 continue;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001701 gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
Max878bd1f2016-07-20 13:05:05 +02001702 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001703 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001704 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001705 *fn = fn_add_blocks(*fn, 1);
1706 }
1707}
1708
Max4c112dc2018-02-01 16:49:23 +01001709static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1710{
1711 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1712 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001713 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 +01001714}
1715
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001716static void test_tbf_single_phase()
1717{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001718 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001719 the_pcu->bts = bts_alloc(the_pcu);
1720 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001721 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001722 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001723 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001724 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001725 uint16_t qta = 31;
1726 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001727
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001728 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001729
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001730 setup_bts(the_bts, ts_no);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001731
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001732 ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001733
Max4c112dc2018-02-01 16:49:23 +01001734 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001735 send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001736
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001737 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001738 TALLOC_FREE(the_pcu);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001739}
1740
sivasankari1d8744c2017-01-24 15:53:35 +05301741static void test_tbf_egprs_two_phase_puan(void)
1742{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001743 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001744 the_pcu->bts = bts_alloc(the_pcu);
1745 BTS *the_bts = the_pcu->bts;
sivasankari1d8744c2017-01-24 15:53:35 +05301746 int ts_no = 7;
1747 uint32_t fn = 2654218;
1748 uint16_t qta = 31;
1749 uint32_t tlli = 0xf1223344;
1750 const char *imsi = "0011223344";
1751 uint8_t ms_class = 1;
sivasankari1d8744c2017-01-24 15:53:35 +05301752 uint8_t egprs_ms_class = 1;
1753 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301754 uint8_t test_data[256];
1755
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001756 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301757
1758 memset(test_data, 1, sizeof(test_data));
1759
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001760 setup_bts(the_bts, ts_no, 4);
1761 the_bts->bts_data()->initial_mcs_dl = 9;
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001762 the_pcu->vty.ws_base = 128;
1763 the_pcu->vty.ws_pdch = 64;
sivasankari1d8744c2017-01-24 15:53:35 +05301764
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001765 ul_tbf = establish_ul_tbf(the_bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301766 /* Function to generate URBB with no length */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001767 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(the_bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301768 qta, ms_class, egprs_ms_class, ul_tbf);
1769
Max4c112dc2018-02-01 16:49:23 +01001770 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001771 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301772
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001773 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301774 /* Function to generate URBB with length */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001775 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(the_bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301776 qta, ms_class, egprs_ms_class, ul_tbf);
1777
Max4c112dc2018-02-01 16:49:23 +01001778 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001779 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301780
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001781 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301782 /* Function to generate CRBB */
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001783 the_pcu->vty.ws_base = 128;
1784 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001785 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(the_bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301786 qta, ms_class, egprs_ms_class);
1787
Max4c112dc2018-02-01 16:49:23 +01001788 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001789 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301790
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001791 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001792 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301793}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301794/*
1795 * Trigger rach for single block
1796 */
1797static void test_immediate_assign_rej_single_block()
1798{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001799 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001800 the_pcu->bts = bts_alloc(the_pcu);
1801 BTS *the_bts = the_pcu->bts;
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301802 uint32_t fn = 2654218;
1803 uint16_t qta = 31;
1804 int ts_no = 7;
1805
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001806 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301807
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001808 setup_bts(the_bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301809
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001810 the_bts->bts_data()->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301811
1812 uint32_t rach_fn = fn - 51;
1813
1814 int rc = 0;
1815
1816 /*
1817 * simulate RACH, sends an Immediate Assignment
1818 * Uplink reject on the AGCH
1819 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001820 rc = bts_handle_rach(the_bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301821
1822 OSMO_ASSERT(rc == -EINVAL);
1823
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001824 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001825 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301826}
1827
1828/*
1829 * Trigger rach till resources(USF) exhaust
1830 */
1831static void test_immediate_assign_rej_multi_block()
1832{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001833 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001834 the_pcu->bts = bts_alloc(the_pcu);
1835 BTS *the_bts = the_pcu->bts;
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301836 uint32_t fn = 2654218;
1837 uint16_t qta = 31;
1838 int ts_no = 7;
1839
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001840 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301841
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001842 setup_bts(the_bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301843
1844 uint32_t rach_fn = fn - 51;
1845
1846 int rc = 0;
1847
1848 /*
1849 * simulate RACH, sends an Immediate Assignment Uplink
1850 * reject on the AGCH
1851 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001852 rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);
1853 rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);
1854 rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);
1855 rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);
1856 rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);
1857 rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);
1858 rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);
1859 rc = bts_handle_rach(the_bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301860
1861 OSMO_ASSERT(rc == -EBUSY);
1862
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001863 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001864 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301865}
1866
1867static void test_immediate_assign_rej()
1868{
1869 test_immediate_assign_rej_multi_block();
1870 test_immediate_assign_rej_single_block();
1871}
1872
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001873static void test_tbf_two_phase()
1874{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001875 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001876 the_pcu->bts = bts_alloc(the_pcu);
1877 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001878 int ts_no = 7;
1879 uint32_t fn = 2654218;
1880 uint16_t qta = 31;
1881 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001882 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001883 uint8_t ms_class = 1;
1884 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001885
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001886 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001887
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001888 setup_bts(the_bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001889
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001890 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001891 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001892
Max4c112dc2018-02-01 16:49:23 +01001893 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001894 send_dl_data(the_bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001895
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001896 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001897 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001898}
1899
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001900static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001901{
1902 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001903 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 +01001904}
1905
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001906static void test_tbf_ra_update_rach()
1907{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001908 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001909 the_pcu->bts = bts_alloc(the_pcu);
1910 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001911 int ts_no = 7;
1912 uint32_t fn = 2654218;
1913 uint16_t qta = 31;
1914 uint32_t tlli1 = 0xf1223344;
1915 uint32_t tlli2 = 0xf5667788;
1916 const char *imsi = "0011223344";
1917 uint8_t ms_class = 1;
1918 gprs_rlcmac_ul_tbf *ul_tbf;
1919 GprsMs *ms, *ms1, *ms2;
1920
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001921 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001922
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001923 setup_bts(the_bts, ts_no, 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001924
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001925 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001926 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001927
1928 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001929 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001930
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001931 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001932 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001933
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001934 /* Send Packet Downlink Assignment to MS */
1935 request_dl_rlc_block(ul_tbf, &fn);
1936
1937 /* Ack it */
1938 send_control_ack(ul_tbf);
1939
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001940 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001941 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001942 transmit_dl_data(the_bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001943 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001944
1945 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001946 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001947 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001948
1949 ms2 = ul_tbf->ms();
1950
1951 /* The PCU cannot know yet, that both TBF belong to the same MS */
1952 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01001953 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001954
1955 /* Send some downlink data along with the new TLLI and the IMSI so that
1956 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001957 send_dl_data(the_bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001958
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001959 ms = the_bts->ms_by_imsi(imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001960 OSMO_ASSERT(ms == ms2);
1961
Max4c112dc2018-02-01 16:49:23 +01001962 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001963
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001964 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001965 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001966 ms = the_bts->ms_by_tlli(tlli2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001967 OSMO_ASSERT(ms == ms2);
1968
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001969 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001970 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001971}
1972
1973static void test_tbf_dl_flow_and_rach_two_phase()
1974{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001975 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001976 the_pcu->bts = bts_alloc(the_pcu);
1977 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001978 int ts_no = 7;
1979 uint32_t fn = 2654218;
1980 uint16_t qta = 31;
1981 uint32_t tlli1 = 0xf1223344;
1982 const char *imsi = "0011223344";
1983 uint8_t ms_class = 1;
1984 gprs_rlcmac_ul_tbf *ul_tbf;
1985 gprs_rlcmac_dl_tbf *dl_tbf;
1986 GprsMs *ms, *ms1, *ms2;
1987
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001988 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001989
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001990 setup_bts(the_bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001991
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001992 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001993 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001994
1995 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001996 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001997
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001998 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1999 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002000 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002001
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002002 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2003 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002004 OSMO_ASSERT(dl_tbf != NULL);
2005
2006 /* Get rid of old UL TBF */
2007 tbf_free(ul_tbf);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002008 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002009 OSMO_ASSERT(ms1 == ms);
2010
2011 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002012 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002013 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002014
2015 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002016 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002017
2018 /* This should be the same MS object */
2019 OSMO_ASSERT(ms2 == ms1);
2020
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002021 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002022 OSMO_ASSERT(ms2 == ms);
2023
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002024 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002025 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002026
2027 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002028 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002029
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002030 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002031 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002032}
2033
2034
2035static void test_tbf_dl_flow_and_rach_single_phase()
2036{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002037 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002038 the_pcu->bts = bts_alloc(the_pcu);
2039 BTS *the_bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002040 int ts_no = 7;
2041 uint32_t fn = 2654218;
2042 uint16_t qta = 31;
2043 uint32_t tlli1 = 0xf1223344;
2044 const char *imsi = "0011223344";
2045 uint8_t ms_class = 1;
2046 gprs_rlcmac_ul_tbf *ul_tbf;
2047 gprs_rlcmac_dl_tbf *dl_tbf;
2048 GprsMs *ms, *ms1, *ms2;
2049
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002050 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002051
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002052 setup_bts(the_bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002053
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002054 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002055 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002056
2057 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002058 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002059
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002060 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2061 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002062 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002063
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002064 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2065 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002066 OSMO_ASSERT(dl_tbf != NULL);
2067
2068 /* Get rid of old UL TBF */
2069 tbf_free(ul_tbf);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002070 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002071 OSMO_ASSERT(ms1 == ms);
2072
2073 /* Now establish a new UL TBF */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002074 ul_tbf = establish_ul_tbf_single_phase(the_bts, ts_no, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002075
2076 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002077 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002078
2079 /* There should be a different MS object */
2080 OSMO_ASSERT(ms2 != ms1);
2081
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002082 ms = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002083 OSMO_ASSERT(ms2 == ms);
2084 OSMO_ASSERT(ms1 != ms);
2085
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002086 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002087 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002088
2089 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002090 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002091
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002092 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002093 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002094}
2095
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002096static void test_tbf_dl_reuse()
2097{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002098 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002099 the_pcu->bts = bts_alloc(the_pcu);
2100 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002101 int ts_no = 7;
2102 uint32_t fn = 2654218;
2103 uint16_t qta = 31;
2104 uint32_t tlli1 = 0xf1223344;
2105 const char *imsi = "0011223344";
2106 uint8_t ms_class = 1;
2107 gprs_rlcmac_ul_tbf *ul_tbf;
2108 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2109 GprsMs *ms1, *ms2;
2110 unsigned i;
2111 RlcMacUplink_t ulreq = {0};
2112
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002113 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002114
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002115 setup_bts(the_bts, ts_no, 1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002116
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002117 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002118 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002119
2120 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002121 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002122
2123 /* Send some LLC frames */
2124 for (i = 0; i < 40; i++) {
2125 char buf[32];
2126 int rc;
2127
2128 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2129 OSMO_ASSERT(rc > 0);
2130
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002131 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002132 }
2133
Max4c112dc2018-02-01 16:49:23 +01002134 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002135
2136 /* Send Packet Downlink Assignment to MS */
2137 request_dl_rlc_block(ul_tbf, &fn);
2138
2139 /* Ack it */
2140 send_control_ack(ul_tbf);
2141
2142 /* Transmit all data */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002143 transmit_dl_data(the_bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002144 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2145 OSMO_ASSERT(ms_dl_tbf(ms1));
2146 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002147
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002148 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002149
2150 /* Send some LLC frames */
2151 for (i = 0; i < 10; i++) {
2152 char buf[32];
2153 int rc;
2154
2155 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2156 OSMO_ASSERT(rc > 0);
2157
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002158 send_dl_data(the_bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002159 }
2160
2161 /* Fake Final DL Ack/Nack */
2162 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2163 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2164
2165 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2166 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2167 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2168
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002169 send_ul_mac_block(the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002170
2171 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2172
2173 request_dl_rlc_block(dl_tbf1, &fn);
2174
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002175 ms2 = the_bts->ms_by_tlli(tlli1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002176 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002177 OSMO_ASSERT(ms_dl_tbf(ms2));
2178 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002179
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002180 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002181
2182 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2183
2184 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02002185 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002186
2187 /* Transmit all data */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002188 transmit_dl_data(the_bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002189 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2190 OSMO_ASSERT(ms_dl_tbf(ms2));
2191 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002192
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002193 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002194 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002195}
2196
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002197static void test_tbf_gprs_egprs()
2198{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002199 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002200 the_pcu->bts = bts_alloc(the_pcu);
2201 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002202 gprs_rlcmac_bts *bts;
2203 uint8_t ts_no = 4;
2204 uint8_t ms_class = 45;
2205 int rc = 0;
2206 uint32_t tlli = 0xc0006789;
2207 const char *imsi = "001001123456789";
2208 unsigned delay_csec = 1000;
2209
2210 uint8_t buf[256] = {0};
2211
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002212 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002213
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002214 bts = the_bts->bts_data();
2215 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2216 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002217 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2218 abort();
2219 }
2220
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002221 setup_bts(the_bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002222
2223 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002224
Alexander Couzens290d9032020-09-16 21:52:02 +02002225 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002226
2227 /* Does not support EGPRS */
2228 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
2229 delay_csec, buf, sizeof(buf));
2230
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002231 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002232 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002233
Alexander Couzens290d9032020-09-16 21:52:02 +02002234 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002235 TALLOC_FREE(the_pcu);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002236}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002237
Max4c112dc2018-02-01 16:49:23 +01002238static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
2239 bool free, bool end)
2240{
Alexander Couzens290d9032020-09-16 21:52:02 +02002241 gprs_rlcmac_bts *bts = dl_tbf->bts->bts_data();
Max4c112dc2018-02-01 16:49:23 +01002242 if (!dl_tbf) {
2243 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2244 return;
2245 }
2246
2247 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2248 dl_tbf->dl_slots(),
2249 pcu_bitcount(dl_tbf->dl_slots()),
2250 dl_tbf->window_size());
2251
2252 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2253 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2254 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2255
2256 fprintf(stderr, "\n");
2257
2258 if (free)
2259 tbf_free(dl_tbf);
2260
2261 if (end) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002262 fprintf(stderr, "=== end %s ===\n", test);
Alexander Couzens290d9032020-09-16 21:52:02 +02002263 gprs_bssgp_destroy(bts);
Max4c112dc2018-02-01 16:49:23 +01002264 }
2265}
2266
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002267static void test_tbf_ws()
2268{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002269 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002270 the_pcu->bts = bts_alloc(the_pcu);
2271 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002272 gprs_rlcmac_bts *bts;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002273 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002274 uint8_t ts_no = 4;
2275 uint8_t ms_class = 12;
2276 gprs_rlcmac_dl_tbf *dl_tbf;
2277
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002278 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002279
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002280 bts = the_bts->bts_data();
2281 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2282 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002283 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2284 abort();
2285 }
2286
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002287 setup_bts(the_bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002288
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002289 the_pcu->vty.ws_base = 128;
2290 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002291 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002292 bts->trx[0].pdch[2].enable();
2293 bts->trx[0].pdch[3].enable();
2294 bts->trx[0].pdch[4].enable();
2295 bts->trx[0].pdch[5].enable();
2296
Alexander Couzens290d9032020-09-16 21:52:02 +02002297 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002298
2299 /* Does no support EGPRS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002300 ms = the_bts->ms_alloc(ms_class, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002301 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002302
2303 ws_check(dl_tbf, __func__, 4, 64, true, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002304
2305 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002306
2307 /* Does support EGPRS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002308 ms = the_bts->ms_alloc(ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002309 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002310
Max4c112dc2018-02-01 16:49:23 +01002311 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002312 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002313}
2314
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302315static void test_tbf_update_ws(void)
2316{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002317 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002318 the_pcu->bts = bts_alloc(the_pcu);
2319 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302320 gprs_rlcmac_bts *bts;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002321 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302322 uint8_t ts_no = 4;
2323 uint8_t ms_class = 11;
2324 gprs_rlcmac_dl_tbf *dl_tbf;
2325
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002326 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302327
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002328 bts = the_bts->bts_data();
2329 the_bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2330 if (!the_bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002331 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2332 abort();
2333 }
2334
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002335 setup_bts(the_bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302336
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002337 the_pcu->vty.ws_base = 128;
2338 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002339 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302340 bts->trx[0].pdch[2].enable();
2341 bts->trx[0].pdch[3].enable();
2342 bts->trx[0].pdch[4].enable();
2343 bts->trx[0].pdch[5].enable();
2344
Alexander Couzens290d9032020-09-16 21:52:02 +02002345 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302346
2347 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302348
2349 /* Does support EGPRS */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002350 ms = the_bts->ms_alloc(ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002351 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302352
Max4c112dc2018-02-01 16:49:23 +01002353 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302354
2355 dl_tbf->update();
2356
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302357 /* window size should be 384 */
Max4c112dc2018-02-01 16:49:23 +01002358 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002359 TALLOC_FREE(the_pcu);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302360}
2361
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302362static void test_tbf_puan_urbb_len(void)
2363{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002364 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002365 the_pcu->bts = bts_alloc(the_pcu);
2366 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302367 int ts_no = 7;
2368 uint32_t fn = 2654218;
2369 uint16_t qta = 31;
2370 uint32_t tlli = 0xf1223344;
2371 const char *imsi = "0011223344";
2372 uint8_t ms_class = 1;
2373 uint8_t egprs_ms_class = 1;
2374 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302375 uint8_t test_data[256];
2376
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002377 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302378
2379 memset(test_data, 1, sizeof(test_data));
2380
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002381 setup_bts(the_bts, ts_no, 4);
2382 the_bts->bts_data()->initial_mcs_dl = 9;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302383
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002384 ul_tbf = puan_urbb_len_issue(the_bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302385 ms_class, egprs_ms_class);
2386
Max4c112dc2018-02-01 16:49:23 +01002387 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002388 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302389
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002390 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002391 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302392}
2393
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302394static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
2395 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2396 uint8_t ms_class, uint8_t egprs_ms_class)
2397{
2398 GprsMs *ms;
2399 uint32_t rach_fn = *fn - 51;
2400 uint32_t sba_fn = *fn + 52;
2401 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002402 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302403 gprs_rlcmac_ul_tbf *ul_tbf;
2404 struct gprs_rlcmac_pdch *pdch;
2405 gprs_rlcmac_bts *bts;
2406 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302407 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302408 Packet_Resource_Request_t *presreq = NULL;
2409 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2410 Multislot_capability_t *pmultislotcap = NULL;
2411
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302412 bts = the_bts->bts_data();
2413
2414 /* needed to set last_rts_fn in the PDCH object */
2415 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2416
2417 /*
2418 * simulate RACH, this sends an Immediate
2419 * Assignment Uplink on the AGCH
2420 */
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +07002421 bts_handle_rach(the_bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302422
2423 /* get next free TFI */
2424 tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
2425
2426 /* fake a resource request */
2427 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2428 presreq = &ulreq.u.Packet_Resource_Request;
2429 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2430 presreq->ID.UnionType = 1; /* != 0 */
2431 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002432 presreq->Exist_MS_Radio_Access_capability2 = 1;
2433 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302434 pmsradiocap->Count_MS_RA_capability_value = 1;
2435 pmsradiocap->MS_RA_capability_value[0].u.Content.
2436 Exist_Multislot_capability = 1;
2437 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2438 u.Content.Multislot_capability;
2439
2440 pmultislotcap->Exist_GPRS_multislot_class = 1;
2441 pmultislotcap->GPRS_multislot_class = ms_class;
2442 if (egprs_ms_class) {
2443 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2444 pmultislotcap->EGPRS_multislot_class = ms_class;
2445 }
2446
2447 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
2448
2449 /* check the TBF */
2450 ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
2451 OSMO_ASSERT(ul_tbf);
2452 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2453
2454 /* send packet uplink assignment */
2455 *fn = sba_fn;
2456 request_dl_rlc_block(ul_tbf, fn);
2457
2458 /* send real acknowledgement */
2459 send_control_ack(ul_tbf);
2460
2461 check_tbf(ul_tbf);
2462
2463 uint8_t data_msg[49] = {0};
2464
2465 pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
2466
2467 ms = the_bts->ms_by_tlli(tlli);
2468 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002469 OSMO_ASSERT(ms_ta(ms) == qta/4);
2470 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302471
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302472 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2473 egprs3->si = 0;
2474 egprs3->r = 1;
2475 egprs3->cv = 7;
2476 egprs3->tfi_hi = tfi & 0x03;
2477 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2478 egprs3->bsn1_hi = 0;
2479 egprs3->bsn1_lo = 0;
2480 egprs3->cps_hi = 1;
2481 data_msg[3] = 0xff;
2482 egprs3->pi = 0;
2483 egprs3->cps_lo = 1;
2484 egprs3->rsb = 0;
2485 egprs3->spb = 0;
2486 egprs3->pi = 0;
2487 pdch->rcv_block(data_msg, 49, *fn, &meas);
2488
2489 egprs3->bsn1_hi = 1;
2490 egprs3->bsn1_lo = 0;
2491 data_msg[3] = 0x7f;
2492 egprs3->cps_lo = 1;
2493 egprs3->rsb = 0;
2494 egprs3->spb = 0;
2495 egprs3->pi = 0;
2496 data_msg[4] = 0x2;
2497 data_msg[5] = 0x0;
2498 pdch->rcv_block(data_msg, 49, *fn, &meas);
2499
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302500 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302501
2502 return ul_tbf;
2503}
2504
2505static void test_tbf_li_decoding(void)
2506{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002507 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002508 the_pcu->bts = bts_alloc(the_pcu);
2509 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302510 int ts_no = 7;
2511 uint32_t fn = 2654218;
2512 uint16_t qta = 31;
2513 uint32_t tlli = 0xf1223344;
2514 const char *imsi = "0011223344";
2515 uint8_t ms_class = 1;
2516 uint8_t egprs_ms_class = 1;
2517 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302518 uint8_t test_data[256];
2519
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002520 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302521
2522 memset(test_data, 1, sizeof(test_data));
2523
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002524 setup_bts(the_bts, ts_no, 4);
2525 the_bts->bts_data()->initial_mcs_dl = 9;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302526
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002527 ul_tbf = tbf_li_decoding(the_bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302528 ms_class, egprs_ms_class);
2529
Max4c112dc2018-02-01 16:49:23 +01002530 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002531 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302532
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002533 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002534 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302535}
2536
aravind sirsikarf2761382016-10-25 12:45:24 +05302537/*
2538 * Test that a bit within the uncompressed bitmap whose BSN is not within
2539 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2540 * version 7.27.0 Release 7.
2541 */
2542static void test_tbf_epdan_out_of_rx_window(void)
2543{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002544 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002545 the_pcu->bts = bts_alloc(the_pcu);
2546 BTS *the_bts = the_pcu->bts;
aravind sirsikarf2761382016-10-25 12:45:24 +05302547 uint8_t ms_class = 11;
2548 uint8_t egprs_ms_class = 11;
2549 uint8_t trx_no;
2550 uint32_t tlli = 0xffeeddcc;
2551 gprs_rlcmac_dl_tbf *dl_tbf;
2552 int ts_no = 4;
2553 bitvec *block;
2554 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2555 bitvec bits;
2556 int bsn_begin, bsn_end;
2557 EGPRS_PD_AckNack_t *ack_nack;
2558 RlcMacUplink_t ul_control_block;
2559 gprs_rlc_v_b *prlcmvb;
2560 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002561 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302562
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302563 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2564
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002565 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302566
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002567 setup_bts(the_bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002568 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302569 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002570 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302571
2572 /*
2573 * Simulate a message captured during over-the-air testing,
2574 * where the following values were observed:
2575 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2576 */
2577 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2578 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2579 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2581
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002582 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
aravind sirsikarf2761382016-10-25 12:45:24 +05302583 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002584 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302585 prlcmvb = &prlcdlwindow->m_v_b;
2586 prlcdlwindow->m_v_s = 1288;
2587 prlcdlwindow->m_v_a = 1176;
2588 prlcdlwindow->set_sns(2048);
2589 prlcdlwindow->set_ws(480);
2590 prlcmvb->mark_unacked(1176);
2591 prlcmvb->mark_unacked(1177);
2592 prlcmvb->mark_unacked(1286);
2593 prlcmvb->mark_unacked(1287);
2594
2595 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2596
Alexander Couzensccde5c92017-02-04 03:10:08 +01002597 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302598
2599 bitvec_unpack(block, data_msg);
2600
2601 bits.data = bits_data;
2602 bits.data_len = sizeof(bits_data);
2603 bits.cur_bit = 0;
2604
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002605 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2606 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302607
2608 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2609
2610 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2611 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2612 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2613 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2614
2615 Decoding::decode_egprs_acknack_bits(
2616 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002617 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302618
2619 dl_tbf->rcvd_dl_ack(
2620 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2621 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302622
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302623 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2624 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2625 OSMO_ASSERT(prlcmvb->is_acked(1286));
2626 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302627
2628 bitvec_free(block);
2629 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002630 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002631 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302632}
2633
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302634static void test_tbf_egprs_two_phase_spb(void)
2635{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002636 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002637 the_pcu->bts = bts_alloc(the_pcu);
2638 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302639 int ts_no = 7;
2640 uint32_t fn = 2654218;
2641 uint16_t qta = 31;
2642 uint32_t tlli = 0xf1223344;
2643 const char *imsi = "0011223344";
2644 uint8_t ms_class = 1;
2645 uint8_t egprs_ms_class = 1;
2646 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302647 uint8_t test_data[256];
2648
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002649 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302650
2651 memset(test_data, 1, sizeof(test_data));
2652
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002653 setup_bts(the_bts, ts_no, 4);
2654 the_bts->bts_data()->initial_mcs_dl = 9;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302655
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002656 ul_tbf = establish_ul_tbf_two_phase_spb(the_bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302657 ms_class, egprs_ms_class);
2658
Max4c112dc2018-02-01 16:49:23 +01002659 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002660 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302661
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002662 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002663 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302664}
2665
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002666static void test_tbf_egprs_two_phase()
2667{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002668 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002669 the_pcu->bts = bts_alloc(the_pcu);
2670 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002671 int ts_no = 7;
2672 uint32_t fn = 2654218;
2673 uint16_t qta = 31;
2674 uint32_t tlli = 0xf1223344;
2675 const char *imsi = "0011223344";
2676 uint8_t ms_class = 1;
2677 uint8_t egprs_ms_class = 1;
2678 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002679 uint8_t test_data[256];
2680
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002681 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002682
2683 memset(test_data, 1, sizeof(test_data));
2684
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002685 setup_bts(the_bts, ts_no, 4);
2686 the_bts->bts_data()->initial_mcs_dl = 9;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002687
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002688 ul_tbf = establish_ul_tbf_two_phase(the_bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002689 ms_class, egprs_ms_class);
2690
Max4c112dc2018-02-01 16:49:23 +01002691 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002692 send_dl_data(the_bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002693
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002694 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002695 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002696}
2697
2698static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
2699{
2700 unsigned i;
2701 uint8_t ms_class = 11;
2702 uint8_t egprs_ms_class = 11;
2703 uint32_t fn = 0;
2704 uint8_t trx_no;
2705 uint32_t tlli = 0xffeeddcc;
2706 uint8_t test_data[512];
2707
2708 uint8_t rbb[64/8];
2709
2710 gprs_rlcmac_dl_tbf *dl_tbf;
2711
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002712 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002713
2714 memset(test_data, 1, sizeof(test_data));
2715 the_bts->bts_data()->initial_mcs_dl = mcs;
2716
2717 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2718 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2719
2720 for (i = 0; i < sizeof(llc_data); i++)
2721 llc_data[i] = i%256;
2722
2723 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2724
2725 /* Schedule a small LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002726 dl_tbf->append_data(1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002727
2728 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2729
2730 /* Drain the queue */
2731 while (dl_tbf->have_data())
2732 /* Request to send one RLC/MAC block */
2733 request_dl_rlc_block(dl_tbf, &fn);
2734
2735 /* Schedule a large LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002736 dl_tbf->append_data(1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002737
2738 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2739
2740 /* Drain the queue */
2741 while (dl_tbf->have_data())
2742 /* Request to send one RLC/MAC block */
2743 request_dl_rlc_block(dl_tbf, &fn);
2744
2745 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2746
Max7d32f552017-12-15 11:25:14 +01002747 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002748
2749 /* Clean up and ensure tbfs are in the correct state */
2750 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002751 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002752 check_tbf(dl_tbf);
2753 tbf_free(dl_tbf);
2754}
2755
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302756static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
2757 int mcs)
2758{
2759 unsigned i;
2760 uint8_t ms_class = 11;
2761 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302762 uint8_t trx_no;
2763 uint32_t tlli = 0xffeeddcc;
2764 uint8_t test_data[512];
2765
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302766 gprs_rlcmac_dl_tbf *dl_tbf;
2767
2768 memset(test_data, 1, sizeof(test_data));
2769 the_bts->bts_data()->initial_mcs_dl = mcs;
2770
2771 dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
2772 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2773
2774 for (i = 0; i < sizeof(test_data); i++)
2775 test_data[i] = i%256;
2776
2777 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2778
2779 /* Schedule a LLC frame
2780 * passing only 100 bytes, since it is enough to construct
2781 * 2 RLC data blocks. Which are enough to test Header Type 1
2782 * cases
2783 */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002784 dl_tbf->append_data(1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302785
2786 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2787
2788 return dl_tbf;
2789
2790}
2791
2792static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2793{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302794 uint8_t rbb[64/8];
2795
Max7d32f552017-12-15 11:25:14 +01002796 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302797
2798 /* Clean up and ensure tbfs are in the correct state */
2799 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002800 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302801 check_tbf(dl_tbf);
2802 tbf_free(dl_tbf);
2803
2804}
2805
Max7d32f552017-12-15 11:25:14 +01002806#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002807 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2808 w->m_v_b.mark_nacked(x); \
2809 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002810 } while(0)
2811
2812#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002813 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2814 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002815 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002816 } while(0)
2817
2818#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002819 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2820 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002821 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002822 } while(0)
2823
2824#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
2825 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
2826 OSMO_ASSERT(m); \
2827 if (check_unacked) \
2828 CHECK_UNACKED(tbf, cs, 0); \
2829 else \
2830 CHECK_NACKED(tbf, cs, 0); \
2831 } while(0)
2832
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302833static void egprs_spb_to_normal_validation(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002834 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302835{
2836 uint32_t fn = 0;
2837 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302838 uint16_t bsn1, bsn2, bsn3;
2839 struct msgb *msg;
2840 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2841 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2842
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002843 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302844
2845 dl_tbf = tbf_init(the_bts, mcs);
2846
2847 /*
2848 * Table 10.4.8a.3.1 of 44.060.
2849 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2850 * (MCS5, MCS6) to (MCS2, MCS3) transition
2851 */
2852 if (!(mcs == 6 && demanded_mcs == 3))
2853 return;
2854
2855 fn = fn_add_blocks(fn, 1);
2856 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002857 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302858
2859 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01002860 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01002861
2862 NACK(dl_tbf, 0);
2863
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302864 OSMO_ASSERT(bsn1 == 0);
2865
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002866 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302867
2868 fn = fn_add_blocks(fn, 1);
2869
2870 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002871 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302872 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2873 == EGPRS_RESEG_FIRST_SEG_SENT);
2874
2875 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2876 OSMO_ASSERT(egprs3->spb == 2);
2877
2878 /* Table 10.4.8a.3.1 of 44.060 */
2879 OSMO_ASSERT(egprs3->cps == 3);
2880
2881 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002882 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302883 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2884 == EGPRS_RESEG_SECOND_SEG_SENT);
2885
2886 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2887 /* Table 10.4.8a.3.1 of 44.060 */
2888 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01002889 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302890 OSMO_ASSERT(bsn2 == bsn1);
2891
2892 /* Table 10.4.8a.3.1 of 44.060 */
2893 OSMO_ASSERT(egprs3->cps == 3);
2894
2895 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002896 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302897
Max7d32f552017-12-15 11:25:14 +01002898 NACK(dl_tbf, 0);
2899
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302900 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2901 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2902
2903 /* Table 10.4.8a.3.1 of 44.060 */
2904 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01002905 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302906 OSMO_ASSERT(bsn3 == bsn2);
2907
2908 tbf_cleanup(dl_tbf);
2909}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002910
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302911static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002912 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302913{
2914 uint32_t fn = 0;
2915 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302916 struct msgb *msg;
2917 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2918
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002919 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302920
2921 dl_tbf = tbf_init(the_bts, mcs);
2922
2923 /*
2924 * Table 10.4.8a.3.1 of 44.060.
2925 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2926 * (MCS5, MCS6) to (MCS2, MCS3) transition
2927 */
2928 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2929 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2930 * dated 2016-02-07 23:45:40 (UTC)
2931 */
2932 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2933 ((mcs == 6) && (demanded_mcs == 3)) ||
2934 ((mcs == 4) && (demanded_mcs == 1))))
2935 return;
2936
2937 fn = fn_add_blocks(fn, 1);
2938 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002939 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302940
Max7d32f552017-12-15 11:25:14 +01002941 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302942
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002943 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302944
2945 fn = fn_add_blocks(fn, 1);
2946
2947 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002948 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302949 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2950 == EGPRS_RESEG_FIRST_SEG_SENT);
2951
2952 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2953 OSMO_ASSERT(egprs3->spb == 2);
2954
2955 /* Table 10.4.8a.3.1 of 44.060 */
2956 switch (demanded_mcs) {
2957 case 3:
2958 OSMO_ASSERT(egprs3->cps == 3);
2959 break;
2960 case 2:
2961 OSMO_ASSERT(egprs3->cps == 9);
2962 break;
2963 case 1:
2964 OSMO_ASSERT(egprs3->cps == 11);
2965 break;
2966 default:
2967 OSMO_ASSERT(false);
2968 break;
2969 }
2970
2971 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002972 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302973 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2974 == EGPRS_RESEG_SECOND_SEG_SENT);
2975
2976 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2977 /* Table 10.4.8a.3.1 of 44.060 */
2978 OSMO_ASSERT(egprs3->spb == 3);
2979
2980 /* Table 10.4.8a.3.1 of 44.060 */
2981 switch (demanded_mcs) {
2982 case 3:
2983 OSMO_ASSERT(egprs3->cps == 3);
2984 break;
2985 case 2:
2986 OSMO_ASSERT(egprs3->cps == 9);
2987 break;
2988 case 1:
2989 OSMO_ASSERT(egprs3->cps == 11);
2990 break;
2991 default:
2992 OSMO_ASSERT(false);
2993 break;
2994 }
2995 tbf_cleanup(dl_tbf);
2996}
2997
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302998static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002999 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303000{
3001 uint32_t fn = 0;
3002 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303003 struct msgb *msg;
3004
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003005 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303006
3007 dl_tbf = tbf_init(the_bts, mcs);
3008
3009 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
3010 * The MCS transition are referred from table Table 8.1.1.2
3011 * of TS 44.060
3012 */
3013 /* TODO: Need to support of MCS8 -> MCS6 transistion
3014 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3015 * dated 2016-02-07 23:45:40 (UTC)
3016 */
3017 if (((mcs == 9) && (demanded_mcs < 9)) ||
3018 ((mcs == 7) && (demanded_mcs < 7))) {
3019 fn = fn_add_blocks(fn, 1);
3020 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003021 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3022 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303023
Max7d32f552017-12-15 11:25:14 +01003024 NACK(dl_tbf, 0);
3025 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303026
3027 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003028 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303029
3030 fn = fn_add_blocks(fn, 1);
3031 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003032 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3033 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303034
3035 fn = fn_add_blocks(fn, 1);
3036 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003037 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3038 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303039 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3040 ((mcs == 6) && (demanded_mcs > 8))) {
3041 fn = fn_add_blocks(fn, 1);
3042 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003043 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303044
3045 fn = fn_add_blocks(fn, 1);
3046 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003047 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3048 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303049
Max7d32f552017-12-15 11:25:14 +01003050 NACK(dl_tbf, 0);
3051 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303052
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003053 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303054
3055 fn = fn_add_blocks(fn, 1);
3056 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003057 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3058 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303059 } else if (mcs > 6) {
3060 /* No Mcs change cases are handled here for mcs > MCS6*/
3061 fn = fn_add_blocks(fn, 1);
3062 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003063 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3064 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303065
Max7d32f552017-12-15 11:25:14 +01003066 NACK(dl_tbf, 0);
3067 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303068
3069 fn = fn_add_blocks(fn, 1);
3070 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003071 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3072 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303073 } else {
3074
3075 /* No MCS change cases are handled here for mcs <= MCS6*/
3076 fn = fn_add_blocks(fn, 1);
3077 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003078 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303079
Max7d32f552017-12-15 11:25:14 +01003080 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303081
3082 fn = fn_add_blocks(fn, 1);
3083 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003084 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303085 }
3086
3087 tbf_cleanup(dl_tbf);
3088}
3089
3090static void test_tbf_egprs_retx_dl(void)
3091{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003092 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003093 the_pcu->bts = bts_alloc(the_pcu);
3094 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303095 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303096
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003097 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303098
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003099 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003100 setup_bts(the_bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003101 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303102 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003103 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303104
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303105
3106 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003107 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 6);
3108 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 1, 9);
3109 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 2, 8);
3110 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 5, 7);
3111 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 6, 9);
3112 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 7, 5);
3113 establish_and_use_egprs_dl_tbf_for_retx(the_bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303114
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003115 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003116 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303117}
3118
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303119static void test_tbf_egprs_spb_dl(void)
3120{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003121 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003122 the_pcu->bts = bts_alloc(the_pcu);
3123 BTS *the_bts = the_pcu->bts;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303124 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303125
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003126 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303127
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003128 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003129 setup_bts(the_bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003130 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303131
3132 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003133 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303134
3135 /*
3136 * First parameter is current MCS, second one is demanded_mcs
3137 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3138 * rest scenarios has been integration tested
3139 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003140 establish_and_use_egprs_dl_tbf_for_spb(the_bts, 6, 3);
3141 establish_and_use_egprs_dl_tbf_for_spb(the_bts, 5, 2);
3142 establish_and_use_egprs_dl_tbf_for_spb(the_bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303143 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003144 egprs_spb_to_normal_validation(the_bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303145
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003146 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003147 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303148}
3149
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003150static void test_tbf_egprs_dl()
3151{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003152 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003153 the_pcu->bts = bts_alloc(the_pcu);
3154 BTS *the_bts = the_pcu->bts;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003155 uint8_t ts_no = 4;
3156 int i;
3157
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003158 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003159
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003160 setup_bts(the_bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003161 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303162 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003163 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003164
3165 for (i = 1; i <= 9; i++)
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003166 establish_and_use_egprs_dl_tbf(the_bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003167
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003168 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003169 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003170}
3171
3172
3173
aravind sirsikare9a138e2017-01-24 12:36:08 +05303174static void test_packet_access_rej_prr_no_other_tbfs()
3175{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003176 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003177 the_pcu->bts = bts_alloc(the_pcu);
3178 BTS *the_bts = the_pcu->bts;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303179 uint32_t fn = 2654218;
3180 int ts_no = 7;
3181 uint8_t trx_no = 0;
3182 uint32_t tlli = 0xffeeddcc;
3183 struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
3184
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003185 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303186
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003187 setup_bts(the_bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303188
3189 int rc = 0;
3190
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003191 ul_tbf = handle_tbf_reject(the_bts->bts_data(), NULL, tlli,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303192 trx_no, ts_no);
3193
3194 OSMO_ASSERT(ul_tbf != 0);
3195
3196 /* trigger packet access reject */
3197 uint8_t bn = fn2bn(fn);
3198
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003199 rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
aravind sirsikare9a138e2017-01-24 12:36:08 +05303200 trx_no, ts_no, fn, bn);
3201
3202 OSMO_ASSERT(rc == 0);
3203
3204 ul_tbf->handle_timeout();
3205
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003206 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003207 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303208}
3209
3210static void test_packet_access_rej_prr()
3211{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003212 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003213 the_pcu->bts = bts_alloc(the_pcu);
3214 BTS *the_bts = the_pcu->bts;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303215 uint32_t fn = 2654218;
3216 uint16_t qta = 31;
3217 int ts_no = 7;
3218 uint8_t trx_no = 0;
3219 RlcMacUplink_t ulreq = {0};
3220 Packet_Resource_Request_t *presreq = NULL;
3221 uint8_t ms_class = 11;
3222 uint8_t egprs_ms_class = 11;
3223 uint32_t rach_fn = fn - 51;
3224 uint32_t sba_fn = fn + 52;
3225 uint32_t tlli = 0xffeeddcc;
3226 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3227 Multislot_capability_t *pmultislotcap = NULL;
3228
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003229 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303230
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003231 setup_bts(the_bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303232
3233 int rc = 0;
3234
3235 /*
3236 * Trigger rach till resources(USF) exhaust
3237 */
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003238 rc = bts_handle_rach(the_bts, 0x78, rach_fn, qta);
3239 rc = bts_handle_rach(the_bts, 0x79, rach_fn, qta);
3240 rc = bts_handle_rach(the_bts, 0x7a, rach_fn, qta);
3241 rc = bts_handle_rach(the_bts, 0x7b, rach_fn, qta);
3242 rc = bts_handle_rach(the_bts, 0x7c, rach_fn, qta);
3243 rc = bts_handle_rach(the_bts, 0x7d, rach_fn, qta);
3244 rc = bts_handle_rach(the_bts, 0x7e, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303245
3246 /* fake a resource request */
3247 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3248 presreq = &ulreq.u.Packet_Resource_Request;
3249 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3250 presreq->ID.UnionType = 1; /* != 0 */
3251 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01003252 presreq->Exist_MS_Radio_Access_capability2 = 1;
3253 pmsradiocap = &presreq->MS_Radio_Access_capability2;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303254 pmsradiocap->Count_MS_RA_capability_value = 1;
3255 pmsradiocap->MS_RA_capability_value[0].u.Content.
3256 Exist_Multislot_capability = 1;
3257 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3258 u.Content.Multislot_capability;
3259
3260 pmultislotcap->Exist_GPRS_multislot_class = 1;
3261 pmultislotcap->GPRS_multislot_class = ms_class;
3262 if (egprs_ms_class) {
3263 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3264 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3265 }
3266
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003267 send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303268
3269 /* trigger packet access reject */
3270 uint8_t bn = fn2bn(fn);
3271
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003272 rc = gprs_rlcmac_rcv_rts_block(the_bts->bts_data(),
aravind sirsikare9a138e2017-01-24 12:36:08 +05303273 trx_no, ts_no, fn, bn);
3274
3275 OSMO_ASSERT(rc == 0);
3276
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003277 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003278 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303279}
3280
aravind sirsikared3413e2016-11-11 17:15:10 +05303281void test_packet_access_rej_epdan()
3282{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003283 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003284 the_pcu->bts = bts_alloc(the_pcu);
3285 BTS *the_bts = the_pcu->bts;
aravind sirsikared3413e2016-11-11 17:15:10 +05303286 uint32_t tlli = 0xffeeddcc;
Maxd3a0d912019-03-05 16:15:01 +01003287 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x41, 0x4b,
3288 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3289 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3290 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303291
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003292 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003293 setup_bts(the_bts, 4);
3294 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(the_bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303295
3296 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3297
3298 struct msgb *msg = dl_tbf->create_packet_access_reject();
3299
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003300 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303301 osmo_hexdump(msg->data, 23));
3302
Maxd3a0d912019-03-05 16:15:01 +01003303 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003304 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003305
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003306 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003307 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303308}
3309
3310
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003311int main(int argc, char **argv)
3312{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003313 struct vty_app_info pcu_vty_info = {0};
3314
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003315 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3316 if (!tall_pcu_ctx)
3317 abort();
3318
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003319 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003320 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003321 log_set_use_color(osmo_stderr_target, 0);
3322 log_set_print_filename(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003323 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003324 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003325 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003326 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003327 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003328
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003329 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003330 pcu_l1_meas_set_link_qual(&meas, 12);
3331 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003332
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003333 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003334 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003335 test_tbf_final_ack(TEST_MODE_STANDARD);
3336 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003337 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003338 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003339 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003340 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003341 test_tbf_single_phase();
3342 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003343 test_tbf_ra_update_rach();
3344 test_tbf_dl_flow_and_rach_two_phase();
3345 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003346 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003347 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003348 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003349 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303350 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003351 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303352 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303353 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303354 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303355 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303356 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303357 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303358 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303359 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303360 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303361 test_packet_access_rej_prr();
3362 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003363
3364 if (getenv("TALLOC_REPORT_FULL"))
3365 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003366 return EXIT_SUCCESS;
3367}
3368
3369/*
3370 * stubs that should not be reached
3371 */
3372extern "C" {
3373void l1if_pdch_req() { abort(); }
3374void l1if_connect_pdch() { abort(); }
3375void l1if_close_pdch() { abort(); }
3376void l1if_open_pdch() { abort(); }
3377}