blob: aa7ab46b8b7a380e22a2482d28448c1f39dca8e6 [file] [log] [blame]
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01001/*
2 * TbfTest.cpp
3 *
4 * Copyright (C) 2013 by Holger Hans Peter Freyther
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include "bts.h"
24#include "tbf.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010025#include "tbf_dl.h"
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020026#include "tbf_ul.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010027#include "gprs_ms.h"
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010028#include "gprs_debug.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010029#include "gprs_ms_storage.h"
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +010030#include "pcu_utils.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020031#include "gprs_bssgp_pcu.h"
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020032#include "pcu_l1_if.h"
aravind sirsikarf2761382016-10-25 12:45:24 +053033#include "decoding.h"
Max1187a772018-01-26 13:31:42 +010034#include <gprs_rlcmac.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010035
36extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020037#include "pcu_vty.h"
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020038#include "coding_scheme.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020039
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010040#include <osmocom/core/application.h>
41#include <osmocom/core/msgb.h>
42#include <osmocom/core/talloc.h>
43#include <osmocom/core/utils.h>
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020044#include <osmocom/vty/vty.h>
Aravind Sirsikar505a86d2016-07-26 18:26:21 +053045#include <osmocom/gprs/protocol/gsm_04_60.h>
bhargava959d1de2016-08-17 15:17:21 +053046#include <osmocom/gsm/l1sap.h>
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020047#include <osmocom/core/fsm.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010048}
49
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020050#include <errno.h>
51
Philippd935d882016-11-07 13:07:36 +010052#define DUMMY_FN 2654167
53
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010054void *tall_pcu_ctx;
55int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010056bool spoof_mnc_3_digits = false;
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010057
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +070058/* Measurements shared by all unit tests */
59static struct pcu_l1_meas meas;
60
Pau Espin Pedrol945be912021-07-26 14:47:46 +020061int gprs_gp_send_test_cb(void *ctx, struct msgb *msg)
62{
63 return 0;
64}
65
66static gprs_pcu *prepare_pcu(void)
67{
68 struct gprs_pcu *pcu = gprs_pcu_alloc(tall_pcu_ctx);
69 bssgp_set_bssgp_callback(gprs_gp_send_test_cb, NULL);
70 return pcu;
71}
72
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010073static int bts_handle_rach(struct gprs_rlcmac_bts *bts, uint16_t ra, uint32_t Fn, int16_t qta)
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070074{
75 struct rach_ind_params rip = {
76 .burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
77 .is_11bit = false,
78 .ra = ra,
79 .trx_nr = 0,
80 .ts_nr = 0,
81 .rfn = Fn,
82 .qta = qta,
83 };
84
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010085 return bts_rcv_rach(bts, &rip);
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070086}
87
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010088static void check_tbf(gprs_rlcmac_tbf *tbf)
89{
90 OSMO_ASSERT(tbf);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020091 if (tbf->state_is(TBF_ST_WAIT_RELEASE))
Maxee5be3a2017-12-20 17:31:13 +010092 OSMO_ASSERT(tbf->timers_pending(T3191) || tbf->timers_pending(T3193));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020093 if (tbf->state_is(TBF_ST_RELEASING))
Maxee5be3a2017-12-20 17:31:13 +010094 OSMO_ASSERT(tbf->timers_pending(T_MAX));
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010095}
96
Jacob Erlbeckac89a552015-06-29 14:18:46 +020097static void test_tbf_base()
98{
99
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200100 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200101
102 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
103 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
104
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200105 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200106}
107
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100108static void test_tbf_tlli_update()
109{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200110 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100111 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200112 GprsMs *ms, *ms_new;
113
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200114 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100115
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100116 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100117 bts->trx[0].pdch[2].enable();
118 bts->trx[0].pdch[3].enable();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100119
120 /*
121 * Make a uplink and downlink allocation
122 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100123 ms = bts_alloc_ms(bts, 0, 0);
124 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200125 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200126 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200127 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200128 dl_tbf->set_ta(4);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100129 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200130 OSMO_ASSERT(dl_tbf->ms() == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100131
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100132 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200133 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200134 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200135 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100136 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200137 OSMO_ASSERT(ul_tbf->ms() == ms);
138
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100139 OSMO_ASSERT(bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100140
141 /*
142 * Now check.. that DL changes and that the timing advance
143 * has changed.
144 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200145 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100146
Jacob Erlbeck93990462015-05-15 15:50:43 +0200147 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100148 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200149 OSMO_ASSERT(ms == ms_new);
150
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100151 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200152 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100153 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
154 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200155
156 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200157 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100158 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200159 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100160
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100161 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200162 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100163 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200164
165 OSMO_ASSERT(ul_tbf->ta() == 4);
166 OSMO_ASSERT(dl_tbf->ta() == 4);
167
168 ul_tbf->set_ta(6);
169
170 OSMO_ASSERT(ul_tbf->ta() == 6);
171 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100172
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200173 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100174 TALLOC_FREE(the_pcu);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100175}
176
Daniel Willmann510d7d32014-08-15 18:19:41 +0200177static uint8_t llc_data[200];
178
Maxa2961182018-01-25 19:47:28 +0100179/* override, requires '-Wl,--wrap=pcu_sock_send' */
180int __real_pcu_sock_send(struct msgb *msg);
Pau Espin Pedrole91c4c72021-01-18 17:54:30 +0100181extern "C" int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200182{
183 return 0;
184}
185
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100186static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100187{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100188 gprs_rlcmac_trx *trx;
189
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100190 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200191 bts->initial_cs_dl = cs;
192 bts->initial_cs_ul = cs;
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100193 osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S);
194 osmo_tdef_set(the_pcu->T_defs, -2031, 0, OSMO_TDEF_S);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100195 trx = &bts->trx[0];
196
197 trx->pdch[ts_no].enable();
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100198 bts_set_current_frame_number(bts, DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100199}
200
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100201static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100202 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100203{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100204 int tfi;
205 uint8_t trx_no;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200206 GprsMs *ms;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100207 gprs_rlcmac_dl_tbf *dl_tbf;
208
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100209 ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100210
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100211 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100212 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200213 dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100214 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200215 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100216 check_tbf(dl_tbf);
217
218 /* "Establish" the DL TBF */
Max0e599802018-01-23 20:09:06 +0100219 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200220 TBF_SET_STATE(dl_tbf, TBF_ST_FLOW);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100221 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100222 check_tbf(dl_tbf);
223
224 *trx_no_ = trx_no;
225
226 return dl_tbf;
227}
228
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200229static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
230{
231 unsigned bn = fn2bn(fn) + blocks;
232 fn = fn - (fn % 52);
233 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200234 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200235}
236
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200237static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200238 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200239 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100240{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200241 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200242 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200243 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200244 bn += 1;
245 if (block_nr)
246 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100247}
248
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200249static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200250 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200251{
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100252 request_dl_rlc_block(tbf->bts, tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200253 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200254}
255
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100256enum test_tbf_final_ack_mode {
257 TEST_MODE_STANDARD,
258 TEST_MODE_REVERSE_FREE
259};
260
261static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200262{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200263 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100264 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100265 uint8_t ts_no = 4;
266 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200267 uint8_t ms_class = 45;
268 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100269 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100270 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200271 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200272 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200273
274 uint8_t rbb[64/8];
275
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200276 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100277
Daniel Willmann510d7d32014-08-15 18:19:41 +0200278 gprs_rlcmac_dl_tbf *dl_tbf;
279 gprs_rlcmac_tbf *new_tbf;
280
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100281 setup_bts(bts, ts_no);
282 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200283 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200284 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200285
286 for (i = 0; i < sizeof(llc_data); i++)
287 llc_data[i] = i%256;
288
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100289 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100290 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
291 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200292
293
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100294 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200295 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200296 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200297 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200298 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200299 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200300
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100301 OSMO_ASSERT(dl_tbf->have_data());
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200302 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200303
304 /* Queue a final ACK */
305 memset(rbb, 0, sizeof(rbb));
306 /* Receive a final ACK */
Max7df82d42017-12-15 11:14:30 +0100307 dl_tbf->rcvd_dl_ack(true, 1, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200308
309 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200310 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100311 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100312 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200313 OSMO_ASSERT(new_tbf != dl_tbf);
314 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100315 check_tbf(dl_tbf);
Max0e599802018-01-23 20:09:06 +0100316 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100317 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100318 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100319 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100320 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100321 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100322 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100323 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100324 } else {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100325 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100326 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100327 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100328 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100329 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100330 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
331 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100332 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100333
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100334 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200335 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200336}
337
Max7d32f552017-12-15 11:25:14 +0100338/* Receive an ACK */
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200339#define RCV_ACK(fin, tbf, rbb) do { \
340 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
341 tbf->rcvd_dl_ack(fin, w->v_s(), rbb); \
Max7d32f552017-12-15 11:25:14 +0100342 if (!fin) \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200343 OSMO_ASSERT(w->window_empty()); \
Max7d32f552017-12-15 11:25:14 +0100344 } while(0)
345
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100346static void test_tbf_delayed_release()
347{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200348 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100349 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100350 uint8_t ts_no = 4;
351 unsigned i;
352 uint8_t ms_class = 45;
353 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100354 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200355 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200356 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100357
358 uint8_t rbb[64/8];
359
360 gprs_rlcmac_dl_tbf *dl_tbf;
361
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200362 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100363
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100364 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100365 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100366
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100367 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200368 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100369
370 for (i = 0; i < sizeof(llc_data); i++)
371 llc_data[i] = i%256;
372
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200373 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100374
375 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100376 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
377 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100378
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200379 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100380
381 /* Drain the queue */
382 while (dl_tbf->have_data())
383 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200384 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100385
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200386 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100387
388 /* ACK all blocks */
389 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100390
391 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100392
393 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200394 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100395
Max7d32f552017-12-15 11:25:14 +0100396 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100397
398 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100399 dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200400 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200401 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100402
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200403 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FINISHED));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100404
Max7d32f552017-12-15 11:25:14 +0100405 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100406
407 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200408 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +0100409 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100410 check_tbf(dl_tbf);
411 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100412 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200413 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100414}
415
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200416static void test_tbf_imsi()
417{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200418 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100419 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200420 uint8_t ts_no = 4;
421 uint8_t ms_class = 45;
422 uint8_t trx_no;
423 GprsMs *ms1, *ms2;
424
425 gprs_rlcmac_dl_tbf *dl_tbf[2];
426
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200427 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200428
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100429 setup_bts(bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200430
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100431 dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);
432 dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200433
434 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
435 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
436
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100437 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100438 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200439 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100440 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200441 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100442 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200443 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200444
445 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100446 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100447 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200448 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100449 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200450 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100451 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200452 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200453
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100454 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200455 {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100456 ms_ref(ms2);
457 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100458 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200459 OSMO_ASSERT(ms1 != NULL);
460 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100461 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
462 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
463 ms_unref(ms2);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200464 }
465
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100466 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200467 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200468
469 tbf_free(dl_tbf[1]);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100470 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200471 OSMO_ASSERT(ms1 == NULL);
472
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100473 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200474 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200475}
476
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200477static void test_tbf_exhaustion()
478{
Pau Espin Pedrol945be912021-07-26 14:47:46 +0200479 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100480 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200481 unsigned i;
482 uint8_t ts_no = 4;
483 uint8_t ms_class = 45;
484 int rc = 0;
485
486 uint8_t buf[256] = {0};
487
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200488 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200489
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100490 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
491 if (!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 Pedrol2182e622021-01-14 16:48:38 +0100496 setup_bts(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
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100506 rc = 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 Pedrol945be912021-07-26 14:47:46 +0200522 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100523 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200524 uint8_t ts_no = 4;
525 uint8_t ms_class = 45;
526 int rc = 0;
527 uint32_t tlli = 0xc0123456;
528 const char *imsi = "001001000123456";
529 unsigned delay_csec = 1000;
530 GprsMs *ms;
531
532 uint8_t buf[19];
533
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100534 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
535 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200536 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
537 abort();
538 }
539
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200540 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200541
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100542 setup_bts(bts, ts_no);
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200543 /* keep the MS object 10 seconds */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100544 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200545
Alexander Couzens290d9032020-09-16 21:52:02 +0200546 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200547
548 /* Handle LLC frame 1 */
549 memset(buf, 1, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100550 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200551 delay_csec, buf, sizeof(buf));
552 OSMO_ASSERT(rc >= 0);
553
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100554 ms = bts_ms_store(bts)->get_ms(0, 0, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200555 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100556 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
557 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200558
559 /* Handle LLC frame 2 */
560 memset(buf, 2, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100561 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200562 delay_csec, buf, sizeof(buf));
563 OSMO_ASSERT(rc >= 0);
564
565 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100566 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200567
568 /* Handle LLC frame 3 */
569 memset(buf, 3, sizeof(buf));
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +0100570 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200571 delay_csec, buf, sizeof(buf));
572 OSMO_ASSERT(rc >= 0);
573
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100574 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200575
576 /* Get first BSN */
577 struct msgb *msg;
578 int fn = 0;
579 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100580 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
581 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
582 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
583 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
584 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
585 { 0x07, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
586 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
587 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200588
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100589 while (ms_dl_tbf(ms)->have_data()) {
590 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, 7);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200591 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100592 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200593 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100594
Jacob Erlbeck41168642015-06-12 13:41:00 +0200595 expected_data += 1;
596 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200597 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200598
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200599 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200600
Alexander Couzens290d9032020-09-16 21:52:02 +0200601 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100602 TALLOC_FREE(the_pcu);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200603}
604
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100605static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200606 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200607{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200608 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200609 int tfi = 0;
610 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200611 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200612 struct gprs_rlcmac_pdch *pdch;
613
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100614 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200615
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100616 bts_handle_rach(bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200617
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100618 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200619 OSMO_ASSERT(ul_tbf != NULL);
620
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200621 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200622
623 uint8_t data_msg[23] = {
624 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
625 uint8_t(1 | (tfi << 2)),
626 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200627 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
628 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200629 };
630
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100631 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200632 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200633
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100634 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200635 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200636
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200637 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200638}
639
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100640static void send_ul_mac_block_buf(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch,
641 unsigned fn, uint8_t *buf, int num_bytes)
642{
Pau Espin Pedrolfecab502021-03-17 15:26:37 +0100643 bts_set_current_block_frame_number(bts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100644 pdch->rcv_block(buf, num_bytes, fn, &meas);
645 pdch_ulc_expire_fn(pdch->ulc, fn);
646}
647
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100648static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, unsigned trx_no, unsigned ts_no,
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200649 RlcMacUplink_t *ulreq, unsigned fn)
650{
651 bitvec *rlc_block;
652 uint8_t buf[64];
653 int num_bytes;
654 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200655
Alexander Couzensccde5c92017-02-04 03:10:08 +0100656 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200657
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100658 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200659 num_bytes = bitvec_pack(rlc_block, &buf[0]);
660 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
661 bitvec_free(rlc_block);
662
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100663 pdch = &bts->trx[trx_no].pdch[ts_no];
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100664 send_ul_mac_block_buf(bts, pdch, fn, &buf[0], num_bytes);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200665}
666
Pau Espin Pedrol58046e42021-03-29 19:01:13 +0200667
668static uint32_t get_poll_fn(struct gprs_rlcmac_tbf *tbf, uint8_t poll_ts)
669{
670 struct gprs_rlcmac_pdch *pdch = &tbf->trx->pdch[poll_ts];
671 struct pdch_ulc *ulc = pdch->ulc;
672 struct rb_node *node;
673 struct pdch_ulc_node *item;
674
675 for (node = rb_first(&ulc->tree_root); node; node = rb_next(node)) {
676 item = container_of(node, struct pdch_ulc_node, node);
677 if (item->type == PDCH_ULC_NODE_TBF_POLL && item->tbf_poll.poll_tbf == tbf)
678 return item->fn;
679 }
680 OSMO_ASSERT(0);
681}
682
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200683static void send_control_ack(gprs_rlcmac_tbf *tbf)
684{
685 RlcMacUplink_t ulreq = {0};
686
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200687 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
688 Packet_Control_Acknowledgement_t *ctrl_ack =
689 &ulreq.u.Packet_Control_Acknowledgement;
690
691 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
692 ctrl_ack->TLLI = tbf->tlli();
Pau Espin Pedrol16e16782021-03-29 19:10:19 +0200693 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->control_ts,
694 &ulreq, get_poll_fn(tbf, tbf->control_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200695}
696
Pau Espin Pedrol99360a32021-03-09 17:18:12 +0100697static void send_empty_block(gprs_rlcmac_tbf *tbf, unsigned ts_no, unsigned fn)
698{
699 struct gprs_rlcmac_pdch *pdch;
700 pdch = &tbf->bts->trx[tbf->trx->trx_no].pdch[ts_no];
701 send_ul_mac_block_buf(tbf->bts, pdch, fn, NULL, 0);
702}
703
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100704static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530705 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
706 uint8_t ms_class, uint8_t egprs_ms_class)
707{
708 GprsMs *ms;
709 uint32_t rach_fn = *fn - 51;
710 uint32_t sba_fn = *fn + 52;
711 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100712 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530713 gprs_rlcmac_ul_tbf *ul_tbf;
714 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530715 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530716 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530717
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530718 /* needed to set last_rts_fn in the PDCH object */
719 request_dl_rlc_block(bts, trx_no, ts_no, fn);
720
721 /*
722 * simulate RACH, this sends an Immediate
723 * Assignment Uplink on the AGCH
724 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100725 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530726
727 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100728 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530729
730 /* fake a resource request */
731 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
732 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
733 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
734 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100735 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
736 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530737 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100738 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530739 MS_RA_capability_value[0].u.Content.
740 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100741 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530742 MS_RA_capability_value[0].u.Content.Multislot_capability.
743 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100744 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530745 MS_RA_capability_value[0].u.Content.Multislot_capability.
746 GPRS_multislot_class = ms_class;
747 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100748 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530749 MS_RA_capability_value[0].u.Content.
750 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100751 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530752 MS_RA_capability_value[0].u.Content.
753 Multislot_capability.EGPRS_multislot_class = ms_class;
754 }
755
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100756 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530757
758 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100759 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530760 OSMO_ASSERT(ul_tbf);
761 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
762
763 /* send packet uplink assignment */
764 *fn = sba_fn;
765 request_dl_rlc_block(ul_tbf, fn);
766
767 /* send real acknowledgement */
768 send_control_ack(ul_tbf);
769
770 check_tbf(ul_tbf);
771 /* send fake data */
772 uint8_t data_msg[42] = {
773 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100774 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530775 1, /* BSN:7, E:1 */
776 };
777
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100778 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530779 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
780
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100781 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530782 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100783 OSMO_ASSERT(ms_ta(ms) == qta/4);
784 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530785
786 /*
787 * TS 44.060, B.8.1
788 * first seg received first, later second seg
789 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530790 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
791 egprs3->si = 0;
792 egprs3->r = 1;
793 egprs3->cv = 7;
794 egprs3->tfi_hi = tfi & 0x03;
795 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
796 egprs3->bsn1_hi = 1;
797 egprs3->bsn1_lo = 0;
798 egprs3->cps_hi = 1;
799 data_msg[3] = 0xff;
800 egprs3->pi = 0;
801 egprs3->cps_lo = 1;
802 egprs3->rsb = 0;
803 egprs3->spb = 0;
804 egprs3->pi = 0;
805
806 pdch->rcv_block(data_msg, 42, *fn, &meas);
807
808 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
809
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200810 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x87, 0xb0,
811 0x06, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100812 };
813
814 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200815 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100816 return NULL;
817 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530818
819 egprs3->si = 0;
820 egprs3->r = 1;
821 egprs3->cv = 7;
822 egprs3->tfi_hi = tfi & 0x03;
823 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
824 egprs3->bsn1_hi = 4;
825 egprs3->bsn1_lo = 0;
826 egprs3->cps_hi = 1;
827 data_msg[3] = 0xff;
828 egprs3->pi = 0;
829 egprs3->cps_lo = 1;
830 egprs3->rsb = 0;
831 egprs3->spb = 0;
832
833 pdch->rcv_block(data_msg, 42, *fn, &meas);
834
835 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
836
Pau Espin Pedrolc432e062021-05-11 13:17:31 +0200837 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x88, 0xb0,
838 0x06, 0x8b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
Maxd3a0d912019-03-05 16:15:01 +0100839 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530840
Maxd3a0d912019-03-05 16:15:01 +0100841 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200842 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100843 return NULL;
844 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530845 return ul_tbf;
846}
847
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100848static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530849 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
850 uint8_t ms_class, uint8_t egprs_ms_class)
851{
852 GprsMs *ms;
853 uint32_t rach_fn = *fn - 51;
854 uint32_t sba_fn = *fn + 52;
855 uint8_t trx_no = 0;
856 int tfi = 0, i = 0;
857 gprs_rlcmac_ul_tbf *ul_tbf;
858 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530859 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530860 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530861
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530862 /* needed to set last_rts_fn in the PDCH object */
863 request_dl_rlc_block(bts, trx_no, ts_no, fn);
864
865 /*
866 * simulate RACH, this sends an Immediate
867 * Assignment Uplink on the AGCH
868 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100869 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530870
871 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100872 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530873
874 /* fake a resource request */
875 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
876 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
877 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
878 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100879 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
880 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530881 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100882 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530883 MS_RA_capability_value[0].u.Content.
884 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100885 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530886 MS_RA_capability_value[0].u.Content.Multislot_capability.
887 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100888 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530889 MS_RA_capability_value[0].u.Content.Multislot_capability.
890 GPRS_multislot_class = ms_class;
891 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100892 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530893 MS_RA_capability_value[0].u.Content.
894 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100895 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530896 MS_RA_capability_value[0].u.Content.
897 Multislot_capability.EGPRS_multislot_class = ms_class;
898 }
899
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100900 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530901
902 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100903 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530904 OSMO_ASSERT(ul_tbf != NULL);
905 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
906
907 /* send packet uplink assignment */
908 *fn = sba_fn;
909 request_dl_rlc_block(ul_tbf, fn);
910
911 /* send real acknowledgement */
912 send_control_ack(ul_tbf);
913
914 check_tbf(ul_tbf);
915
916 /* send fake data */
917 uint8_t data_msg[42] = {
918 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
919 uint8_t(0 | (tfi << 1)),
920 uint8_t(1), /* BSN:7, E:1 */
921 };
922
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100923 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530924 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
925
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100926 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530927 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100928 OSMO_ASSERT(ms_ta(ms) == qta/4);
929 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530930
931 /*
932 * TS 44.060, B.8.1
933 * first seg received first, later second seg
934 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530935 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
936 egprs3->si = 1;
937 egprs3->r = 1;
938 egprs3->cv = 7;
939 egprs3->tfi_hi = tfi & 0x03;
940 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
941 egprs3->bsn1_hi = 1;
942 egprs3->bsn1_lo = 0;
943 egprs3->cps_hi = 1;
944 data_msg[3] = 0xff;
945 egprs3->pi = 0;
946 egprs3->cps_lo = 1;
947 egprs3->rsb = 0;
948 egprs3->spb = 2;
949 egprs3->pi = 0;
950
951 pdch->rcv_block(data_msg, 42, *fn, &meas);
952
953 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
954
955 /* check the status of the block */
956 OSMO_ASSERT(block->spb_status.block_status_ul ==
957 EGPRS_RESEG_FIRST_SEG_RXD);
958
959 egprs3->si = 1;
960 egprs3->r = 1;
961 egprs3->cv = 7;
962 egprs3->tfi_hi = tfi & 0x03;
963 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
964 egprs3->bsn1_hi = 1;
965 egprs3->bsn1_lo = 0;
966 egprs3->cps_hi = 1;
967 data_msg[3] = 0xff;
968 egprs3->pi = 0;
969 egprs3->cps_lo = 1;
970 egprs3->rsb = 0;
971 egprs3->spb = 3;
972
973 pdch->rcv_block(data_msg, 42, *fn, &meas);
974
975 /* check the status of the block */
976 OSMO_ASSERT(block->spb_status.block_status_ul ==
977 EGPRS_RESEG_DEFAULT);
978 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100979 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530980 /* Assembled MCS is MCS6. so the size is 74 */
981 OSMO_ASSERT(block->len == 74);
982
983 /*
984 * TS 44.060, B.8.1
985 * second seg first, later first seg
986 */
987 memset(data_msg, 0, sizeof(data_msg));
988
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530989 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
990 egprs3->si = 1;
991 egprs3->r = 1;
992 egprs3->cv = 7;
993 egprs3->tfi_hi = tfi & 0x03;
994 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
995 egprs3->bsn1_hi = 2;
996 egprs3->bsn1_lo = 0;
997 egprs3->cps_hi = 1;
998 data_msg[3] = 0xff;
999 egprs3->pi = 0;
1000 egprs3->cps_lo = 1;
1001 egprs3->rsb = 0;
1002 egprs3->spb = 3;
1003 egprs3->pi = 0;
1004
1005 pdch->rcv_block(data_msg, 42, *fn, &meas);
1006
1007 block = ul_tbf->m_rlc.block(2);
1008 /* check the status of the block */
1009 OSMO_ASSERT(block->spb_status.block_status_ul ==
1010 EGPRS_RESEG_SECOND_SEG_RXD);
1011
1012 egprs3->si = 1;
1013 egprs3->r = 1;
1014 egprs3->cv = 7;
1015 egprs3->tfi_hi = tfi & 0x03;
1016 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1017 egprs3->bsn1_hi = 2;
1018 egprs3->bsn1_lo = 0;
1019 egprs3->cps_hi = 1;
1020 data_msg[3] = 0xff;
1021 egprs3->pi = 0;
1022 egprs3->cps_lo = 1;
1023 egprs3->rsb = 0;
1024 egprs3->spb = 2;
1025 egprs3->pi = 0;
1026
1027 pdch->rcv_block(data_msg, 42, *fn, &meas);
1028
1029 /* check the status of the block */
1030 OSMO_ASSERT(block->spb_status.block_status_ul ==
1031 EGPRS_RESEG_DEFAULT);
1032 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001033 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301034 /* Assembled MCS is MCS6. so the size is 74 */
1035 OSMO_ASSERT(block->len == 74);
1036
1037 /*
1038 * TS 44.060, B.8.1
1039 * Error scenario with spb as 1
1040 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301041 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1042 egprs3->si = 1;
1043 egprs3->r = 1;
1044 egprs3->cv = 7;
1045 egprs3->tfi_hi = tfi & 0x03;
1046 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1047 egprs3->bsn1_hi = 3;
1048 egprs3->bsn1_lo = 0;
1049 egprs3->cps_hi = 1;
1050 data_msg[3] = 0xff;
1051 egprs3->pi = 0;
1052 egprs3->cps_lo = 1;
1053 egprs3->rsb = 0;
1054 egprs3->spb = 1;
1055 egprs3->pi = 0;
1056
1057 pdch->rcv_block(data_msg, 42, *fn, &meas);
1058
1059 block = ul_tbf->m_rlc.block(3);
1060 /* check the status of the block */
1061 OSMO_ASSERT(block->spb_status.block_status_ul ==
1062 EGPRS_RESEG_DEFAULT);
1063 /*
1064 * TS 44.060, B.8.1
1065 * comparison of rlc_data for multiple scenarios
1066 * Receive First, the second(BSN 3)
1067 * Receive First, First then Second(BSN 4)
1068 * Receive Second then First(BSN 5)
1069 * after above 3 scenarios are triggered,
1070 * rlc_data of all 3 BSN are compared
1071 */
1072
1073 /* Initialize the data_msg */
1074 for (i = 0; i < 42; i++)
1075 data_msg[i] = i;
1076
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301077 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1078 egprs3->si = 1;
1079 egprs3->r = 1;
1080 egprs3->cv = 7;
1081 egprs3->tfi_hi = tfi & 0x03;
1082 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1083 egprs3->bsn1_hi = 3;
1084 egprs3->bsn1_lo = 0;
1085 egprs3->cps_hi = 1;
1086 data_msg[3] = 0xff;
1087 egprs3->pi = 0;
1088 egprs3->cps_lo = 1;
1089 egprs3->rsb = 0;
1090 egprs3->spb = 2;
1091 egprs3->pi = 0;
1092
1093 pdch->rcv_block(data_msg, 42, *fn, &meas);
1094
1095 block = ul_tbf->m_rlc.block(3);
1096 /* check the status of the block */
1097 OSMO_ASSERT(block->spb_status.block_status_ul ==
1098 EGPRS_RESEG_FIRST_SEG_RXD);
1099
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301100 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1101 egprs3->si = 1;
1102 egprs3->r = 1;
1103 egprs3->cv = 7;
1104 egprs3->tfi_hi = tfi & 0x03;
1105 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1106 egprs3->bsn1_hi = 3;
1107 egprs3->bsn1_lo = 0;
1108 egprs3->cps_hi = 1;
1109 data_msg[3] = 0xff;
1110 egprs3->pi = 0;
1111 egprs3->cps_lo = 1;
1112 egprs3->rsb = 0;
1113 egprs3->spb = 3;
1114 egprs3->pi = 0;
1115
1116 pdch->rcv_block(data_msg, 42, *fn, &meas);
1117
1118 block = ul_tbf->m_rlc.block(3);
1119 /* check the status of the block */
1120 OSMO_ASSERT(block->spb_status.block_status_ul ==
1121 EGPRS_RESEG_DEFAULT);
1122 /* Assembled MCS is MCS6. so the size is 74 */
1123 OSMO_ASSERT(block->len == 74);
1124 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001125 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301126
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301127 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1128 egprs3->si = 1;
1129 egprs3->r = 1;
1130 egprs3->cv = 7;
1131 egprs3->tfi_hi = tfi & 0x03;
1132 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1133 egprs3->bsn1_hi = 4;
1134 egprs3->bsn1_lo = 0;
1135 egprs3->cps_hi = 1;
1136 data_msg[3] = 0xff;
1137 egprs3->pi = 0;
1138 egprs3->cps_lo = 1;
1139 egprs3->rsb = 0;
1140 egprs3->spb = 2;
1141 egprs3->pi = 0;
1142
1143 pdch->rcv_block(data_msg, 42, *fn, &meas);
1144
1145 block = ul_tbf->m_rlc.block(4);
1146 /* check the status of the block */
1147 OSMO_ASSERT(block->spb_status.block_status_ul ==
1148 EGPRS_RESEG_FIRST_SEG_RXD);
1149
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301150 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1151 egprs3->si = 1;
1152 egprs3->r = 1;
1153 egprs3->cv = 7;
1154 egprs3->tfi_hi = tfi & 0x03;
1155 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1156 egprs3->bsn1_hi = 4;
1157 egprs3->bsn1_lo = 0;
1158 egprs3->cps_hi = 1;
1159 data_msg[3] = 0xff;
1160 egprs3->pi = 0;
1161 egprs3->cps_lo = 1;
1162 egprs3->rsb = 0;
1163 egprs3->spb = 2;
1164 egprs3->pi = 0;
1165
1166 pdch->rcv_block(data_msg, 42, *fn, &meas);
1167
1168 block = ul_tbf->m_rlc.block(4);
1169 /* check the status of the block */
1170 OSMO_ASSERT(block->spb_status.block_status_ul ==
1171 EGPRS_RESEG_FIRST_SEG_RXD);
1172
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301173 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1174 egprs3->si = 1;
1175 egprs3->r = 1;
1176 egprs3->cv = 7;
1177 egprs3->tfi_hi = tfi & 0x03;
1178 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1179 egprs3->bsn1_hi = 4;
1180 egprs3->bsn1_lo = 0;
1181 egprs3->cps_hi = 1;
1182 data_msg[3] = 0xff;
1183 egprs3->pi = 0;
1184 egprs3->cps_lo = 1;
1185 egprs3->rsb = 0;
1186 egprs3->spb = 3;
1187 egprs3->pi = 0;
1188
1189 pdch->rcv_block(data_msg, 42, *fn, &meas);
1190
1191 block = ul_tbf->m_rlc.block(4);
1192 /* check the status of the block */
1193 OSMO_ASSERT(block->spb_status.block_status_ul ==
1194 EGPRS_RESEG_DEFAULT);
1195 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001196 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301197 /* Assembled MCS is MCS6. so the size is 74 */
1198 OSMO_ASSERT(block->len == 74);
1199
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301200 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1201 egprs3->si = 1;
1202 egprs3->r = 1;
1203 egprs3->cv = 7;
1204 egprs3->tfi_hi = tfi & 0x03;
1205 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1206 egprs3->bsn1_hi = 5;
1207 egprs3->bsn1_lo = 0;
1208 egprs3->cps_hi = 1;
1209 data_msg[3] = 0xff;
1210 egprs3->pi = 0;
1211 egprs3->cps_lo = 1;
1212 egprs3->rsb = 0;
1213 egprs3->spb = 3;
1214 egprs3->pi = 0;
1215
1216 pdch->rcv_block(data_msg, 42, *fn, &meas);
1217
1218 block = ul_tbf->m_rlc.block(5);
1219 /* check the status of the block */
1220 OSMO_ASSERT(block->spb_status.block_status_ul ==
1221 EGPRS_RESEG_SECOND_SEG_RXD);
1222
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301223 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1224 egprs3->si = 1;
1225 egprs3->r = 1;
1226 egprs3->cv = 7;
1227 egprs3->tfi_hi = tfi & 0x03;
1228 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1229 egprs3->bsn1_hi = 5;
1230 egprs3->bsn1_lo = 0;
1231 egprs3->cps_hi = 1;
1232 data_msg[3] = 0xff;
1233 egprs3->pi = 0;
1234 egprs3->cps_lo = 1;
1235 egprs3->rsb = 0;
1236 egprs3->spb = 2;
1237 egprs3->pi = 0;
1238
1239 pdch->rcv_block(data_msg, 42, *fn, &meas);
1240
1241 block = ul_tbf->m_rlc.block(5);
1242
1243 /* check the status of the block */
1244 OSMO_ASSERT(block->spb_status.block_status_ul ==
1245 EGPRS_RESEG_DEFAULT);
1246 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001247 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301248 /* Assembled MCS is MCS6. so the size is 74 */
1249 OSMO_ASSERT(block->len == 74);
1250
1251 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1252 ul_tbf->m_rlc.block(4)->len);
1253 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1254 ul_tbf->m_rlc.block(3)->len);
1255
1256 /* Compare the spb status of each BSNs(3,4,5). should be same */
1257 OSMO_ASSERT(
1258 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1259 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1260 OSMO_ASSERT(
1261 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1262 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1263
1264 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1265 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1266 ul_tbf->m_rlc.block(4)->cs_last);
1267 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1268 ul_tbf->m_rlc.block(3)->cs_last);
1269
1270 /* Compare the data of each BSNs(3,4,5). should be same */
1271 OSMO_ASSERT(
1272 !memcmp(ul_tbf->m_rlc.block(5)->block,
1273 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1274 ));
1275 OSMO_ASSERT(
1276 !memcmp(ul_tbf->m_rlc.block(5)->block,
1277 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1278 ));
1279
1280 return ul_tbf;
1281}
1282
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001283static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301284 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1285 uint8_t ms_class, uint8_t egprs_ms_class)
1286{
sivasankari1d8744c2017-01-24 15:53:35 +05301287 uint32_t rach_fn = *fn - 51;
1288 uint32_t sba_fn = *fn + 52;
1289 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001290 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301291 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301292 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301293
sivasankari1d8744c2017-01-24 15:53:35 +05301294 /* needed to set last_rts_fn in the PDCH object */
1295 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1296
1297 /*
1298 * simulate RACH, this sends an Immediate
1299 * Assignment Uplink on the AGCH
1300 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001301 bts_handle_rach(bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301302
1303 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001304 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
sivasankari1d8744c2017-01-24 15:53:35 +05301305
1306 /* fake a resource request */
1307 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1308 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1309 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1310 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001311 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1312 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301313 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001314 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301315 MS_RA_capability_value[0].u.Content.
1316 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001317 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301318 MS_RA_capability_value[0].u.Content.Multislot_capability.
1319 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001320 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301321 MS_RA_capability_value[0].u.Content.Multislot_capability.
1322 GPRS_multislot_class = ms_class;
1323 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001324 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301325 MS_RA_capability_value[0].u.Content.
1326 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001327 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301328 MS_RA_capability_value[0].u.Content.
1329 Multislot_capability.EGPRS_multislot_class = ms_class;
1330 }
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001331 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301332
1333 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001334 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301335 /* send packet uplink assignment */
1336 *fn = sba_fn;
1337 request_dl_rlc_block(ul_tbf, fn);
1338
1339 /* send real acknowledgement */
1340 send_control_ack(ul_tbf);
1341
1342 check_tbf(ul_tbf);
1343
1344 return ul_tbf;
1345}
1346
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001347static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301348 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1349 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1350{
1351 OSMO_ASSERT(ul_tbf);
1352 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1353 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301354 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001355 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301356 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301357
1358 /* send fake data with cv=0*/
1359 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1360 uint8_t data[49] = {0};
1361
1362 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1363
1364 /*header_construction */
1365 memset(data, 0x2b, sizeof(data));
1366 /* Message with CRBB */
1367 for (int i = 0 ; i < 80; i++) {
1368 hdr3->r = 0;
1369 hdr3->si = 0;
1370 hdr3->cv = 10;
1371 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1372 hdr3->tfi_lo = tfi & 0x7;
1373 hdr3->bsn1_hi = ((i * 2)&0x1f);
1374 hdr3->bsn1_lo = ((i * 2)/32);
1375 hdr3->cps_hi = 0;
1376 hdr3->cps_lo = 0;
1377 hdr3->spb = 0;
1378 hdr3->rsb = 0;
1379 hdr3->pi = 0;
1380 hdr3->spare = 0;
1381 hdr3->dummy = 1;
1382 data[4] = 0x0;
1383 data[5] = 0x0;
1384 data[6] = 0x2b;
1385 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001386 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301387 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1388 }
1389 ul_tbf->create_ul_ack(*fn, ts_no);
1390 memset(data, 0x2b, sizeof(data));
1391 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1392 hdr3->r = 0;
1393 hdr3->si = 0;
1394 hdr3->cv = 0;
1395 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1396 hdr3->tfi_lo = tfi & 0x7;
1397 hdr3->bsn1_hi = 0;
1398 hdr3->bsn1_lo = 2;
1399 hdr3->cps_hi = 0;
1400 hdr3->cps_lo = 0;
1401 hdr3->spb = 0;
1402 hdr3->rsb = 0;
1403 hdr3->pi = 0;
1404 hdr3->spare = 0;
1405 hdr3->dummy = 1;
1406 data[4] = 0x0;
1407 data[5] = 0x2b;
1408 data[6] = 0x2b;
1409 data[7] = 0x2b;
1410
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001411 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301412 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1413
1414 request_dl_rlc_block(ul_tbf, fn);
1415
1416 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001417 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301418
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001419 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301420 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001421 OSMO_ASSERT(ms_ta(ms) == qta/4);
1422 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301423
1424 return ul_tbf;
1425}
1426
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001427static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301428 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1429 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1430{
1431 OSMO_ASSERT(ul_tbf);
1432 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1433 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301434 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001435 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301436 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301437
1438 check_tbf(ul_tbf);
1439 /* send fake data with cv=0*/
1440 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1441 uint8_t data[49] = {0};
1442
1443 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1444
1445 /*header_construction */
1446 memset(data, 0x2b, sizeof(data));
1447
1448 /* Message with URBB & URBB length */
1449 for (int i = 0 ; i < 20; i++) {
1450 hdr3->r = 0;
1451 hdr3->si = 0;
1452 hdr3->cv = 10;
1453 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1454 hdr3->tfi_lo = tfi & 0x7;
1455 hdr3->bsn1_hi = ((i * 2)&0x1f);
1456 hdr3->bsn1_lo = ((i * 2)/32);
1457 hdr3->cps_hi = 0;
1458 hdr3->cps_lo = 0;
1459 hdr3->spb = 0;
1460 hdr3->rsb = 0;
1461 hdr3->pi = 0;
1462 hdr3->spare = 0;
1463 hdr3->dummy = 1;
1464 data[4] = 0x0;
1465 data[5] = 0x0;
1466 data[6] = 0x2b;
1467 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001468 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301469 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1470 }
1471 ul_tbf->create_ul_ack(*fn, ts_no);
1472 memset(data, 0x2b, sizeof(data));
1473 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1474 hdr3->r = 0;
1475 hdr3->si = 0;
1476 hdr3->cv = 0;
1477 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1478 hdr3->tfi_lo = tfi & 0x7;
1479 hdr3->bsn1_hi = 0;
1480 hdr3->bsn1_lo = 2;
1481 hdr3->cps_hi = 0;
1482 hdr3->cps_lo = 0;
1483 hdr3->spb = 0;
1484 hdr3->rsb = 0;
1485 hdr3->pi = 0;
1486 hdr3->spare = 0;
1487 hdr3->dummy = 1;
1488 data[4] = 0x0;
1489 data[5] = 0x2b;
1490 data[6] = 0x2b;
1491 data[7] = 0x2b;
1492
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001493 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301494 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +02001495 ul_tbf->create_ul_ack(*fn, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301496
1497 request_dl_rlc_block(ul_tbf, fn);
1498
1499 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001500 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301501
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001502 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301503 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001504 OSMO_ASSERT(ms_ta(ms) == qta/4);
1505 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301506
1507 return ul_tbf;
1508}
1509
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001510static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301511 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1512 uint8_t ms_class, uint8_t egprs_ms_class)
1513{
1514 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301515 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001516 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301517 gprs_rlcmac_ul_tbf *ul_tbf;
1518 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301519
1520 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001521 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301522 OSMO_ASSERT(ul_tbf);
1523 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1524
1525 /* send fake data with cv=0*/
1526 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1527 uint8_t data[49] = {0};
1528
1529 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1530
1531 /*header_construction */
1532 memset(data, 0x2b, sizeof(data));
1533
1534 /* Message with CRBB */
1535 for (int i = 80 ; i < 160; i++) {
1536 hdr3->r = 0;
1537 hdr3->si = 0;
1538 hdr3->cv = 10;
1539 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1540 hdr3->tfi_lo = tfi & 0x7;
1541 hdr3->bsn1_hi = ((i)&0x1f);
1542 hdr3->bsn1_lo = ((i)/32);
1543 hdr3->cps_hi = 0;
1544 hdr3->cps_lo = 0;
1545 hdr3->spb = 0;
1546 hdr3->rsb = 0;
1547 hdr3->pi = 0;
1548 hdr3->spare = 0;
1549 hdr3->dummy = 1;
1550 data[4] = 0x0;
1551 data[5] = 0x0;
1552 data[6] = 0x2b;
1553 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001554 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301555 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1556 }
1557 ul_tbf->create_ul_ack(*fn, ts_no);
1558 memset(data, 0x2b, sizeof(data));
1559 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1560 hdr3->r = 0;
1561 hdr3->si = 0;
1562 hdr3->cv = 0;
1563 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1564 hdr3->tfi_lo = tfi & 0x7;
1565 hdr3->bsn1_hi = 0;
1566 hdr3->bsn1_lo = 2;
1567 hdr3->cps_hi = 0;
1568 hdr3->cps_lo = 0;
1569 hdr3->spb = 0;
1570 hdr3->rsb = 0;
1571 hdr3->pi = 0;
1572 hdr3->spare = 0;
1573 hdr3->dummy = 1;
1574 data[4] = 0x0;
1575 data[5] = 0x2b;
1576 data[6] = 0x2b;
1577 data[7] = 0x2b;
1578
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001579 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301580 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1581
1582 request_dl_rlc_block(ul_tbf, fn);
1583
1584 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001585 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301586
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001587 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301588 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001589 OSMO_ASSERT(ms_ta(ms) == qta/4);
1590 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301591
1592 return ul_tbf;
1593}
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001594static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001595 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001596 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001597{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001598 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001599 uint32_t rach_fn = *fn - 51;
1600 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001601 uint8_t trx_no = 0;
1602 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001603 gprs_rlcmac_ul_tbf *ul_tbf;
1604 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001605 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001606
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001607 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001608 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001609
bhargava959d1de2016-08-17 15:17:21 +05301610 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001611 bts_handle_rach(bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001612
1613 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001614 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001615
1616 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001617 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1618 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1619 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1620 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001621 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1622 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001623 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001624 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001625 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001626 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001627 MS_RA_capability_value[0].u.Content.Multislot_capability.
1628 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001629 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001630 MS_RA_capability_value[0].u.Content.Multislot_capability.
1631 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001632 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001633 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001634 MS_RA_capability_value[0].u.Content.Multislot_capability.
1635 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001636 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001637 MS_RA_capability_value[0].u.Content.Multislot_capability.
1638 EGPRS_multislot_class = ms_class;
1639 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001640
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001641 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001642
1643 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001644 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001645 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001646 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001647
1648 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001649 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001650 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001651
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001652 /* send real acknowledgement */
1653 send_control_ack(ul_tbf);
1654
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001655 check_tbf(ul_tbf);
1656
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001657 /* send fake data */
1658 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001659 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1660 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001661 uint8_t(1), /* BSN:7, E:1 */
1662 };
1663
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001664 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001665 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001666
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001667 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001668 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001669 OSMO_ASSERT(ms_ta(ms) == qta/4);
1670 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001671
1672 return ul_tbf;
1673}
1674
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001675static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001676 const uint8_t *data, unsigned data_size)
1677{
1678 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001679
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001680 ms = bts_ms_store(bts)->get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001681
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01001682 dl_tbf_handle(bts, tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001683 1000, data, data_size);
1684
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001685 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001686 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001687 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001688
1689 if (imsi[0] && strcmp(imsi, "000") != 0) {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001690 ms2 = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001691 OSMO_ASSERT(ms == ms2);
1692 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001693}
1694
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001695static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001696 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001697{
1698 gprs_rlcmac_dl_tbf *dl_tbf;
1699 GprsMs *ms;
1700 unsigned ts_no;
1701
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001702 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001703 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001704 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001705 OSMO_ASSERT(dl_tbf);
1706
1707 while (dl_tbf->have_data()) {
1708 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001709 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1710 if (!(slots & (1 << ts_no)))
1711 continue;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001712 gprs_rlcmac_rcv_rts_block(bts,
Max878bd1f2016-07-20 13:05:05 +02001713 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001714 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001715 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001716 *fn = fn_add_blocks(*fn, 1);
1717 }
1718}
1719
Max4c112dc2018-02-01 16:49:23 +01001720static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1721{
1722 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1723 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001724 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 +01001725}
1726
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001727static void test_tbf_single_phase()
1728{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001729 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001730 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001731 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001732 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001733 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001734 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001735 uint16_t qta = 31;
1736 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001737
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001738 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001739
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001740 setup_bts(bts, ts_no);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001741
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001742 ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001743
Max4c112dc2018-02-01 16:49:23 +01001744 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001745 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001746
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001747 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001748 TALLOC_FREE(the_pcu);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001749}
1750
sivasankari1d8744c2017-01-24 15:53:35 +05301751static void test_tbf_egprs_two_phase_puan(void)
1752{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001753 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001754 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
sivasankari1d8744c2017-01-24 15:53:35 +05301755 int ts_no = 7;
1756 uint32_t fn = 2654218;
1757 uint16_t qta = 31;
1758 uint32_t tlli = 0xf1223344;
1759 const char *imsi = "0011223344";
1760 uint8_t ms_class = 1;
sivasankari1d8744c2017-01-24 15:53:35 +05301761 uint8_t egprs_ms_class = 1;
1762 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301763 uint8_t test_data[256];
1764
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001765 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301766
1767 memset(test_data, 1, sizeof(test_data));
1768
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001769 setup_bts(bts, ts_no, 4);
1770 bts->initial_mcs_dl = 9;
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001771 the_pcu->vty.ws_base = 128;
1772 the_pcu->vty.ws_pdch = 64;
sivasankari1d8744c2017-01-24 15:53:35 +05301773
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001774 ul_tbf = establish_ul_tbf(bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301775 /* Function to generate URBB with no length */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001776 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301777 qta, ms_class, egprs_ms_class, ul_tbf);
1778
Max4c112dc2018-02-01 16:49:23 +01001779 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001780 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301781
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001782 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301783 /* Function to generate URBB with length */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001784 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301785 qta, ms_class, egprs_ms_class, ul_tbf);
1786
Max4c112dc2018-02-01 16:49:23 +01001787 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001788 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301789
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001790 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301791 /* Function to generate CRBB */
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001792 the_pcu->vty.ws_base = 128;
1793 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001794 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301795 qta, ms_class, egprs_ms_class);
1796
Max4c112dc2018-02-01 16:49:23 +01001797 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001798 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301799
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001800 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001801 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301802}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301803/*
1804 * Trigger rach for single block
1805 */
1806static void test_immediate_assign_rej_single_block()
1807{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001808 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001809 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301810 uint32_t fn = 2654218;
1811 uint16_t qta = 31;
1812 int ts_no = 7;
1813
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001814 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301815
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001816 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301817
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001818 bts->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301819
1820 uint32_t rach_fn = fn - 51;
1821
1822 int rc = 0;
1823
1824 /*
1825 * simulate RACH, sends an Immediate Assignment
1826 * Uplink reject on the AGCH
1827 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001828 rc = bts_handle_rach(bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301829
Pau Espin Pedrol15c58ac2021-03-08 14:57:58 +01001830 OSMO_ASSERT(rc == -EBUSY);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301831
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001832 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001833 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301834}
1835
1836/*
1837 * Trigger rach till resources(USF) exhaust
1838 */
1839static void test_immediate_assign_rej_multi_block()
1840{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001841 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001842 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301843 uint32_t fn = 2654218;
1844 uint16_t qta = 31;
1845 int ts_no = 7;
1846
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001847 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301848
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001849 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301850
1851 uint32_t rach_fn = fn - 51;
1852
1853 int rc = 0;
1854
1855 /*
1856 * simulate RACH, sends an Immediate Assignment Uplink
1857 * reject on the AGCH
1858 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001859 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
1860 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
1861 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
1862 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
1863 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
1864 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
1865 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
1866 rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301867
1868 OSMO_ASSERT(rc == -EBUSY);
1869
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001870 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001871 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301872}
1873
1874static void test_immediate_assign_rej()
1875{
1876 test_immediate_assign_rej_multi_block();
1877 test_immediate_assign_rej_single_block();
1878}
1879
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001880static void test_tbf_two_phase()
1881{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001882 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001883 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001884 int ts_no = 7;
1885 uint32_t fn = 2654218;
1886 uint16_t qta = 31;
1887 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001888 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001889 uint8_t ms_class = 1;
1890 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001891
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001892 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001893
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001894 setup_bts(bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001895
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001896 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001897 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001898
Max4c112dc2018-02-01 16:49:23 +01001899 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001900 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001901
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001902 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001903 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001904}
1905
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001906static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001907{
1908 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001909 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 +01001910}
1911
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001912static void test_tbf_ra_update_rach()
1913{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001914 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001915 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001916 int ts_no = 7;
1917 uint32_t fn = 2654218;
1918 uint16_t qta = 31;
1919 uint32_t tlli1 = 0xf1223344;
1920 uint32_t tlli2 = 0xf5667788;
1921 const char *imsi = "0011223344";
1922 uint8_t ms_class = 1;
1923 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001924 gprs_rlcmac_dl_tbf *dl_tbf;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001925 GprsMs *ms, *ms1, *ms2;
1926
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001927 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001928
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001929 setup_bts(bts, ts_no, 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001930
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001931 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001932 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001933
1934 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001935 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001936
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001937 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001938 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001939
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001940 /* Send Packet Downlink Assignment to MS */
1941 request_dl_rlc_block(ul_tbf, &fn);
1942
1943 /* Ack it */
1944 send_control_ack(ul_tbf);
1945
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001946 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001947 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001948 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001949 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001950
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001951 dl_tbf = ms_dl_tbf(ms1);
1952 OSMO_ASSERT(dl_tbf);
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02001953 fn = get_poll_fn(dl_tbf, dl_tbf->control_ts);
1954 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01001955 fn = fn_add_blocks(fn, 1);
1956
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001957 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001958 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001959 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001960
1961 ms2 = ul_tbf->ms();
1962
1963 /* The PCU cannot know yet, that both TBF belong to the same MS */
1964 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01001965 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001966
1967 /* Send some downlink data along with the new TLLI and the IMSI so that
1968 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001969 send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001970
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001971 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001972 OSMO_ASSERT(ms == ms2);
1973
Max4c112dc2018-02-01 16:49:23 +01001974 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001975
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001976 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001977 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001978 ms = bts_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001979 OSMO_ASSERT(ms == ms2);
1980
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001981 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001982 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001983}
1984
1985static void test_tbf_dl_flow_and_rach_two_phase()
1986{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02001987 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001988 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001989 int ts_no = 7;
1990 uint32_t fn = 2654218;
1991 uint16_t qta = 31;
1992 uint32_t tlli1 = 0xf1223344;
1993 const char *imsi = "0011223344";
1994 uint8_t ms_class = 1;
1995 gprs_rlcmac_ul_tbf *ul_tbf;
1996 gprs_rlcmac_dl_tbf *dl_tbf;
1997 GprsMs *ms, *ms1, *ms2;
1998
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001999 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002000
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002001 setup_bts(bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002002
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002003 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002004 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002005
2006 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002007 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002008
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002009 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2010 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002011 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002012
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002013 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2014 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002015 OSMO_ASSERT(dl_tbf != NULL);
2016
2017 /* Get rid of old UL TBF */
2018 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002019 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002020 OSMO_ASSERT(ms1 == ms);
2021
2022 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002023 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002024 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002025
2026 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002027 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002028
2029 /* This should be the same MS object */
2030 OSMO_ASSERT(ms2 == ms1);
2031
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002032 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002033 OSMO_ASSERT(ms2 == ms);
2034
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002035 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002036 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002037
2038 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002039 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002040
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002041 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002042 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002043}
2044
2045
2046static void test_tbf_dl_flow_and_rach_single_phase()
2047{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002048 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002049 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002050 int ts_no = 7;
2051 uint32_t fn = 2654218;
2052 uint16_t qta = 31;
2053 uint32_t tlli1 = 0xf1223344;
2054 const char *imsi = "0011223344";
2055 uint8_t ms_class = 1;
2056 gprs_rlcmac_ul_tbf *ul_tbf;
2057 gprs_rlcmac_dl_tbf *dl_tbf;
2058 GprsMs *ms, *ms1, *ms2;
2059
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002060 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002061
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002062 setup_bts(bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002063
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002064 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002065 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002066
2067 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002068 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002069
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002070 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2071 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002072 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002073
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002074 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2075 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002076 OSMO_ASSERT(dl_tbf != NULL);
2077
2078 /* Get rid of old UL TBF */
2079 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002080 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002081 OSMO_ASSERT(ms1 == ms);
2082
2083 /* Now establish a new UL TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002084 ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002085
2086 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002087 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002088
2089 /* There should be a different MS object */
2090 OSMO_ASSERT(ms2 != ms1);
2091
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002092 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002093 OSMO_ASSERT(ms2 == ms);
2094 OSMO_ASSERT(ms1 != ms);
2095
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002096 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002097 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002098
2099 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002100 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002101
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002102 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002103 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002104}
2105
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002106static void test_tbf_dl_reuse()
2107{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002108 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002109 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002110 int ts_no = 7;
2111 uint32_t fn = 2654218;
2112 uint16_t qta = 31;
2113 uint32_t tlli1 = 0xf1223344;
2114 const char *imsi = "0011223344";
2115 uint8_t ms_class = 1;
2116 gprs_rlcmac_ul_tbf *ul_tbf;
2117 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2118 GprsMs *ms1, *ms2;
2119 unsigned i;
2120 RlcMacUplink_t ulreq = {0};
2121
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002122 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002123
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002124 setup_bts(bts, ts_no, 1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002125
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002126 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002127 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002128
2129 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002130 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002131
2132 /* Send some LLC frames */
2133 for (i = 0; i < 40; i++) {
2134 char buf[32];
2135 int rc;
2136
2137 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2138 OSMO_ASSERT(rc > 0);
2139
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002140 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002141 }
2142
Max4c112dc2018-02-01 16:49:23 +01002143 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002144
2145 /* Send Packet Downlink Assignment to MS */
2146 request_dl_rlc_block(ul_tbf, &fn);
2147
2148 /* Ack it */
2149 send_control_ack(ul_tbf);
2150
2151 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002152 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002153 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2154 OSMO_ASSERT(ms_dl_tbf(ms1));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002155 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002156
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002157 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002158
2159 /* Send some LLC frames */
2160 for (i = 0; i < 10; i++) {
2161 char buf[32];
2162 int rc;
2163
2164 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2165 OSMO_ASSERT(rc > 0);
2166
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002167 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002168 }
2169
2170 /* Fake Final DL Ack/Nack */
2171 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2172 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2173
2174 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2175 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2176 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2177
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002178 send_ul_mac_block(bts, 0, dl_tbf1->control_ts, &ulreq, get_poll_fn(dl_tbf1, dl_tbf1->control_ts));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002179
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002180 OSMO_ASSERT(dl_tbf1->state_is(TBF_ST_WAIT_RELEASE));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002181
2182 request_dl_rlc_block(dl_tbf1, &fn);
2183
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002184 ms2 = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002185 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002186 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002187 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002188
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002189 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002190
2191 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2192
2193 send_control_ack(dl_tbf1);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002194 OSMO_ASSERT(dl_tbf2->state_is(TBF_ST_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002195
2196 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002197 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002198 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2199 OSMO_ASSERT(ms_dl_tbf(ms2));
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002200 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002201
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002202 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002203 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002204}
2205
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002206static void test_tbf_gprs_egprs()
2207{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002208 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002209 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002210 uint8_t ts_no = 4;
2211 uint8_t ms_class = 45;
2212 int rc = 0;
2213 uint32_t tlli = 0xc0006789;
2214 const char *imsi = "001001123456789";
2215 unsigned delay_csec = 1000;
2216
2217 uint8_t buf[256] = {0};
2218
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002219 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002220
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002221 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2222 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002223 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2224 abort();
2225 }
2226
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002227 setup_bts(bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002228
2229 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002230
Alexander Couzens290d9032020-09-16 21:52:02 +02002231 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002232
2233 /* Does not support EGPRS */
Pau Espin Pedrol8a35e642021-01-18 17:14:14 +01002234 rc = dl_tbf_handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002235 delay_csec, buf, sizeof(buf));
2236
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002237 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002238 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002239
Alexander Couzens290d9032020-09-16 21:52:02 +02002240 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002241 TALLOC_FREE(the_pcu);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002242}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002243
Max4c112dc2018-02-01 16:49:23 +01002244static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
2245 bool free, bool end)
2246{
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002247 gprs_rlcmac_bts *bts = dl_tbf->bts;
Max4c112dc2018-02-01 16:49:23 +01002248 if (!dl_tbf) {
2249 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2250 return;
2251 }
2252
2253 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2254 dl_tbf->dl_slots(),
2255 pcu_bitcount(dl_tbf->dl_slots()),
2256 dl_tbf->window_size());
2257
2258 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2259 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2260 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2261
2262 fprintf(stderr, "\n");
2263
2264 if (free)
2265 tbf_free(dl_tbf);
2266
2267 if (end) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002268 fprintf(stderr, "=== end %s ===\n", test);
Alexander Couzens290d9032020-09-16 21:52:02 +02002269 gprs_bssgp_destroy(bts);
Max4c112dc2018-02-01 16:49:23 +01002270 }
2271}
2272
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002273static void test_tbf_ws()
2274{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002275 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002276 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002277 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002278 uint8_t ts_no = 4;
2279 uint8_t ms_class = 12;
2280 gprs_rlcmac_dl_tbf *dl_tbf;
2281
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002282 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002283
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002284 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2285 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002286 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2287 abort();
2288 }
2289
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002290 setup_bts(bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002291
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002292 the_pcu->vty.ws_base = 128;
2293 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002294 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002295 bts->trx[0].pdch[2].enable();
2296 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002297 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts() */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002298 bts->trx[0].pdch[5].enable();
2299
Alexander Couzens290d9032020-09-16 21:52:02 +02002300 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002301
2302 /* Does no support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002303 ms = bts_alloc_ms(bts, ms_class, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002304 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002305
2306 ws_check(dl_tbf, __func__, 4, 64, true, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002307
2308 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002309
2310 /* Does support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002311 ms = bts_alloc_ms(bts, ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002312 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002313
Max4c112dc2018-02-01 16:49:23 +01002314 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002315 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002316}
2317
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302318static void test_tbf_update_ws(void)
2319{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002320 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002321 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002322 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302323 uint8_t ts_no = 4;
2324 uint8_t ms_class = 11;
2325 gprs_rlcmac_dl_tbf *dl_tbf;
2326
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002327 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302328
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002329 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2330 if (!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 Pedrol2182e622021-01-14 16:48:38 +01002335 setup_bts(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();
Pau Espin Pedrol4f67a9b2021-06-30 16:03:06 +02002342 /* bts->trx[0].pdch[4].enable(); Already enabled during setup_bts()) */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302343 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 Pedrol2182e622021-01-14 16:48:38 +01002350 ms = bts_alloc_ms(bts, 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 Pedrol945be912021-07-26 14:47:46 +02002364 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002365 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302366 int ts_no = 7;
2367 uint32_t fn = 2654218;
2368 uint16_t qta = 31;
2369 uint32_t tlli = 0xf1223344;
2370 const char *imsi = "0011223344";
2371 uint8_t ms_class = 1;
2372 uint8_t egprs_ms_class = 1;
2373 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302374 uint8_t test_data[256];
2375
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002376 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302377
2378 memset(test_data, 1, sizeof(test_data));
2379
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002380 setup_bts(bts, ts_no, 4);
2381 bts->initial_mcs_dl = 9;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302382
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002383 ul_tbf = puan_urbb_len_issue(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302384 ms_class, egprs_ms_class);
2385
Max4c112dc2018-02-01 16:49:23 +01002386 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002387 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302388
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002389 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002390 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302391}
2392
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002393static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302394 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2395 uint8_t ms_class, uint8_t egprs_ms_class)
2396{
2397 GprsMs *ms;
2398 uint32_t rach_fn = *fn - 51;
2399 uint32_t sba_fn = *fn + 52;
2400 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002401 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302402 gprs_rlcmac_ul_tbf *ul_tbf;
2403 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302404 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302405 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302406 Packet_Resource_Request_t *presreq = NULL;
2407 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2408 Multislot_capability_t *pmultislotcap = NULL;
2409
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302410 /* needed to set last_rts_fn in the PDCH object */
2411 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2412
2413 /*
2414 * simulate RACH, this sends an Immediate
2415 * Assignment Uplink on the AGCH
2416 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002417 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302418
2419 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002420 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302421
2422 /* fake a resource request */
2423 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2424 presreq = &ulreq.u.Packet_Resource_Request;
2425 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2426 presreq->ID.UnionType = 1; /* != 0 */
2427 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002428 presreq->Exist_MS_Radio_Access_capability2 = 1;
2429 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302430 pmsradiocap->Count_MS_RA_capability_value = 1;
2431 pmsradiocap->MS_RA_capability_value[0].u.Content.
2432 Exist_Multislot_capability = 1;
2433 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2434 u.Content.Multislot_capability;
2435
2436 pmultislotcap->Exist_GPRS_multislot_class = 1;
2437 pmultislotcap->GPRS_multislot_class = ms_class;
2438 if (egprs_ms_class) {
2439 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2440 pmultislotcap->EGPRS_multislot_class = ms_class;
2441 }
2442
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002443 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302444
2445 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002446 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302447 OSMO_ASSERT(ul_tbf);
2448 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2449
2450 /* send packet uplink assignment */
2451 *fn = sba_fn;
2452 request_dl_rlc_block(ul_tbf, fn);
2453
2454 /* send real acknowledgement */
2455 send_control_ack(ul_tbf);
2456
2457 check_tbf(ul_tbf);
2458
2459 uint8_t data_msg[49] = {0};
2460
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002461 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302462
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002463 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302464 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002465 OSMO_ASSERT(ms_ta(ms) == qta/4);
2466 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302467
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302468 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2469 egprs3->si = 0;
2470 egprs3->r = 1;
2471 egprs3->cv = 7;
2472 egprs3->tfi_hi = tfi & 0x03;
2473 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2474 egprs3->bsn1_hi = 0;
2475 egprs3->bsn1_lo = 0;
2476 egprs3->cps_hi = 1;
2477 data_msg[3] = 0xff;
2478 egprs3->pi = 0;
2479 egprs3->cps_lo = 1;
2480 egprs3->rsb = 0;
2481 egprs3->spb = 0;
2482 egprs3->pi = 0;
2483 pdch->rcv_block(data_msg, 49, *fn, &meas);
2484
2485 egprs3->bsn1_hi = 1;
2486 egprs3->bsn1_lo = 0;
2487 data_msg[3] = 0x7f;
2488 egprs3->cps_lo = 1;
2489 egprs3->rsb = 0;
2490 egprs3->spb = 0;
2491 egprs3->pi = 0;
2492 data_msg[4] = 0x2;
2493 data_msg[5] = 0x0;
2494 pdch->rcv_block(data_msg, 49, *fn, &meas);
2495
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302496 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302497
2498 return ul_tbf;
2499}
2500
2501static void test_tbf_li_decoding(void)
2502{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002503 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002504 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302505 int ts_no = 7;
2506 uint32_t fn = 2654218;
2507 uint16_t qta = 31;
2508 uint32_t tlli = 0xf1223344;
2509 const char *imsi = "0011223344";
2510 uint8_t ms_class = 1;
2511 uint8_t egprs_ms_class = 1;
2512 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302513 uint8_t test_data[256];
2514
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002515 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302516
2517 memset(test_data, 1, sizeof(test_data));
2518
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002519 setup_bts(bts, ts_no, 4);
2520 bts->initial_mcs_dl = 9;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302521
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002522 ul_tbf = tbf_li_decoding(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302523 ms_class, egprs_ms_class);
2524
Max4c112dc2018-02-01 16:49:23 +01002525 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002526 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302527
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002528 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002529 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302530}
2531
aravind sirsikarf2761382016-10-25 12:45:24 +05302532/*
2533 * Test that a bit within the uncompressed bitmap whose BSN is not within
2534 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2535 * version 7.27.0 Release 7.
2536 */
2537static void test_tbf_epdan_out_of_rx_window(void)
2538{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002539 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002540 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302541 uint8_t ms_class = 11;
2542 uint8_t egprs_ms_class = 11;
2543 uint8_t trx_no;
2544 uint32_t tlli = 0xffeeddcc;
2545 gprs_rlcmac_dl_tbf *dl_tbf;
2546 int ts_no = 4;
2547 bitvec *block;
2548 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2549 bitvec bits;
2550 int bsn_begin, bsn_end;
2551 EGPRS_PD_AckNack_t *ack_nack;
2552 RlcMacUplink_t ul_control_block;
2553 gprs_rlc_v_b *prlcmvb;
2554 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002555 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302556
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302557 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2558
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002559 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302560
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002561 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002562 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302563 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002564 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302565
2566 /*
2567 * Simulate a message captured during over-the-air testing,
2568 * where the following values were observed:
2569 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2570 */
2571 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2572 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2573 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2575
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002576 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
aravind sirsikarf2761382016-10-25 12:45:24 +05302577 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002578 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302579 prlcmvb = &prlcdlwindow->m_v_b;
2580 prlcdlwindow->m_v_s = 1288;
2581 prlcdlwindow->m_v_a = 1176;
2582 prlcdlwindow->set_sns(2048);
2583 prlcdlwindow->set_ws(480);
2584 prlcmvb->mark_unacked(1176);
2585 prlcmvb->mark_unacked(1177);
2586 prlcmvb->mark_unacked(1286);
2587 prlcmvb->mark_unacked(1287);
2588
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002589 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
aravind sirsikarf2761382016-10-25 12:45:24 +05302590
Alexander Couzensccde5c92017-02-04 03:10:08 +01002591 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302592
2593 bitvec_unpack(block, data_msg);
2594
2595 bits.data = bits_data;
2596 bits.data_len = sizeof(bits_data);
2597 bits.cur_bit = 0;
2598
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002599 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2600 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302601
2602 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2603
2604 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2605 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2606 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2607 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2608
2609 Decoding::decode_egprs_acknack_bits(
2610 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002611 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302612
2613 dl_tbf->rcvd_dl_ack(
2614 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2615 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302616
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302617 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2618 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2619 OSMO_ASSERT(prlcmvb->is_acked(1286));
2620 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302621
2622 bitvec_free(block);
2623 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002624 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002625 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302626}
2627
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302628static void test_tbf_egprs_two_phase_spb(void)
2629{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002630 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002631 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302632 int ts_no = 7;
2633 uint32_t fn = 2654218;
2634 uint16_t qta = 31;
2635 uint32_t tlli = 0xf1223344;
2636 const char *imsi = "0011223344";
2637 uint8_t ms_class = 1;
2638 uint8_t egprs_ms_class = 1;
2639 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302640 uint8_t test_data[256];
2641
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002642 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302643
2644 memset(test_data, 1, sizeof(test_data));
2645
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002646 setup_bts(bts, ts_no, 4);
2647 bts->initial_mcs_dl = 9;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302648
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002649 ul_tbf = establish_ul_tbf_two_phase_spb(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302650 ms_class, egprs_ms_class);
2651
Max4c112dc2018-02-01 16:49:23 +01002652 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002653 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302654
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002655 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002656 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302657}
2658
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002659static void test_tbf_egprs_two_phase()
2660{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02002661 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01002662 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002663 int ts_no = 7;
2664 uint32_t fn = 2654218;
2665 uint16_t qta = 31;
2666 uint32_t tlli = 0xf1223344;
2667 const char *imsi = "0011223344";
2668 uint8_t ms_class = 1;
2669 uint8_t egprs_ms_class = 1;
2670 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002671 uint8_t test_data[256];
2672
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002673 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002674
2675 memset(test_data, 1, sizeof(test_data));
2676
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002677 setup_bts(bts, ts_no, 4);
2678 bts->initial_mcs_dl = 9;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002679
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002680 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002681 ms_class, egprs_ms_class);
2682
Max4c112dc2018-02-01 16:49:23 +01002683 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002684 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002685
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002686 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002687 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002688}
2689
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002690static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002691{
2692 unsigned i;
2693 uint8_t ms_class = 11;
2694 uint8_t egprs_ms_class = 11;
2695 uint32_t fn = 0;
2696 uint8_t trx_no;
2697 uint32_t tlli = 0xffeeddcc;
2698 uint8_t test_data[512];
2699
2700 uint8_t rbb[64/8];
2701
2702 gprs_rlcmac_dl_tbf *dl_tbf;
2703
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002704 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002705
2706 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002707 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002708
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002709 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002710 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2711
2712 for (i = 0; i < sizeof(llc_data); i++)
2713 llc_data[i] = i%256;
2714
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002715 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002716
2717 /* Schedule a small LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002718 dl_tbf->append_data(1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002719
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002720 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002721
2722 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002723 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002724 /* Request to send one RLC/MAC block */
2725 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002726 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002727 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002728
2729 /* Schedule a large LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002730 dl_tbf->append_data(1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002731
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002732 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002733
2734 /* Drain the queue */
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002735 while (dl_tbf->have_data()) {
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002736 /* Request to send one RLC/MAC block */
2737 request_dl_rlc_block(dl_tbf, &fn);
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01002738 }
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02002739 send_empty_block(dl_tbf, dl_tbf->control_ts, fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002740
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002741 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002742
Max7d32f552017-12-15 11:25:14 +01002743 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002744
2745 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002746 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002747 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002748 check_tbf(dl_tbf);
2749 tbf_free(dl_tbf);
2750}
2751
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002752static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302753 int mcs)
2754{
2755 unsigned i;
2756 uint8_t ms_class = 11;
2757 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302758 uint8_t trx_no;
2759 uint32_t tlli = 0xffeeddcc;
2760 uint8_t test_data[512];
2761
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302762 gprs_rlcmac_dl_tbf *dl_tbf;
2763
2764 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002765 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302766
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002767 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302768 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2769
2770 for (i = 0; i < sizeof(test_data); i++)
2771 test_data[i] = i%256;
2772
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002773 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302774
2775 /* Schedule a LLC frame
2776 * passing only 100 bytes, since it is enough to construct
2777 * 2 RLC data blocks. Which are enough to test Header Type 1
2778 * cases
2779 */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002780 dl_tbf->append_data(1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302781
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002782 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302783
2784 return dl_tbf;
2785
2786}
2787
2788static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2789{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302790 uint8_t rbb[64/8];
2791
Max7d32f552017-12-15 11:25:14 +01002792 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302793
2794 /* Clean up and ensure tbfs are in the correct state */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02002795 OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002796 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302797 check_tbf(dl_tbf);
2798 tbf_free(dl_tbf);
2799
2800}
2801
Max7d32f552017-12-15 11:25:14 +01002802#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002803 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2804 w->m_v_b.mark_nacked(x); \
2805 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002806 } while(0)
2807
2808#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002809 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2810 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002811 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002812 } while(0)
2813
2814#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002815 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2816 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002817 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002818 } while(0)
2819
2820#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
2821 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
2822 OSMO_ASSERT(m); \
2823 if (check_unacked) \
2824 CHECK_UNACKED(tbf, cs, 0); \
2825 else \
2826 CHECK_NACKED(tbf, cs, 0); \
2827 } while(0)
2828
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002829static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002830 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302831{
2832 uint32_t fn = 0;
2833 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302834 uint16_t bsn1, bsn2, bsn3;
2835 struct msgb *msg;
2836 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2837 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2838
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002839 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302840
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002841 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302842
2843 /*
2844 * Table 10.4.8a.3.1 of 44.060.
2845 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2846 * (MCS5, MCS6) to (MCS2, MCS3) transition
2847 */
2848 if (!(mcs == 6 && demanded_mcs == 3))
2849 return;
2850
2851 fn = fn_add_blocks(fn, 1);
2852 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002853 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302854
2855 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01002856 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01002857
2858 NACK(dl_tbf, 0);
2859
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302860 OSMO_ASSERT(bsn1 == 0);
2861
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002862 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302863
2864 fn = fn_add_blocks(fn, 1);
2865
2866 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002867 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302868 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2869 == EGPRS_RESEG_FIRST_SEG_SENT);
2870
2871 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2872 OSMO_ASSERT(egprs3->spb == 2);
2873
2874 /* Table 10.4.8a.3.1 of 44.060 */
2875 OSMO_ASSERT(egprs3->cps == 3);
2876
2877 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002878 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302879 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2880 == EGPRS_RESEG_SECOND_SEG_SENT);
2881
2882 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2883 /* Table 10.4.8a.3.1 of 44.060 */
2884 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01002885 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302886 OSMO_ASSERT(bsn2 == bsn1);
2887
2888 /* Table 10.4.8a.3.1 of 44.060 */
2889 OSMO_ASSERT(egprs3->cps == 3);
2890
2891 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002892 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302893
Max7d32f552017-12-15 11:25:14 +01002894 NACK(dl_tbf, 0);
2895
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302896 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2897 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2898
2899 /* Table 10.4.8a.3.1 of 44.060 */
2900 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01002901 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302902 OSMO_ASSERT(bsn3 == bsn2);
2903
2904 tbf_cleanup(dl_tbf);
2905}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002906
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002907static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002908 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302909{
2910 uint32_t fn = 0;
2911 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302912 struct msgb *msg;
2913 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2914
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002915 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302916
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002917 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302918
2919 /*
2920 * Table 10.4.8a.3.1 of 44.060.
2921 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2922 * (MCS5, MCS6) to (MCS2, MCS3) transition
2923 */
2924 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2925 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2926 * dated 2016-02-07 23:45:40 (UTC)
2927 */
2928 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2929 ((mcs == 6) && (demanded_mcs == 3)) ||
2930 ((mcs == 4) && (demanded_mcs == 1))))
2931 return;
2932
2933 fn = fn_add_blocks(fn, 1);
2934 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002935 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302936
Max7d32f552017-12-15 11:25:14 +01002937 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302938
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002939 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302940
2941 fn = fn_add_blocks(fn, 1);
2942
2943 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002944 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302945 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2946 == EGPRS_RESEG_FIRST_SEG_SENT);
2947
2948 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2949 OSMO_ASSERT(egprs3->spb == 2);
2950
2951 /* Table 10.4.8a.3.1 of 44.060 */
2952 switch (demanded_mcs) {
2953 case 3:
2954 OSMO_ASSERT(egprs3->cps == 3);
2955 break;
2956 case 2:
2957 OSMO_ASSERT(egprs3->cps == 9);
2958 break;
2959 case 1:
2960 OSMO_ASSERT(egprs3->cps == 11);
2961 break;
2962 default:
2963 OSMO_ASSERT(false);
2964 break;
2965 }
2966
2967 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002968 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302969 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2970 == EGPRS_RESEG_SECOND_SEG_SENT);
2971
2972 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2973 /* Table 10.4.8a.3.1 of 44.060 */
2974 OSMO_ASSERT(egprs3->spb == 3);
2975
2976 /* Table 10.4.8a.3.1 of 44.060 */
2977 switch (demanded_mcs) {
2978 case 3:
2979 OSMO_ASSERT(egprs3->cps == 3);
2980 break;
2981 case 2:
2982 OSMO_ASSERT(egprs3->cps == 9);
2983 break;
2984 case 1:
2985 OSMO_ASSERT(egprs3->cps == 11);
2986 break;
2987 default:
2988 OSMO_ASSERT(false);
2989 break;
2990 }
2991 tbf_cleanup(dl_tbf);
2992}
2993
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002994static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002995 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302996{
2997 uint32_t fn = 0;
2998 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302999 struct msgb *msg;
3000
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003001 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303002
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003003 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303004
3005 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
3006 * The MCS transition are referred from table Table 8.1.1.2
3007 * of TS 44.060
3008 */
3009 /* TODO: Need to support of MCS8 -> MCS6 transistion
3010 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
3011 * dated 2016-02-07 23:45:40 (UTC)
3012 */
3013 if (((mcs == 9) && (demanded_mcs < 9)) ||
3014 ((mcs == 7) && (demanded_mcs < 7))) {
3015 fn = fn_add_blocks(fn, 1);
3016 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01003017 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3018 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303019
Max7d32f552017-12-15 11:25:14 +01003020 NACK(dl_tbf, 0);
3021 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303022
3023 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003024 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303025
3026 fn = fn_add_blocks(fn, 1);
3027 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003028 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3029 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303030
3031 fn = fn_add_blocks(fn, 1);
3032 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003033 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3034 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303035 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3036 ((mcs == 6) && (demanded_mcs > 8))) {
3037 fn = fn_add_blocks(fn, 1);
3038 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003039 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303040
3041 fn = fn_add_blocks(fn, 1);
3042 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003043 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3044 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303045
Max7d32f552017-12-15 11:25:14 +01003046 NACK(dl_tbf, 0);
3047 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303048
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003049 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303050
3051 fn = fn_add_blocks(fn, 1);
3052 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003053 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3054 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303055 } else if (mcs > 6) {
3056 /* No Mcs change cases are handled here for mcs > MCS6*/
3057 fn = fn_add_blocks(fn, 1);
3058 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003059 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3060 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303061
Max7d32f552017-12-15 11:25:14 +01003062 NACK(dl_tbf, 0);
3063 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303064
3065 fn = fn_add_blocks(fn, 1);
3066 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003067 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3068 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303069 } else {
3070
3071 /* No MCS change cases are handled here for mcs <= MCS6*/
3072 fn = fn_add_blocks(fn, 1);
3073 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003074 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303075
Max7d32f552017-12-15 11:25:14 +01003076 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303077
3078 fn = fn_add_blocks(fn, 1);
3079 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003080 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303081 }
Pau Espin Pedrol99360a32021-03-09 17:18:12 +01003082 /* Clean up pending items in UL controller: */
Pau Espin Pedrol16e16782021-03-29 19:10:19 +02003083 send_empty_block(dl_tbf, dl_tbf->control_ts, fn+50);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303084 tbf_cleanup(dl_tbf);
3085}
3086
3087static void test_tbf_egprs_retx_dl(void)
3088{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003089 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003090 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303091 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303092
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003093 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303094
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003095 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003096 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003097 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303098 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003099 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303100
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303101
3102 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003103 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3104 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3105 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3106 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3107 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3108 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3109 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303110
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003111 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003112 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303113}
3114
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303115static void test_tbf_egprs_spb_dl(void)
3116{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003117 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003118 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303119 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303120
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003121 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303122
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003123 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003124 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003125 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303126
3127 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003128 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303129
3130 /*
3131 * First parameter is current MCS, second one is demanded_mcs
3132 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3133 * rest scenarios has been integration tested
3134 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003135 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3136 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3137 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303138 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003139 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303140
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003141 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003142 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303143}
3144
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003145static void test_tbf_egprs_dl()
3146{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003147 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003148 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003149 uint8_t ts_no = 4;
3150 int i;
3151
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003152 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003153
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003154 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003155 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303156 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003157 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003158
3159 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003160 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003161
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003162 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003163 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003164}
3165
3166
3167
aravind sirsikare9a138e2017-01-24 12:36:08 +05303168static void test_packet_access_rej_prr_no_other_tbfs()
3169{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003170 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003171 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303172 uint32_t fn = 2654218;
3173 int ts_no = 7;
3174 uint8_t trx_no = 0;
3175 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003176 struct gprs_rlcmac_ul_tbf *ul_tbf;
3177 struct GprsMs *ms;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303178
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003179 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303180
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003181 setup_bts(bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303182
3183 int rc = 0;
3184
Pau Espin Pedrol54742f22021-04-26 16:48:34 +02003185 ms = bts_alloc_ms(bts, 0, 0);
3186 ms_set_tlli(ms, tlli);
3187 ul_tbf = handle_tbf_reject(bts, ms, trx_no, ts_no);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303188
3189 OSMO_ASSERT(ul_tbf != 0);
3190
3191 /* trigger packet access reject */
3192 uint8_t bn = fn2bn(fn);
3193
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003194 rc = gprs_rlcmac_rcv_rts_block(bts,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303195 trx_no, ts_no, fn, bn);
3196
3197 OSMO_ASSERT(rc == 0);
3198
3199 ul_tbf->handle_timeout();
3200
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003201 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003202 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303203}
3204
3205static void test_packet_access_rej_prr()
3206{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003207 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003208 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303209 uint32_t fn = 2654218;
3210 uint16_t qta = 31;
3211 int ts_no = 7;
3212 uint8_t trx_no = 0;
3213 RlcMacUplink_t ulreq = {0};
3214 Packet_Resource_Request_t *presreq = NULL;
3215 uint8_t ms_class = 11;
3216 uint8_t egprs_ms_class = 11;
3217 uint32_t rach_fn = fn - 51;
3218 uint32_t sba_fn = fn + 52;
3219 uint32_t tlli = 0xffeeddcc;
3220 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3221 Multislot_capability_t *pmultislotcap = NULL;
3222
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003223 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303224
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003225 setup_bts(bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303226
3227 int rc = 0;
3228
3229 /*
3230 * Trigger rach till resources(USF) exhaust
3231 */
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003232 int i;
3233 for (i = 0; i < 8; i++) {
3234 rc = bts_handle_rach(bts, 0x70 + i, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303235 }
3236
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003237 sba_fn = 52;
3238 for (i = 0; i < 8; i++) {
3239 /* fake a resource request */
3240 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3241 presreq = &ulreq.u.Packet_Resource_Request;
3242 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3243 presreq->ID.UnionType = 1; /* != 0 */
3244 presreq->ID.u.TLLI = tlli + i;
3245 presreq->Exist_MS_Radio_Access_capability2 = 1;
3246 pmsradiocap = &presreq->MS_Radio_Access_capability2;
3247 pmsradiocap->Count_MS_RA_capability_value = 1;
3248 pmsradiocap->MS_RA_capability_value[0].u.Content.
3249 Exist_Multislot_capability = 1;
3250 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3251 u.Content.Multislot_capability;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303252
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003253 pmultislotcap->Exist_GPRS_multislot_class = 1;
3254 pmultislotcap->GPRS_multislot_class = ms_class;
3255 if (egprs_ms_class) {
3256 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3257 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3258 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303259
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003260 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
3261 sba_fn = fn_next_block(sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303262
Pau Espin Pedrol43479972021-04-22 19:18:13 +02003263 /* trigger packet access reject */
3264 uint8_t bn = fn2bn(fn);
3265
3266 rc = gprs_rlcmac_rcv_rts_block(bts,
3267 trx_no, ts_no, fn, bn);
3268 OSMO_ASSERT(rc == 0);
3269 }
aravind sirsikare9a138e2017-01-24 12:36:08 +05303270
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003271 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003272 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303273}
3274
aravind sirsikared3413e2016-11-11 17:15:10 +05303275void test_packet_access_rej_epdan()
3276{
Pau Espin Pedrol945be912021-07-26 14:47:46 +02003277 the_pcu = prepare_pcu();
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01003278 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
aravind sirsikared3413e2016-11-11 17:15:10 +05303279 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2ab840a2021-04-26 17:49:05 +02003280 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x7e, 0xab,
Maxd3a0d912019-03-05 16:15:01 +01003281 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3282 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3283 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303284
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003285 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003286 setup_bts(bts, 4);
3287 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303288
3289 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3290
3291 struct msgb *msg = dl_tbf->create_packet_access_reject();
3292
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003293 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303294 osmo_hexdump(msg->data, 23));
3295
Maxd3a0d912019-03-05 16:15:01 +01003296 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003297 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003298
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003299 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003300 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303301}
3302
3303
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003304int main(int argc, char **argv)
3305{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003306 struct vty_app_info pcu_vty_info = {0};
3307
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003308 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3309 if (!tall_pcu_ctx)
3310 abort();
3311
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003312 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003313 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003314 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01003315 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01003316 log_set_print_category(osmo_stderr_target, 0);
3317 log_set_print_category_hex(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003318 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003319 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003320 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +02003321 osmo_fsm_log_addr(false);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003322 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003323 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003324
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003325 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003326 pcu_l1_meas_set_link_qual(&meas, 12);
3327 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003328
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003329 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003330 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003331 test_tbf_final_ack(TEST_MODE_STANDARD);
3332 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003333 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003334 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003335 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003336 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003337 test_tbf_single_phase();
3338 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003339 test_tbf_ra_update_rach();
3340 test_tbf_dl_flow_and_rach_two_phase();
3341 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003342 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003343 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003344 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003345 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303346 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003347 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303348 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303349 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303350 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303351 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303352 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303353 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303354 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303355 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303356 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303357 test_packet_access_rej_prr();
3358 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003359
3360 if (getenv("TALLOC_REPORT_FULL"))
3361 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003362 return EXIT_SUCCESS;
3363}
3364
3365/*
3366 * stubs that should not be reached
3367 */
3368extern "C" {
3369void l1if_pdch_req() { abort(); }
3370void l1if_connect_pdch() { abort(); }
3371void l1if_close_pdch() { abort(); }
3372void l1if_open_pdch() { abort(); }
3373}