blob: ef268629c7820d58b2695a8275f4683f57838e29 [file] [log] [blame]
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01001/*
2 * TbfTest.cpp
3 *
4 * Copyright (C) 2013 by Holger Hans Peter Freyther
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include "bts.h"
24#include "tbf.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010025#include "tbf_dl.h"
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020026#include "tbf_ul.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010027#include "gprs_ms.h"
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010028#include "gprs_debug.h"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010029#include "gprs_ms_storage.h"
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +010030#include "pcu_utils.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020031#include "gprs_bssgp_pcu.h"
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +020032#include "pcu_l1_if.h"
aravind sirsikarf2761382016-10-25 12:45:24 +053033#include "decoding.h"
Max1187a772018-01-26 13:31:42 +010034#include <gprs_rlcmac.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010035
36extern "C" {
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020037#include "pcu_vty.h"
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020038#include "coding_scheme.h"
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020039
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010040#include <osmocom/core/application.h>
41#include <osmocom/core/msgb.h>
42#include <osmocom/core/talloc.h>
43#include <osmocom/core/utils.h>
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020044#include <osmocom/vty/vty.h>
Aravind Sirsikar505a86d2016-07-26 18:26:21 +053045#include <osmocom/gprs/protocol/gsm_04_60.h>
bhargava959d1de2016-08-17 15:17:21 +053046#include <osmocom/gsm/l1sap.h>
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010047}
48
Jacob Erlbeckd58b7112015-04-09 19:17:21 +020049#include <errno.h>
50
Philippd935d882016-11-07 13:07:36 +010051#define DUMMY_FN 2654167
52
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010053void *tall_pcu_ctx;
54int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010055bool spoof_mnc_3_digits = false;
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010056
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +070057/* Measurements shared by all unit tests */
58static struct pcu_l1_meas meas;
59
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010060static int bts_handle_rach(struct gprs_rlcmac_bts *bts, uint16_t ra, uint32_t Fn, int16_t qta)
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070061{
62 struct rach_ind_params rip = {
63 .burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
64 .is_11bit = false,
65 .ra = ra,
66 .trx_nr = 0,
67 .ts_nr = 0,
68 .rfn = Fn,
69 .qta = qta,
70 };
71
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010072 return bts_rcv_rach(bts, &rip);
Vadim Yanitskiya0a0b7f2020-05-21 19:55:46 +070073}
74
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010075static void check_tbf(gprs_rlcmac_tbf *tbf)
76{
77 OSMO_ASSERT(tbf);
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020078 if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE))
Maxee5be3a2017-12-20 17:31:13 +010079 OSMO_ASSERT(tbf->timers_pending(T3191) || tbf->timers_pending(T3193));
Jacob Erlbeck04e72d32015-08-13 18:36:56 +020080 if (tbf->state_is(GPRS_RLCMAC_RELEASING))
Maxee5be3a2017-12-20 17:31:13 +010081 OSMO_ASSERT(tbf->timers_pending(T_MAX));
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +010082}
83
Jacob Erlbeckac89a552015-06-29 14:18:46 +020084static void test_tbf_base()
85{
86
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020087 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020088
89 OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
90 OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
91
Pau Espin Pedrol474dc772019-09-09 14:09:48 +020092 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020093}
94
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +010095static void test_tbf_tlli_update()
96{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +010097 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +010098 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010099 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck93990462015-05-15 15:50:43 +0200100 GprsMs *ms, *ms_new;
101
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200102 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100103
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100104 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100105 bts->trx[0].pdch[2].enable();
106 bts->trx[0].pdch[3].enable();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100107
108 /*
109 * Make a uplink and downlink allocation
110 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100111 ms = bts_alloc_ms(bts, 0, 0);
112 gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200113 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200114 OSMO_ASSERT(dl_tbf != NULL);
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200115 dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200116 dl_tbf->set_ta(4);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100117 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200118 OSMO_ASSERT(dl_tbf->ms() == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100119
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100120 gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(bts,
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200121 ms, 0, false);
Jacob Erlbeckc6d4cee2015-06-29 13:03:46 +0200122 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200123 ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100124 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200125 OSMO_ASSERT(ul_tbf->ms() == ms);
126
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100127 OSMO_ASSERT(bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100128
129 /*
130 * Now check.. that DL changes and that the timing advance
131 * has changed.
132 */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200133 dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100134
Jacob Erlbeck93990462015-05-15 15:50:43 +0200135 /* It is still there, since the new TLLI has not been used for UL yet */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100136 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200137 OSMO_ASSERT(ms == ms_new);
138
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100139 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200140 OSMO_ASSERT(ms == ms_new);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100141 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
142 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200143
144 /* Now use the new TLLI for UL */
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200145 ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100146 ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200147 OSMO_ASSERT(ms_new == NULL);
Holger Hans Peter Freytherbc1626e2013-10-30 19:50:49 +0100148
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100149 ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200150 OSMO_ASSERT(ms_new != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100151 OSMO_ASSERT(ms_ta(ms_new) == 4);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200152
153 OSMO_ASSERT(ul_tbf->ta() == 4);
154 OSMO_ASSERT(dl_tbf->ta() == 4);
155
156 ul_tbf->set_ta(6);
157
158 OSMO_ASSERT(ul_tbf->ta() == 6);
159 OSMO_ASSERT(dl_tbf->ta() == 6);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100160
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200161 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100162 TALLOC_FREE(the_pcu);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +0100163}
164
Daniel Willmann510d7d32014-08-15 18:19:41 +0200165static uint8_t llc_data[200];
166
Maxa2961182018-01-25 19:47:28 +0100167/* override, requires '-Wl,--wrap=pcu_sock_send' */
168int __real_pcu_sock_send(struct msgb *msg);
169int __wrap_pcu_sock_send(struct msgb *msg)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200170{
171 return 0;
172}
173
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100174static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100175{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100176 gprs_rlcmac_trx *trx;
177
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100178 the_pcu->alloc_algorithm = alloc_algorithm_a;
Jacob Erlbecka700dd92015-06-02 16:00:41 +0200179 bts->initial_cs_dl = cs;
180 bts->initial_cs_ul = cs;
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100181 osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S);
182 osmo_tdef_set(the_pcu->T_defs, -2031, 0, OSMO_TDEF_S);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100183 trx = &bts->trx[0];
184
185 trx->pdch[ts_no].enable();
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100186 bts_set_current_frame_number(bts, DUMMY_FN);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100187}
188
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100189static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +0100190 uint8_t egprs_ms_class, uint8_t *trx_no_)
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100191{
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100192 int tfi;
193 uint8_t trx_no;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200194 GprsMs *ms;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100195 gprs_rlcmac_dl_tbf *dl_tbf;
196
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100197 ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100198
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100199 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100200 OSMO_ASSERT(tfi >= 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200201 dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);
Pau Espin Pedrol983bb7e2020-10-26 14:52:06 +0100202 OSMO_ASSERT(dl_tbf);
Max9bbe1602016-07-18 12:50:18 +0200203 dl_tbf->set_ta(0);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100204 check_tbf(dl_tbf);
205
206 /* "Establish" the DL TBF */
Max0e599802018-01-23 20:09:06 +0100207 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
Max2399b1d2018-01-12 15:48:12 +0100208 TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_FLOW);
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100209 dl_tbf->m_wait_confirm = 0;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100210 check_tbf(dl_tbf);
211
212 *trx_no_ = trx_no;
213
214 return dl_tbf;
215}
216
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200217static unsigned fn2bn(unsigned fn)
218{
219 return (fn % 52) / 4;
220}
221
222static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
223{
224 unsigned bn = fn2bn(fn) + blocks;
225 fn = fn - (fn % 52);
226 fn += bn * 4 + bn / 3;
Max9dabfa22017-05-16 16:10:45 +0200227 return fn % GSM_MAX_FN;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200228}
229
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200230static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
Max878bd1f2016-07-20 13:05:05 +0200231 uint8_t trx_no, uint8_t ts_no,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200232 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100233{
Jacob Erlbeckee310902015-08-24 11:55:17 +0200234 uint8_t bn = fn2bn(*fn);
Max878bd1f2016-07-20 13:05:05 +0200235 gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200236 *fn = fn_add_blocks(*fn, 1);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200237 bn += 1;
238 if (block_nr)
239 *block_nr = bn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100240}
241
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200242static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
Jacob Erlbeckee310902015-08-24 11:55:17 +0200243 uint32_t *fn, uint8_t *block_nr = NULL)
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200244{
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100245 request_dl_rlc_block(tbf->bts, tbf->trx->trx_no,
Max878bd1f2016-07-20 13:05:05 +0200246 tbf->control_ts, fn, block_nr);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200247}
248
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100249enum test_tbf_final_ack_mode {
250 TEST_MODE_STANDARD,
251 TEST_MODE_REVERSE_FREE
252};
253
254static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
Daniel Willmann510d7d32014-08-15 18:19:41 +0200255{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100256 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100257 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100258 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100259 uint8_t ts_no = 4;
260 unsigned i;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200261 uint8_t ms_class = 45;
262 uint32_t fn;
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100263 uint8_t block_nr;
Jacob Erlbecka3e45092015-03-25 09:11:24 +0100264 uint8_t trx_no;
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200265 GprsMs *ms;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200266 uint32_t tlli = 0xffeeddcc;
Daniel Willmann510d7d32014-08-15 18:19:41 +0200267
268 uint8_t rbb[64/8];
269
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200270 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100271
Daniel Willmann510d7d32014-08-15 18:19:41 +0200272 gprs_rlcmac_dl_tbf *dl_tbf;
273 gprs_rlcmac_tbf *new_tbf;
274
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100275 setup_bts(bts, ts_no);
276 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200277 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeckd3eac282015-05-22 15:47:55 +0200278 ms = dl_tbf->ms();
Daniel Willmann510d7d32014-08-15 18:19:41 +0200279
280 for (i = 0; i < sizeof(llc_data); i++)
281 llc_data[i] = i%256;
282
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100283 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100284 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
285 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200286
287
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100288 /* Send only a few RLC/MAC blocks */
Daniel Willmann510d7d32014-08-15 18:19:41 +0200289 fn = 0;
Jacob Erlbeckee310902015-08-24 11:55:17 +0200290 do {
Daniel Willmann510d7d32014-08-15 18:19:41 +0200291 /* Request to send one block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200292 request_dl_rlc_block(dl_tbf, &fn, &block_nr);
Jacob Erlbeckee310902015-08-24 11:55:17 +0200293 } while (block_nr < 3);
Jacob Erlbeck64921d22015-08-24 11:34:47 +0200294
Jacob Erlbeck2493c662015-03-25 10:05:34 +0100295 OSMO_ASSERT(dl_tbf->have_data());
296 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
Daniel Willmann510d7d32014-08-15 18:19:41 +0200297
298 /* Queue a final ACK */
299 memset(rbb, 0, sizeof(rbb));
300 /* Receive a final ACK */
Max7df82d42017-12-15 11:14:30 +0100301 dl_tbf->rcvd_dl_ack(true, 1, rbb);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200302
303 /* Clean up and ensure tbfs are in the correct state */
304 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100305 new_tbf = ms_dl_tbf(ms);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100306 check_tbf(new_tbf);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200307 OSMO_ASSERT(new_tbf != dl_tbf);
308 OSMO_ASSERT(new_tbf->tfi() == 1);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100309 check_tbf(dl_tbf);
Max0e599802018-01-23 20:09:06 +0100310 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100311 if (test_mode == TEST_MODE_REVERSE_FREE) {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100312 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100313 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100314 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100315 check_tbf(dl_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100316 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100317 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100318 } else {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100319 ms_ref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100320 tbf_free(dl_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100321 OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf);
Jacob Erlbeck08fe76a2015-02-23 15:10:20 +0100322 check_tbf(new_tbf);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100323 tbf_free(new_tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100324 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
325 ms_unref(ms);
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +0100326 }
Jacob Erlbeck53efa3e2016-01-11 16:12:01 +0100327
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100328 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200329 fprintf(stderr, "=== end %s ===\n", __func__);
Daniel Willmann510d7d32014-08-15 18:19:41 +0200330}
331
Max7d32f552017-12-15 11:25:14 +0100332/* Receive an ACK */
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200333#define RCV_ACK(fin, tbf, rbb) do { \
334 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
335 tbf->rcvd_dl_ack(fin, w->v_s(), rbb); \
Max7d32f552017-12-15 11:25:14 +0100336 if (!fin) \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200337 OSMO_ASSERT(w->window_empty()); \
Max7d32f552017-12-15 11:25:14 +0100338 } while(0)
339
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100340static void test_tbf_delayed_release()
341{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100342 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100343 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100344 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100345 uint8_t ts_no = 4;
346 unsigned i;
347 uint8_t ms_class = 45;
348 uint32_t fn = 0;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100349 uint8_t trx_no;
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200350 uint32_t tlli = 0xffeeddcc;
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200351 unsigned long dl_tbf_idle_msec;
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100352
353 uint8_t rbb[64/8];
354
355 gprs_rlcmac_dl_tbf *dl_tbf;
356
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200357 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100358
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100359 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100360 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100361
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100362 dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeck1c68aba2015-05-22 15:40:08 +0200363 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100364
365 for (i = 0; i < sizeof(llc_data); i++)
366 llc_data[i] = i%256;
367
368 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
369
370 /* Schedule two LLC frames */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +0100371 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
372 dl_tbf->append_data(1000, llc_data, sizeof(llc_data));
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100373
374 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
375
376 /* Drain the queue */
377 while (dl_tbf->have_data())
378 /* Request to send one RLC/MAC block */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200379 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100380
381 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
382
383 /* ACK all blocks */
384 memset(rbb, 0xff, sizeof(rbb));
Max7d32f552017-12-15 11:25:14 +0100385
386 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100387
388 /* Force sending of a single block containing an LLC dummy command */
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200389 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100390
Max7d32f552017-12-15 11:25:14 +0100391 RCV_ACK(false, dl_tbf, rbb); /* Receive an ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100392
393 /* Timeout (make sure fn % 52 remains valid) */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100394 dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200395 fn += 52 * ((msecs_to_frames(dl_tbf_idle_msec + 100) + 51)/ 52);
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +0200396 request_dl_rlc_block(dl_tbf, &fn);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100397
398 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FINISHED));
399
Max7d32f552017-12-15 11:25:14 +0100400 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100401
402 /* Clean up and ensure tbfs are in the correct state */
403 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +0100404 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100405 check_tbf(dl_tbf);
406 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100407 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200408 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +0100409}
410
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200411static void test_tbf_imsi()
412{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100413 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100414 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100415 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200416 uint8_t ts_no = 4;
417 uint8_t ms_class = 45;
418 uint8_t trx_no;
419 GprsMs *ms1, *ms2;
420
421 gprs_rlcmac_dl_tbf *dl_tbf[2];
422
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200423 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200424
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100425 setup_bts(bts, ts_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200426
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100427 dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no);
428 dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200429
430 dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF);
431 dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF);
432
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100433 ms_set_imsi(dl_tbf[0]->ms(), "001001000000001");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100434 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200435 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100436 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200437 OSMO_ASSERT(ms2 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100438 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200439 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200440
441 /* change the IMSI on TBF 0 */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100442 ms_set_imsi(dl_tbf[0]->ms(), "001001000000002");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100443 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200444 OSMO_ASSERT(ms1 == NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100445 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200446 OSMO_ASSERT(ms1 != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100447 OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200448 OSMO_ASSERT(ms1 == ms2);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200449
Pau Espin Pedrol528820d2020-10-26 12:40:11 +0100450 /* use the same IMSI on TBF 1 */
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200451 {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100452 ms_ref(ms2);
453 ms_set_imsi(dl_tbf[1]->ms(), "001001000000002");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100454 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200455 OSMO_ASSERT(ms1 != NULL);
456 OSMO_ASSERT(ms1 != ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100457 OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0);
458 OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0);
459 ms_unref(ms2);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200460 }
461
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100462 ms2 = bts_ms_store(bts)->get_ms(0xf1000001);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200463 OSMO_ASSERT(ms2 == NULL);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200464
465 tbf_free(dl_tbf[1]);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100466 ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002");
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200467 OSMO_ASSERT(ms1 == NULL);
468
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100469 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200470 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +0200471}
472
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200473static void test_tbf_exhaustion()
474{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100475 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100476 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100477 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200478 unsigned i;
479 uint8_t ts_no = 4;
480 uint8_t ms_class = 45;
481 int rc = 0;
482
483 uint8_t buf[256] = {0};
484
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200485 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200486
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100487 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
488 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200489 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
490 abort();
491 }
492
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100493 setup_bts(bts, ts_no);
Alexander Couzens290d9032020-09-16 21:52:02 +0200494 gprs_bssgp_init(bts, 1234, 1234, 1, 1, false, 0, 0, 0);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200495
496 for (i = 0; i < 1024; i++) {
497 uint32_t tlli = 0xc0000000 + i;
498 char imsi[16] = {0};
499 unsigned delay_csec = 1000;
500
Jacob Erlbeck9a2845d2015-05-21 12:06:58 +0200501 snprintf(imsi, sizeof(imsi), "001001%09d", i);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200502
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100503 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200504 delay_csec, buf, sizeof(buf));
505
506 if (rc < 0)
507 break;
508 }
509
510 OSMO_ASSERT(rc == -EBUSY);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200511 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200512
Alexander Couzens290d9032020-09-16 21:52:02 +0200513 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100514 TALLOC_FREE(the_pcu);
Jacob Erlbeckd58b7112015-04-09 19:17:21 +0200515}
516
Jacob Erlbeck41168642015-06-12 13:41:00 +0200517static void test_tbf_dl_llc_loss()
518{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100519 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100520 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100521 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck41168642015-06-12 13:41:00 +0200522 uint8_t ts_no = 4;
523 uint8_t ms_class = 45;
524 int rc = 0;
525 uint32_t tlli = 0xc0123456;
526 const char *imsi = "001001000123456";
527 unsigned delay_csec = 1000;
528 GprsMs *ms;
529
530 uint8_t buf[19];
531
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100532 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
533 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +0200534 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
535 abort();
536 }
537
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200538 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200539
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100540 setup_bts(bts, ts_no);
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200541 /* keep the MS object 10 seconds */
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +0100542 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200543
Alexander Couzens290d9032020-09-16 21:52:02 +0200544 gprs_bssgp_init(bts, 2234, 2234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200545
546 /* Handle LLC frame 1 */
547 memset(buf, 1, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100548 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200549 delay_csec, buf, sizeof(buf));
550 OSMO_ASSERT(rc >= 0);
551
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100552 ms = bts_ms_store(bts)->get_ms(0, 0, imsi);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200553 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100554 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
555 ms_dl_tbf(ms)->set_ta(0);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200556
557 /* Handle LLC frame 2 */
558 memset(buf, 2, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100559 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200560 delay_csec, buf, sizeof(buf));
561 OSMO_ASSERT(rc >= 0);
562
563 /* TBF establishment fails (timeout) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100564 tbf_free(ms_dl_tbf(ms));
Jacob Erlbeck41168642015-06-12 13:41:00 +0200565
566 /* Handle LLC frame 3 */
567 memset(buf, 3, sizeof(buf));
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100568 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
Jacob Erlbeck41168642015-06-12 13:41:00 +0200569 delay_csec, buf, sizeof(buf));
570 OSMO_ASSERT(rc >= 0);
571
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100572 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200573
574 /* Get first BSN */
575 struct msgb *msg;
576 int fn = 0;
577 uint8_t expected_data = 1;
Maxd3a0d912019-03-05 16:15:01 +0100578 static uint8_t exp[][GSM_MACBLOCK_LEN] = {
579 { 0x07, 0x00, 0x00, 0x4d, 0x01, 0x01, 0x01,
580 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
581 { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02,
582 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
583 { 0x07, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03,
584 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 },
585 };
Jacob Erlbeck41168642015-06-12 13:41:00 +0200586
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100587 while (ms_dl_tbf(ms)->have_data()) {
588 msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, 7);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200589 fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg));
Maxd3a0d912019-03-05 16:15:01 +0100590 if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200591 fprintf(stderr, "%s failed at %u\n", __func__, expected_data);
Maxd3a0d912019-03-05 16:15:01 +0100592
Jacob Erlbeck41168642015-06-12 13:41:00 +0200593 expected_data += 1;
594 }
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200595 OSMO_ASSERT(expected_data-1 == 3);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200596
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200597 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200598
Alexander Couzens290d9032020-09-16 21:52:02 +0200599 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +0100600 TALLOC_FREE(the_pcu);
Jacob Erlbeck41168642015-06-12 13:41:00 +0200601}
602
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100603static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200604 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200605{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200606 GprsMs *ms;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200607 int tfi = 0;
608 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200609 uint8_t trx_no = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200610 struct gprs_rlcmac_pdch *pdch;
611
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100612 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200613
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100614 bts_handle_rach(bts, 0x03, *fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200615
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100616 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200617 OSMO_ASSERT(ul_tbf != NULL);
618
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200619 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200620
621 uint8_t data_msg[23] = {
622 0x00, /* GPRS_RLCMAC_DATA_BLOCK << 6 */
623 uint8_t(1 | (tfi << 2)),
624 uint8_t(1), /* BSN:7, E:1 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200625 uint8_t(tlli >> 24), uint8_t(tlli >> 16),
626 uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200627 };
628
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100629 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200630 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200631
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100632 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200633 OSMO_ASSERT(ms != NULL);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200634
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +0200635 return ul_tbf;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +0200636}
637
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100638static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, unsigned trx_no, unsigned ts_no,
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200639 RlcMacUplink_t *ulreq, unsigned fn)
640{
641 bitvec *rlc_block;
642 uint8_t buf[64];
643 int num_bytes;
644 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200645
Alexander Couzensccde5c92017-02-04 03:10:08 +0100646 rlc_block = bitvec_alloc(23, tall_pcu_ctx);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200647
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +0100648 OSMO_ASSERT(encode_gsm_rlcmac_uplink(rlc_block, ulreq) == 0);
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200649 num_bytes = bitvec_pack(rlc_block, &buf[0]);
650 OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
651 bitvec_free(rlc_block);
652
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100653 bts_set_current_block_frame_number(bts, fn, 0);
Jacob Erlbeckaf75ce82015-08-26 13:22:28 +0200654
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100655 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck56f99d12015-08-20 15:55:56 +0200656 pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
657}
658
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200659static void send_control_ack(gprs_rlcmac_tbf *tbf)
660{
661 RlcMacUplink_t ulreq = {0};
662
663 OSMO_ASSERT(tbf->poll_fn != 0);
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100664 OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200665
666 ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
667 Packet_Control_Acknowledgement_t *ctrl_ack =
668 &ulreq.u.Packet_Control_Acknowledgement;
669
670 ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
671 ctrl_ack->TLLI = tbf->tlli();
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100672 send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
Jacob Erlbeckaf454732015-08-21 15:03:23 +0200673 &ulreq, tbf->poll_fn);
674}
675
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100676static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530677 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
678 uint8_t ms_class, uint8_t egprs_ms_class)
679{
680 GprsMs *ms;
681 uint32_t rach_fn = *fn - 51;
682 uint32_t sba_fn = *fn + 52;
683 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100684 int tfi = 0;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530685 gprs_rlcmac_ul_tbf *ul_tbf;
686 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530687 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530688 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530689
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530690 /* needed to set last_rts_fn in the PDCH object */
691 request_dl_rlc_block(bts, trx_no, ts_no, fn);
692
693 /*
694 * simulate RACH, this sends an Immediate
695 * Assignment Uplink on the AGCH
696 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100697 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530698
699 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100700 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530701
702 /* fake a resource request */
703 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
704 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
705 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
706 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100707 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
708 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530709 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100710 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530711 MS_RA_capability_value[0].u.Content.
712 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100713 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530714 MS_RA_capability_value[0].u.Content.Multislot_capability.
715 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100716 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530717 MS_RA_capability_value[0].u.Content.Multislot_capability.
718 GPRS_multislot_class = ms_class;
719 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100720 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530721 MS_RA_capability_value[0].u.Content.
722 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100723 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530724 MS_RA_capability_value[0].u.Content.
725 Multislot_capability.EGPRS_multislot_class = ms_class;
726 }
727
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100728 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530729
730 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100731 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530732 OSMO_ASSERT(ul_tbf);
733 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
734
735 /* send packet uplink assignment */
736 *fn = sba_fn;
737 request_dl_rlc_block(ul_tbf, fn);
738
739 /* send real acknowledgement */
740 send_control_ack(ul_tbf);
741
742 check_tbf(ul_tbf);
743 /* send fake data */
744 uint8_t data_msg[42] = {
745 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100746 (uint8_t)(tfi << 1),
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530747 1, /* BSN:7, E:1 */
748 };
749
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100750 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530751 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
752
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100753 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530754 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100755 OSMO_ASSERT(ms_ta(ms) == qta/4);
756 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530757
758 /*
759 * TS 44.060, B.8.1
760 * first seg received first, later second seg
761 */
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530762 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
763 egprs3->si = 0;
764 egprs3->r = 1;
765 egprs3->cv = 7;
766 egprs3->tfi_hi = tfi & 0x03;
767 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
768 egprs3->bsn1_hi = 1;
769 egprs3->bsn1_lo = 0;
770 egprs3->cps_hi = 1;
771 data_msg[3] = 0xff;
772 egprs3->pi = 0;
773 egprs3->cps_lo = 1;
774 egprs3->rsb = 0;
775 egprs3->spb = 0;
776 egprs3->pi = 0;
777
778 pdch->rcv_block(data_msg, 42, *fn, &meas);
779
780 struct msgb *msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
781
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100782 static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x87, 0xb0, 0x06,
Maxd3a0d912019-03-05 16:15:01 +0100783 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
784 };
785
786 if (!msgb_eq_data_print(msg1, exp1, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200787 fprintf(stderr, "%s test failed on 1st segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100788 return NULL;
789 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530790
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 = 4;
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
805 pdch->rcv_block(data_msg, 42, *fn, &meas);
806
807 msg1 = ul_tbf->create_ul_ack(*fn, ts_no);
808
Pau Espin Pedrol46fd7a02020-11-02 14:36:22 +0100809 static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x90, 0x88, 0xb0, 0x06, 0x8b,
Maxd3a0d912019-03-05 16:15:01 +0100810 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
811 };
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530812
Maxd3a0d912019-03-05 16:15:01 +0100813 if (!msgb_eq_data_print(msg1, exp2, GSM_MACBLOCK_LEN)) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +0200814 fprintf(stderr, "%s test failed on 2nd segment!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +0100815 return NULL;
816 }
Aravind Sirsikar02352b42016-08-25 16:37:30 +0530817 return ul_tbf;
818}
819
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100820static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530821 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
822 uint8_t ms_class, uint8_t egprs_ms_class)
823{
824 GprsMs *ms;
825 uint32_t rach_fn = *fn - 51;
826 uint32_t sba_fn = *fn + 52;
827 uint8_t trx_no = 0;
828 int tfi = 0, i = 0;
829 gprs_rlcmac_ul_tbf *ul_tbf;
830 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530831 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530832 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530833
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530834 /* needed to set last_rts_fn in the PDCH object */
835 request_dl_rlc_block(bts, trx_no, ts_no, fn);
836
837 /*
838 * simulate RACH, this sends an Immediate
839 * Assignment Uplink on the AGCH
840 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100841 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530842
843 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100844 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530845
846 /* fake a resource request */
847 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
848 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
849 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
850 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100851 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
852 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530853 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100854 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530855 MS_RA_capability_value[0].u.Content.
856 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100857 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530858 MS_RA_capability_value[0].u.Content.Multislot_capability.
859 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100860 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530861 MS_RA_capability_value[0].u.Content.Multislot_capability.
862 GPRS_multislot_class = ms_class;
863 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100864 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530865 MS_RA_capability_value[0].u.Content.
866 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +0100867 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530868 MS_RA_capability_value[0].u.Content.
869 Multislot_capability.EGPRS_multislot_class = ms_class;
870 }
871
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100872 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530873
874 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100875 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530876 OSMO_ASSERT(ul_tbf != NULL);
877 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
878
879 /* send packet uplink assignment */
880 *fn = sba_fn;
881 request_dl_rlc_block(ul_tbf, fn);
882
883 /* send real acknowledgement */
884 send_control_ack(ul_tbf);
885
886 check_tbf(ul_tbf);
887
888 /* send fake data */
889 uint8_t data_msg[42] = {
890 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
891 uint8_t(0 | (tfi << 1)),
892 uint8_t(1), /* BSN:7, E:1 */
893 };
894
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100895 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530896 pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
897
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100898 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530899 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100900 OSMO_ASSERT(ms_ta(ms) == qta/4);
901 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530902
903 /*
904 * TS 44.060, B.8.1
905 * first seg received first, later second seg
906 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530907 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
908 egprs3->si = 1;
909 egprs3->r = 1;
910 egprs3->cv = 7;
911 egprs3->tfi_hi = tfi & 0x03;
912 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
913 egprs3->bsn1_hi = 1;
914 egprs3->bsn1_lo = 0;
915 egprs3->cps_hi = 1;
916 data_msg[3] = 0xff;
917 egprs3->pi = 0;
918 egprs3->cps_lo = 1;
919 egprs3->rsb = 0;
920 egprs3->spb = 2;
921 egprs3->pi = 0;
922
923 pdch->rcv_block(data_msg, 42, *fn, &meas);
924
925 struct gprs_rlc_data *block = ul_tbf->m_rlc.block(1);
926
927 /* check the status of the block */
928 OSMO_ASSERT(block->spb_status.block_status_ul ==
929 EGPRS_RESEG_FIRST_SEG_RXD);
930
931 egprs3->si = 1;
932 egprs3->r = 1;
933 egprs3->cv = 7;
934 egprs3->tfi_hi = tfi & 0x03;
935 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
936 egprs3->bsn1_hi = 1;
937 egprs3->bsn1_lo = 0;
938 egprs3->cps_hi = 1;
939 data_msg[3] = 0xff;
940 egprs3->pi = 0;
941 egprs3->cps_lo = 1;
942 egprs3->rsb = 0;
943 egprs3->spb = 3;
944
945 pdch->rcv_block(data_msg, 42, *fn, &meas);
946
947 /* check the status of the block */
948 OSMO_ASSERT(block->spb_status.block_status_ul ==
949 EGPRS_RESEG_DEFAULT);
950 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +0100951 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530952 /* Assembled MCS is MCS6. so the size is 74 */
953 OSMO_ASSERT(block->len == 74);
954
955 /*
956 * TS 44.060, B.8.1
957 * second seg first, later first seg
958 */
959 memset(data_msg, 0, sizeof(data_msg));
960
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530961 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
962 egprs3->si = 1;
963 egprs3->r = 1;
964 egprs3->cv = 7;
965 egprs3->tfi_hi = tfi & 0x03;
966 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
967 egprs3->bsn1_hi = 2;
968 egprs3->bsn1_lo = 0;
969 egprs3->cps_hi = 1;
970 data_msg[3] = 0xff;
971 egprs3->pi = 0;
972 egprs3->cps_lo = 1;
973 egprs3->rsb = 0;
974 egprs3->spb = 3;
975 egprs3->pi = 0;
976
977 pdch->rcv_block(data_msg, 42, *fn, &meas);
978
979 block = ul_tbf->m_rlc.block(2);
980 /* check the status of the block */
981 OSMO_ASSERT(block->spb_status.block_status_ul ==
982 EGPRS_RESEG_SECOND_SEG_RXD);
983
984 egprs3->si = 1;
985 egprs3->r = 1;
986 egprs3->cv = 7;
987 egprs3->tfi_hi = tfi & 0x03;
988 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
989 egprs3->bsn1_hi = 2;
990 egprs3->bsn1_lo = 0;
991 egprs3->cps_hi = 1;
992 data_msg[3] = 0xff;
993 egprs3->pi = 0;
994 egprs3->cps_lo = 1;
995 egprs3->rsb = 0;
996 egprs3->spb = 2;
997 egprs3->pi = 0;
998
999 pdch->rcv_block(data_msg, 42, *fn, &meas);
1000
1001 /* check the status of the block */
1002 OSMO_ASSERT(block->spb_status.block_status_ul ==
1003 EGPRS_RESEG_DEFAULT);
1004 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001005 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301006 /* Assembled MCS is MCS6. so the size is 74 */
1007 OSMO_ASSERT(block->len == 74);
1008
1009 /*
1010 * TS 44.060, B.8.1
1011 * Error scenario with spb as 1
1012 */
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301013 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1014 egprs3->si = 1;
1015 egprs3->r = 1;
1016 egprs3->cv = 7;
1017 egprs3->tfi_hi = tfi & 0x03;
1018 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1019 egprs3->bsn1_hi = 3;
1020 egprs3->bsn1_lo = 0;
1021 egprs3->cps_hi = 1;
1022 data_msg[3] = 0xff;
1023 egprs3->pi = 0;
1024 egprs3->cps_lo = 1;
1025 egprs3->rsb = 0;
1026 egprs3->spb = 1;
1027 egprs3->pi = 0;
1028
1029 pdch->rcv_block(data_msg, 42, *fn, &meas);
1030
1031 block = ul_tbf->m_rlc.block(3);
1032 /* check the status of the block */
1033 OSMO_ASSERT(block->spb_status.block_status_ul ==
1034 EGPRS_RESEG_DEFAULT);
1035 /*
1036 * TS 44.060, B.8.1
1037 * comparison of rlc_data for multiple scenarios
1038 * Receive First, the second(BSN 3)
1039 * Receive First, First then Second(BSN 4)
1040 * Receive Second then First(BSN 5)
1041 * after above 3 scenarios are triggered,
1042 * rlc_data of all 3 BSN are compared
1043 */
1044
1045 /* Initialize the data_msg */
1046 for (i = 0; i < 42; i++)
1047 data_msg[i] = i;
1048
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301049 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1050 egprs3->si = 1;
1051 egprs3->r = 1;
1052 egprs3->cv = 7;
1053 egprs3->tfi_hi = tfi & 0x03;
1054 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1055 egprs3->bsn1_hi = 3;
1056 egprs3->bsn1_lo = 0;
1057 egprs3->cps_hi = 1;
1058 data_msg[3] = 0xff;
1059 egprs3->pi = 0;
1060 egprs3->cps_lo = 1;
1061 egprs3->rsb = 0;
1062 egprs3->spb = 2;
1063 egprs3->pi = 0;
1064
1065 pdch->rcv_block(data_msg, 42, *fn, &meas);
1066
1067 block = ul_tbf->m_rlc.block(3);
1068 /* check the status of the block */
1069 OSMO_ASSERT(block->spb_status.block_status_ul ==
1070 EGPRS_RESEG_FIRST_SEG_RXD);
1071
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301072 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1073 egprs3->si = 1;
1074 egprs3->r = 1;
1075 egprs3->cv = 7;
1076 egprs3->tfi_hi = tfi & 0x03;
1077 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1078 egprs3->bsn1_hi = 3;
1079 egprs3->bsn1_lo = 0;
1080 egprs3->cps_hi = 1;
1081 data_msg[3] = 0xff;
1082 egprs3->pi = 0;
1083 egprs3->cps_lo = 1;
1084 egprs3->rsb = 0;
1085 egprs3->spb = 3;
1086 egprs3->pi = 0;
1087
1088 pdch->rcv_block(data_msg, 42, *fn, &meas);
1089
1090 block = ul_tbf->m_rlc.block(3);
1091 /* check the status of the block */
1092 OSMO_ASSERT(block->spb_status.block_status_ul ==
1093 EGPRS_RESEG_DEFAULT);
1094 /* Assembled MCS is MCS6. so the size is 74 */
1095 OSMO_ASSERT(block->len == 74);
1096 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001097 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301098
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301099 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1100 egprs3->si = 1;
1101 egprs3->r = 1;
1102 egprs3->cv = 7;
1103 egprs3->tfi_hi = tfi & 0x03;
1104 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1105 egprs3->bsn1_hi = 4;
1106 egprs3->bsn1_lo = 0;
1107 egprs3->cps_hi = 1;
1108 data_msg[3] = 0xff;
1109 egprs3->pi = 0;
1110 egprs3->cps_lo = 1;
1111 egprs3->rsb = 0;
1112 egprs3->spb = 2;
1113 egprs3->pi = 0;
1114
1115 pdch->rcv_block(data_msg, 42, *fn, &meas);
1116
1117 block = ul_tbf->m_rlc.block(4);
1118 /* check the status of the block */
1119 OSMO_ASSERT(block->spb_status.block_status_ul ==
1120 EGPRS_RESEG_FIRST_SEG_RXD);
1121
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301122 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1123 egprs3->si = 1;
1124 egprs3->r = 1;
1125 egprs3->cv = 7;
1126 egprs3->tfi_hi = tfi & 0x03;
1127 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1128 egprs3->bsn1_hi = 4;
1129 egprs3->bsn1_lo = 0;
1130 egprs3->cps_hi = 1;
1131 data_msg[3] = 0xff;
1132 egprs3->pi = 0;
1133 egprs3->cps_lo = 1;
1134 egprs3->rsb = 0;
1135 egprs3->spb = 2;
1136 egprs3->pi = 0;
1137
1138 pdch->rcv_block(data_msg, 42, *fn, &meas);
1139
1140 block = ul_tbf->m_rlc.block(4);
1141 /* check the status of the block */
1142 OSMO_ASSERT(block->spb_status.block_status_ul ==
1143 EGPRS_RESEG_FIRST_SEG_RXD);
1144
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301145 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1146 egprs3->si = 1;
1147 egprs3->r = 1;
1148 egprs3->cv = 7;
1149 egprs3->tfi_hi = tfi & 0x03;
1150 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1151 egprs3->bsn1_hi = 4;
1152 egprs3->bsn1_lo = 0;
1153 egprs3->cps_hi = 1;
1154 data_msg[3] = 0xff;
1155 egprs3->pi = 0;
1156 egprs3->cps_lo = 1;
1157 egprs3->rsb = 0;
1158 egprs3->spb = 3;
1159 egprs3->pi = 0;
1160
1161 pdch->rcv_block(data_msg, 42, *fn, &meas);
1162
1163 block = ul_tbf->m_rlc.block(4);
1164 /* check the status of the block */
1165 OSMO_ASSERT(block->spb_status.block_status_ul ==
1166 EGPRS_RESEG_DEFAULT);
1167 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001168 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301169 /* Assembled MCS is MCS6. so the size is 74 */
1170 OSMO_ASSERT(block->len == 74);
1171
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301172 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1173 egprs3->si = 1;
1174 egprs3->r = 1;
1175 egprs3->cv = 7;
1176 egprs3->tfi_hi = tfi & 0x03;
1177 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1178 egprs3->bsn1_hi = 5;
1179 egprs3->bsn1_lo = 0;
1180 egprs3->cps_hi = 1;
1181 data_msg[3] = 0xff;
1182 egprs3->pi = 0;
1183 egprs3->cps_lo = 1;
1184 egprs3->rsb = 0;
1185 egprs3->spb = 3;
1186 egprs3->pi = 0;
1187
1188 pdch->rcv_block(data_msg, 42, *fn, &meas);
1189
1190 block = ul_tbf->m_rlc.block(5);
1191 /* check the status of the block */
1192 OSMO_ASSERT(block->spb_status.block_status_ul ==
1193 EGPRS_RESEG_SECOND_SEG_RXD);
1194
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301195 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
1196 egprs3->si = 1;
1197 egprs3->r = 1;
1198 egprs3->cv = 7;
1199 egprs3->tfi_hi = tfi & 0x03;
1200 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
1201 egprs3->bsn1_hi = 5;
1202 egprs3->bsn1_lo = 0;
1203 egprs3->cps_hi = 1;
1204 data_msg[3] = 0xff;
1205 egprs3->pi = 0;
1206 egprs3->cps_lo = 1;
1207 egprs3->rsb = 0;
1208 egprs3->spb = 2;
1209 egprs3->pi = 0;
1210
1211 pdch->rcv_block(data_msg, 42, *fn, &meas);
1212
1213 block = ul_tbf->m_rlc.block(5);
1214
1215 /* check the status of the block */
1216 OSMO_ASSERT(block->spb_status.block_status_ul ==
1217 EGPRS_RESEG_DEFAULT);
1218 OSMO_ASSERT(block->cs_last ==
Maxbea2edb2019-03-06 17:04:59 +01001219 MCS6);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05301220 /* Assembled MCS is MCS6. so the size is 74 */
1221 OSMO_ASSERT(block->len == 74);
1222
1223 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1224 ul_tbf->m_rlc.block(4)->len);
1225 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->len ==
1226 ul_tbf->m_rlc.block(3)->len);
1227
1228 /* Compare the spb status of each BSNs(3,4,5). should be same */
1229 OSMO_ASSERT(
1230 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1231 ul_tbf->m_rlc.block(4)->spb_status.block_status_ul);
1232 OSMO_ASSERT(
1233 ul_tbf->m_rlc.block(5)->spb_status.block_status_ul ==
1234 ul_tbf->m_rlc.block(3)->spb_status.block_status_ul);
1235
1236 /* Compare the Assembled MCS of each BSNs(3,4,5). should be same */
1237 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1238 ul_tbf->m_rlc.block(4)->cs_last);
1239 OSMO_ASSERT(ul_tbf->m_rlc.block(5)->cs_last ==
1240 ul_tbf->m_rlc.block(3)->cs_last);
1241
1242 /* Compare the data of each BSNs(3,4,5). should be same */
1243 OSMO_ASSERT(
1244 !memcmp(ul_tbf->m_rlc.block(5)->block,
1245 ul_tbf->m_rlc.block(4)->block, ul_tbf->m_rlc.block(5)->len
1246 ));
1247 OSMO_ASSERT(
1248 !memcmp(ul_tbf->m_rlc.block(5)->block,
1249 ul_tbf->m_rlc.block(3)->block, ul_tbf->m_rlc.block(5)->len
1250 ));
1251
1252 return ul_tbf;
1253}
1254
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001255static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301256 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1257 uint8_t ms_class, uint8_t egprs_ms_class)
1258{
sivasankari1d8744c2017-01-24 15:53:35 +05301259 uint32_t rach_fn = *fn - 51;
1260 uint32_t sba_fn = *fn + 52;
1261 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001262 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301263 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301264 RlcMacUplink_t ulreq = {0};
sivasankari1d8744c2017-01-24 15:53:35 +05301265
sivasankari1d8744c2017-01-24 15:53:35 +05301266 /* needed to set last_rts_fn in the PDCH object */
1267 request_dl_rlc_block(bts, trx_no, ts_no, fn);
1268
1269 /*
1270 * simulate RACH, this sends an Immediate
1271 * Assignment Uplink on the AGCH
1272 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001273 bts_handle_rach(bts, 0x73, rach_fn, qta);
sivasankari1d8744c2017-01-24 15:53:35 +05301274
1275 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001276 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
sivasankari1d8744c2017-01-24 15:53:35 +05301277
1278 /* fake a resource request */
1279 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1280 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1281 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1282 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001283 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1284 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301285 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001286 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301287 MS_RA_capability_value[0].u.Content.
1288 Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001289 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301290 MS_RA_capability_value[0].u.Content.Multislot_capability.
1291 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001292 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301293 MS_RA_capability_value[0].u.Content.Multislot_capability.
1294 GPRS_multislot_class = ms_class;
1295 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001296 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301297 MS_RA_capability_value[0].u.Content.
1298 Multislot_capability.Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001299 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
sivasankari1d8744c2017-01-24 15:53:35 +05301300 MS_RA_capability_value[0].u.Content.
1301 Multislot_capability.EGPRS_multislot_class = ms_class;
1302 }
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001303 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
sivasankari1d8744c2017-01-24 15:53:35 +05301304
1305 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001306 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301307 /* send packet uplink assignment */
1308 *fn = sba_fn;
1309 request_dl_rlc_block(ul_tbf, fn);
1310
1311 /* send real acknowledgement */
1312 send_control_ack(ul_tbf);
1313
1314 check_tbf(ul_tbf);
1315
1316 return ul_tbf;
1317}
1318
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001319static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301320 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1321 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1322{
1323 OSMO_ASSERT(ul_tbf);
1324 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1325 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301326 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001327 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301328 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301329
1330 /* send fake data with cv=0*/
1331 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1332 uint8_t data[49] = {0};
1333
1334 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1335
1336 /*header_construction */
1337 memset(data, 0x2b, sizeof(data));
1338 /* Message with CRBB */
1339 for (int i = 0 ; i < 80; i++) {
1340 hdr3->r = 0;
1341 hdr3->si = 0;
1342 hdr3->cv = 10;
1343 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1344 hdr3->tfi_lo = tfi & 0x7;
1345 hdr3->bsn1_hi = ((i * 2)&0x1f);
1346 hdr3->bsn1_lo = ((i * 2)/32);
1347 hdr3->cps_hi = 0;
1348 hdr3->cps_lo = 0;
1349 hdr3->spb = 0;
1350 hdr3->rsb = 0;
1351 hdr3->pi = 0;
1352 hdr3->spare = 0;
1353 hdr3->dummy = 1;
1354 data[4] = 0x0;
1355 data[5] = 0x0;
1356 data[6] = 0x2b;
1357 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001358 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301359 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1360 }
1361 ul_tbf->create_ul_ack(*fn, ts_no);
1362 memset(data, 0x2b, sizeof(data));
1363 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1364 hdr3->r = 0;
1365 hdr3->si = 0;
1366 hdr3->cv = 0;
1367 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1368 hdr3->tfi_lo = tfi & 0x7;
1369 hdr3->bsn1_hi = 0;
1370 hdr3->bsn1_lo = 2;
1371 hdr3->cps_hi = 0;
1372 hdr3->cps_lo = 0;
1373 hdr3->spb = 0;
1374 hdr3->rsb = 0;
1375 hdr3->pi = 0;
1376 hdr3->spare = 0;
1377 hdr3->dummy = 1;
1378 data[4] = 0x0;
1379 data[5] = 0x2b;
1380 data[6] = 0x2b;
1381 data[7] = 0x2b;
1382
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001383 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301384 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1385
1386 request_dl_rlc_block(ul_tbf, fn);
1387
1388 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001389 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301390
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001391 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301392 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001393 OSMO_ASSERT(ms_ta(ms) == qta/4);
1394 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301395
1396 return ul_tbf;
1397}
1398
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001399static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301400 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1401 uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf)
1402{
1403 OSMO_ASSERT(ul_tbf);
1404 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1405 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301406 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001407 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301408 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301409
1410 check_tbf(ul_tbf);
1411 /* send fake data with cv=0*/
1412 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1413 uint8_t data[49] = {0};
1414
1415 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1416
1417 /*header_construction */
1418 memset(data, 0x2b, sizeof(data));
1419
1420 /* Message with URBB & URBB length */
1421 for (int i = 0 ; i < 20; i++) {
1422 hdr3->r = 0;
1423 hdr3->si = 0;
1424 hdr3->cv = 10;
1425 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1426 hdr3->tfi_lo = tfi & 0x7;
1427 hdr3->bsn1_hi = ((i * 2)&0x1f);
1428 hdr3->bsn1_lo = ((i * 2)/32);
1429 hdr3->cps_hi = 0;
1430 hdr3->cps_lo = 0;
1431 hdr3->spb = 0;
1432 hdr3->rsb = 0;
1433 hdr3->pi = 0;
1434 hdr3->spare = 0;
1435 hdr3->dummy = 1;
1436 data[4] = 0x0;
1437 data[5] = 0x0;
1438 data[6] = 0x2b;
1439 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001440 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301441 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1442 }
1443 ul_tbf->create_ul_ack(*fn, ts_no);
1444 memset(data, 0x2b, sizeof(data));
1445 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1446 hdr3->r = 0;
1447 hdr3->si = 0;
1448 hdr3->cv = 0;
1449 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1450 hdr3->tfi_lo = tfi & 0x7;
1451 hdr3->bsn1_hi = 0;
1452 hdr3->bsn1_lo = 2;
1453 hdr3->cps_hi = 0;
1454 hdr3->cps_lo = 0;
1455 hdr3->spb = 0;
1456 hdr3->rsb = 0;
1457 hdr3->pi = 0;
1458 hdr3->spare = 0;
1459 hdr3->dummy = 1;
1460 data[4] = 0x0;
1461 data[5] = 0x2b;
1462 data[6] = 0x2b;
1463 data[7] = 0x2b;
1464
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001465 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301466 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +02001467 ul_tbf->create_ul_ack(*fn, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301468
1469 request_dl_rlc_block(ul_tbf, fn);
1470
1471 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001472 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301473
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001474 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301475 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001476 OSMO_ASSERT(ms_ta(ms) == qta/4);
1477 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301478
1479 return ul_tbf;
1480}
1481
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001482static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts,
sivasankari1d8744c2017-01-24 15:53:35 +05301483 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1484 uint8_t ms_class, uint8_t egprs_ms_class)
1485{
1486 GprsMs *ms;
sivasankari1d8744c2017-01-24 15:53:35 +05301487 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001488 int tfi = 0;
sivasankari1d8744c2017-01-24 15:53:35 +05301489 gprs_rlcmac_ul_tbf *ul_tbf;
1490 struct gprs_rlcmac_pdch *pdch;
sivasankari1d8744c2017-01-24 15:53:35 +05301491
1492 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001493 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
sivasankari1d8744c2017-01-24 15:53:35 +05301494 OSMO_ASSERT(ul_tbf);
1495 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
1496
1497 /* send fake data with cv=0*/
1498 struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
1499 uint8_t data[49] = {0};
1500
1501 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1502
1503 /*header_construction */
1504 memset(data, 0x2b, sizeof(data));
1505
1506 /* Message with CRBB */
1507 for (int i = 80 ; i < 160; i++) {
1508 hdr3->r = 0;
1509 hdr3->si = 0;
1510 hdr3->cv = 10;
1511 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1512 hdr3->tfi_lo = tfi & 0x7;
1513 hdr3->bsn1_hi = ((i)&0x1f);
1514 hdr3->bsn1_lo = ((i)/32);
1515 hdr3->cps_hi = 0;
1516 hdr3->cps_lo = 0;
1517 hdr3->spb = 0;
1518 hdr3->rsb = 0;
1519 hdr3->pi = 0;
1520 hdr3->spare = 0;
1521 hdr3->dummy = 1;
1522 data[4] = 0x0;
1523 data[5] = 0x0;
1524 data[6] = 0x2b;
1525 data[7] = 0x2b;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001526 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301527 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1528 }
1529 ul_tbf->create_ul_ack(*fn, ts_no);
1530 memset(data, 0x2b, sizeof(data));
1531 hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data;
1532 hdr3->r = 0;
1533 hdr3->si = 0;
1534 hdr3->cv = 0;
1535 hdr3->tfi_hi = (tfi >> 3) & 0x3;
1536 hdr3->tfi_lo = tfi & 0x7;
1537 hdr3->bsn1_hi = 0;
1538 hdr3->bsn1_lo = 2;
1539 hdr3->cps_hi = 0;
1540 hdr3->cps_lo = 0;
1541 hdr3->spb = 0;
1542 hdr3->rsb = 0;
1543 hdr3->pi = 0;
1544 hdr3->spare = 0;
1545 hdr3->dummy = 1;
1546 data[4] = 0x0;
1547 data[5] = 0x2b;
1548 data[6] = 0x2b;
1549 data[7] = 0x2b;
1550
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001551 pdch = &bts->trx[trx_no].pdch[ts_no];
sivasankari1d8744c2017-01-24 15:53:35 +05301552 pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
1553
1554 request_dl_rlc_block(ul_tbf, fn);
1555
1556 check_tbf(ul_tbf);
Max088c7df2018-01-23 20:16:23 +01001557 OSMO_ASSERT(ul_tbf->ul_ack_state_is(GPRS_RLCMAC_UL_ACK_NONE));
sivasankari1d8744c2017-01-24 15:53:35 +05301558
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001559 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
sivasankari1d8744c2017-01-24 15:53:35 +05301560 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001561 OSMO_ASSERT(ms_ta(ms) == qta/4);
1562 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
sivasankari1d8744c2017-01-24 15:53:35 +05301563
1564 return ul_tbf;
1565}
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001566static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001567 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001568 uint8_t ms_class, uint8_t egprs_ms_class)
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001569{
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001570 GprsMs *ms;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001571 uint32_t rach_fn = *fn - 51;
1572 uint32_t sba_fn = *fn + 52;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001573 uint8_t trx_no = 0;
1574 int tfi = 0;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001575 gprs_rlcmac_ul_tbf *ul_tbf;
1576 struct gprs_rlcmac_pdch *pdch;
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001577 RlcMacUplink_t ulreq = {0};
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001578
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001579 /* needed to set last_rts_fn in the PDCH object */
Max878bd1f2016-07-20 13:05:05 +02001580 request_dl_rlc_block(bts, trx_no, ts_no, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001581
bhargava959d1de2016-08-17 15:17:21 +05301582 /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001583 bts_handle_rach(bts, 0x73, rach_fn, qta);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001584
1585 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001586 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001587
1588 /* fake a resource request */
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001589 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
1590 ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
1591 ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */
1592 ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001593 ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability2 = 1;
1594 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001595 Count_MS_RA_capability_value = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001596 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001597 MS_RA_capability_value[0].u.Content.Exist_Multislot_capability = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001598 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001599 MS_RA_capability_value[0].u.Content.Multislot_capability.
1600 Exist_GPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001601 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001602 MS_RA_capability_value[0].u.Content.Multislot_capability.
1603 GPRS_multislot_class = ms_class;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001604 if (egprs_ms_class) {
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001605 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001606 MS_RA_capability_value[0].u.Content.Multislot_capability.
1607 Exist_EGPRS_multislot_class = 1;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01001608 ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability2.
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001609 MS_RA_capability_value[0].u.Content.Multislot_capability.
1610 EGPRS_multislot_class = ms_class;
1611 }
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001612
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001613 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001614
1615 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001616 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001617 OSMO_ASSERT(ul_tbf != NULL);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +02001618 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001619
1620 /* send packet uplink assignment */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001621 *fn = sba_fn;
Jacob Erlbeckcef20ae2015-08-24 12:00:33 +02001622 request_dl_rlc_block(ul_tbf, fn);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001623
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001624 /* send real acknowledgement */
1625 send_control_ack(ul_tbf);
1626
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001627 check_tbf(ul_tbf);
1628
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001629 /* send fake data */
1630 uint8_t data_msg[23] = {
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001631 0x00 | 0xf << 2, /* GPRS_RLCMAC_DATA_BLOCK << 6, CV = 15 */
1632 uint8_t(0 | (tfi << 1)),
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001633 uint8_t(1), /* BSN:7, E:1 */
1634 };
1635
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001636 pdch = &bts->trx[trx_no].pdch[ts_no];
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001637 pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001638
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001639 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001640 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001641 OSMO_ASSERT(ms_ta(ms) == qta/4);
1642 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001643
1644 return ul_tbf;
1645}
1646
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001647static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char *imsi,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001648 const uint8_t *data, unsigned data_size)
1649{
1650 GprsMs *ms, *ms2;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001651
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001652 ms = bts_ms_store(bts)->get_ms(tlli, 0, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001653
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001654 gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, 0, 0,
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001655 1000, data, data_size);
1656
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001657 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001658 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001659 OSMO_ASSERT(ms_dl_tbf(ms) != NULL);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001660
1661 if (imsi[0] && strcmp(imsi, "000") != 0) {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001662 ms2 = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001663 OSMO_ASSERT(ms == ms2);
1664 }
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001665}
1666
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001667static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t *fn,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001668 uint8_t slots = 0xff)
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001669{
1670 gprs_rlcmac_dl_tbf *dl_tbf;
1671 GprsMs *ms;
1672 unsigned ts_no;
1673
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001674 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001675 OSMO_ASSERT(ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001676 dl_tbf = ms_dl_tbf(ms);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001677 OSMO_ASSERT(dl_tbf);
1678
1679 while (dl_tbf->have_data()) {
1680 uint8_t bn = fn2bn(*fn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001681 for (ts_no = 0 ; ts_no < 8; ts_no += 1) {
1682 if (!(slots & (1 << ts_no)))
1683 continue;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001684 gprs_rlcmac_rcv_rts_block(bts,
Max878bd1f2016-07-20 13:05:05 +02001685 dl_tbf->trx->trx_no, ts_no,
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001686 *fn, bn);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001687 }
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001688 *fn = fn_add_blocks(*fn, 1);
1689 }
1690}
1691
Max4c112dc2018-02-01 16:49:23 +01001692static inline void print_ta_tlli(const gprs_rlcmac_ul_tbf *ul_tbf, bool print_ms)
1693{
1694 fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta());
1695 if (print_ms)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001696 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 +01001697}
1698
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001699static void test_tbf_single_phase()
1700{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001701 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001702 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001703 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001704 int ts_no = 7;
Philippd935d882016-11-07 13:07:36 +01001705 uint32_t fn = DUMMY_FN; /* 17,25,9 */
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001706 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001707 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001708 uint16_t qta = 31;
1709 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001710
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001711 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001712
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001713 setup_bts(bts, ts_no);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001714
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001715 ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli, &fn, qta);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001716
Max4c112dc2018-02-01 16:49:23 +01001717 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001718 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001719
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001720 fprintf(stderr, "=== end %s ===\n", __func__);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001721 TALLOC_FREE(the_pcu);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001722}
1723
sivasankari1d8744c2017-01-24 15:53:35 +05301724static void test_tbf_egprs_two_phase_puan(void)
1725{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001726 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001727 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001728 struct gprs_rlcmac_bts *bts = the_pcu->bts;
sivasankari1d8744c2017-01-24 15:53:35 +05301729 int ts_no = 7;
1730 uint32_t fn = 2654218;
1731 uint16_t qta = 31;
1732 uint32_t tlli = 0xf1223344;
1733 const char *imsi = "0011223344";
1734 uint8_t ms_class = 1;
sivasankari1d8744c2017-01-24 15:53:35 +05301735 uint8_t egprs_ms_class = 1;
1736 gprs_rlcmac_ul_tbf *ul_tbf;
sivasankari1d8744c2017-01-24 15:53:35 +05301737 uint8_t test_data[256];
1738
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001739 fprintf(stderr, "=== start %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301740
1741 memset(test_data, 1, sizeof(test_data));
1742
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001743 setup_bts(bts, ts_no, 4);
1744 bts->initial_mcs_dl = 9;
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001745 the_pcu->vty.ws_base = 128;
1746 the_pcu->vty.ws_pdch = 64;
sivasankari1d8744c2017-01-24 15:53:35 +05301747
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001748 ul_tbf = establish_ul_tbf(bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class);
sivasankari1d8744c2017-01-24 15:53:35 +05301749 /* Function to generate URBB with no length */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001750 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301751 qta, ms_class, egprs_ms_class, ul_tbf);
1752
Max4c112dc2018-02-01 16:49:23 +01001753 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001754 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301755
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001756 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301757 /* Function to generate URBB with length */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001758 ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301759 qta, ms_class, egprs_ms_class, ul_tbf);
1760
Max4c112dc2018-02-01 16:49:23 +01001761 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001762 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301763
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02001764 static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state();
sivasankari1d8744c2017-01-24 15:53:35 +05301765 /* Function to generate CRBB */
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01001766 the_pcu->vty.ws_base = 128;
1767 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001768 ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, ts_no, tlli, &fn,
sivasankari1d8744c2017-01-24 15:53:35 +05301769 qta, ms_class, egprs_ms_class);
1770
Max4c112dc2018-02-01 16:49:23 +01001771 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001772 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
sivasankari1d8744c2017-01-24 15:53:35 +05301773
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001774 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001775 fprintf(stderr, "=== end %s ===\n", __func__);
sivasankari1d8744c2017-01-24 15:53:35 +05301776}
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301777/*
1778 * Trigger rach for single block
1779 */
1780static void test_immediate_assign_rej_single_block()
1781{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001782 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001783 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001784 struct gprs_rlcmac_bts *bts = the_pcu->bts;
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301785 uint32_t fn = 2654218;
1786 uint16_t qta = 31;
1787 int ts_no = 7;
1788
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001789 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301790
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001791 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301792
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001793 bts->trx[0].pdch[ts_no].disable();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301794
1795 uint32_t rach_fn = fn - 51;
1796
1797 int rc = 0;
1798
1799 /*
1800 * simulate RACH, sends an Immediate Assignment
1801 * Uplink reject on the AGCH
1802 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001803 rc = bts_handle_rach(bts, 0x70, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301804
1805 OSMO_ASSERT(rc == -EINVAL);
1806
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001807 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001808 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301809}
1810
1811/*
1812 * Trigger rach till resources(USF) exhaust
1813 */
1814static void test_immediate_assign_rej_multi_block()
1815{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001816 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001817 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001818 struct gprs_rlcmac_bts *bts = the_pcu->bts;
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301819 uint32_t fn = 2654218;
1820 uint16_t qta = 31;
1821 int ts_no = 7;
1822
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001823 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301824
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001825 setup_bts(bts, ts_no, 4);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301826
1827 uint32_t rach_fn = fn - 51;
1828
1829 int rc = 0;
1830
1831 /*
1832 * simulate RACH, sends an Immediate Assignment Uplink
1833 * reject on the AGCH
1834 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001835 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
1836 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
1837 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
1838 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
1839 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
1840 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
1841 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
1842 rc = bts_handle_rach(bts, 0x7f, rach_fn, qta);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301843
1844 OSMO_ASSERT(rc == -EBUSY);
1845
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001846 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001847 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05301848}
1849
1850static void test_immediate_assign_rej()
1851{
1852 test_immediate_assign_rej_multi_block();
1853 test_immediate_assign_rej_single_block();
1854}
1855
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001856static void test_tbf_two_phase()
1857{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001858 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001859 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001860 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001861 int ts_no = 7;
1862 uint32_t fn = 2654218;
1863 uint16_t qta = 31;
1864 uint32_t tlli = 0xf1223344;
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001865 const char *imsi = "0011223344";
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001866 uint8_t ms_class = 1;
1867 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001868
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001869 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001870
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001871 setup_bts(bts, ts_no, 4);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001872
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001873 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001874 ms_class, 0);
Jacob Erlbeck4a6fe532015-08-19 14:00:43 +02001875
Max4c112dc2018-02-01 16:49:23 +01001876 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001877 send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4);
Jacob Erlbeck076f5c72015-08-21 18:00:54 +02001878
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001879 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001880 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02001881}
1882
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001883static inline void print_ms(GprsMs *ms, bool old)
Max4c112dc2018-02-01 16:49:23 +01001884{
1885 fprintf(stderr, "%s MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %zu\n",
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001886 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 +01001887}
1888
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001889static void test_tbf_ra_update_rach()
1890{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001891 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001892 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001893 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001894 int ts_no = 7;
1895 uint32_t fn = 2654218;
1896 uint16_t qta = 31;
1897 uint32_t tlli1 = 0xf1223344;
1898 uint32_t tlli2 = 0xf5667788;
1899 const char *imsi = "0011223344";
1900 uint8_t ms_class = 1;
1901 gprs_rlcmac_ul_tbf *ul_tbf;
1902 GprsMs *ms, *ms1, *ms2;
1903
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001904 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001905
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001906 setup_bts(bts, ts_no, 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001907
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001908 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001909 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001910
1911 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001912 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001913
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001914 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"RAU_ACCEPT", 10);
Max4c112dc2018-02-01 16:49:23 +01001915 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001916
Jacob Erlbeckaf454732015-08-21 15:03:23 +02001917 /* Send Packet Downlink Assignment to MS */
1918 request_dl_rlc_block(ul_tbf, &fn);
1919
1920 /* Ack it */
1921 send_control_ack(ul_tbf);
1922
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001923 /* Make sure the RAU Accept gets sent to the MS */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001924 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 1);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001925 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001926 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001927
1928 /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001929 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli2, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001930 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001931
1932 ms2 = ul_tbf->ms();
1933
1934 /* The PCU cannot know yet, that both TBF belong to the same MS */
1935 OSMO_ASSERT(ms1 != ms2);
Max4c112dc2018-02-01 16:49:23 +01001936 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001937
1938 /* Send some downlink data along with the new TLLI and the IMSI so that
1939 * the PCU can see, that both MS objects belong to same MS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001940 send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001941
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001942 ms = bts_ms_by_imsi(bts, imsi);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001943 OSMO_ASSERT(ms == ms2);
1944
Max4c112dc2018-02-01 16:49:23 +01001945 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001946
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001947 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001948 OSMO_ASSERT(ms == NULL);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001949 ms = bts_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001950 OSMO_ASSERT(ms == ms2);
1951
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001952 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001953 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001954}
1955
1956static void test_tbf_dl_flow_and_rach_two_phase()
1957{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01001958 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001959 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001960 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001961 int ts_no = 7;
1962 uint32_t fn = 2654218;
1963 uint16_t qta = 31;
1964 uint32_t tlli1 = 0xf1223344;
1965 const char *imsi = "0011223344";
1966 uint8_t ms_class = 1;
1967 gprs_rlcmac_ul_tbf *ul_tbf;
1968 gprs_rlcmac_dl_tbf *dl_tbf;
1969 GprsMs *ms, *ms1, *ms2;
1970
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02001971 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001972
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001973 setup_bts(bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001974
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001975 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001976 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001977
1978 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001979 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001980
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001981 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
1982 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01001983 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001984
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01001985 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
1986 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001987 OSMO_ASSERT(dl_tbf != NULL);
1988
1989 /* Get rid of old UL TBF */
1990 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001991 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001992 OSMO_ASSERT(ms1 == ms);
1993
1994 /* Now establish a new UL TBF, this will consume one LLC packet */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001995 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01001996 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02001997
1998 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01001999 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002000
2001 /* This should be the same MS object */
2002 OSMO_ASSERT(ms2 == ms1);
2003
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002004 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002005 OSMO_ASSERT(ms2 == ms);
2006
Jacob Erlbeckc8cbfc22015-09-01 11:38:40 +02002007 /* A DL TBF should still exist */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002008 OSMO_ASSERT(ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002009
2010 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002011 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002012
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002013 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002014 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002015}
2016
2017
2018static void test_tbf_dl_flow_and_rach_single_phase()
2019{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002020 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002021 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002022 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002023 int ts_no = 7;
2024 uint32_t fn = 2654218;
2025 uint16_t qta = 31;
2026 uint32_t tlli1 = 0xf1223344;
2027 const char *imsi = "0011223344";
2028 uint8_t ms_class = 1;
2029 gprs_rlcmac_ul_tbf *ul_tbf;
2030 gprs_rlcmac_dl_tbf *dl_tbf;
2031 GprsMs *ms, *ms1, *ms2;
2032
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002033 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002034
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002035 setup_bts(bts, ts_no, 1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002036
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002037 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002038 ms_class, 0);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002039
2040 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002041 print_ta_tlli(ul_tbf, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002042
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002043 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 1 *************", 20);
2044 send_dl_data(bts, tlli1, imsi, (const uint8_t *)"DATA 2 *************", 20);
Max4c112dc2018-02-01 16:49:23 +01002045 print_ms(ms1, true);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002046
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002047 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 2);
2048 dl_tbf = ms_dl_tbf(ms1);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002049 OSMO_ASSERT(dl_tbf != NULL);
2050
2051 /* Get rid of old UL TBF */
2052 tbf_free(ul_tbf);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002053 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002054 OSMO_ASSERT(ms1 == ms);
2055
2056 /* Now establish a new UL TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002057 ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli1, &fn, qta);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002058
2059 ms2 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002060 print_ms(ms2, false);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002061
2062 /* There should be a different MS object */
2063 OSMO_ASSERT(ms2 != ms1);
2064
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002065 ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002066 OSMO_ASSERT(ms2 == ms);
2067 OSMO_ASSERT(ms1 != ms);
2068
Jacob Erlbeck5f93f852016-01-21 20:48:39 +01002069 /* DL TBF should be removed */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002070 OSMO_ASSERT(!ms_dl_tbf(ms));
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002071
2072 /* No queued packets should be lost */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002073 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms)) == 2);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002074
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002075 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002076 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeckb1395982015-08-21 18:15:38 +02002077}
2078
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002079static void test_tbf_dl_reuse()
2080{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002081 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002082 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002083 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002084 int ts_no = 7;
2085 uint32_t fn = 2654218;
2086 uint16_t qta = 31;
2087 uint32_t tlli1 = 0xf1223344;
2088 const char *imsi = "0011223344";
2089 uint8_t ms_class = 1;
2090 gprs_rlcmac_ul_tbf *ul_tbf;
2091 gprs_rlcmac_dl_tbf *dl_tbf1, *dl_tbf2;
2092 GprsMs *ms1, *ms2;
2093 unsigned i;
2094 RlcMacUplink_t ulreq = {0};
2095
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002096 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002097
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002098 setup_bts(bts, ts_no, 1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002099
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002100 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002101 ms_class, 0);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002102
2103 ms1 = ul_tbf->ms();
Max4c112dc2018-02-01 16:49:23 +01002104 print_ta_tlli(ul_tbf, false);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002105
2106 /* Send some LLC frames */
2107 for (i = 0; i < 40; i++) {
2108 char buf[32];
2109 int rc;
2110
2111 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i", i);
2112 OSMO_ASSERT(rc > 0);
2113
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002114 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002115 }
2116
Max4c112dc2018-02-01 16:49:23 +01002117 print_ms(ms1, true);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002118
2119 /* Send Packet Downlink Assignment to MS */
2120 request_dl_rlc_block(ul_tbf, &fn);
2121
2122 /* Ack it */
2123 send_control_ack(ul_tbf);
2124
2125 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002126 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002127 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms1)) == 0);
2128 OSMO_ASSERT(ms_dl_tbf(ms1));
2129 OSMO_ASSERT(ms_dl_tbf(ms1)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002130
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002131 dl_tbf1 = ms_dl_tbf(ms1);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002132
2133 /* Send some LLC frames */
2134 for (i = 0; i < 10; i++) {
2135 char buf[32];
2136 int rc;
2137
2138 rc = snprintf(buf, sizeof(buf), "LLC PACKET %02i (TBF 2)", i);
2139 OSMO_ASSERT(rc > 0);
2140
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002141 send_dl_data(bts, tlli1, imsi, (const uint8_t *)buf, rc);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002142 }
2143
2144 /* Fake Final DL Ack/Nack */
2145 ulreq.u.MESSAGE_TYPE = MT_PACKET_DOWNLINK_ACK_NACK;
2146 Packet_Downlink_Ack_Nack_t *ack = &ulreq.u.Packet_Downlink_Ack_Nack;
2147
2148 ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2149 ack->DOWNLINK_TFI = dl_tbf1->tfi();
2150 ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1;
2151
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002152 send_ul_mac_block(bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002153
2154 OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE));
2155
2156 request_dl_rlc_block(dl_tbf1, &fn);
2157
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002158 ms2 = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002159 OSMO_ASSERT(ms2 == ms1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002160 OSMO_ASSERT(ms_dl_tbf(ms2));
2161 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_ASSIGN));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002162
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002163 dl_tbf2 = ms_dl_tbf(ms2);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002164
2165 OSMO_ASSERT(dl_tbf1 != dl_tbf2);
2166
2167 send_control_ack(dl_tbf1);
Jacob Erlbeck6835cea2015-08-21 15:24:02 +02002168 OSMO_ASSERT(dl_tbf2->state_is(GPRS_RLCMAC_FLOW));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002169
2170 /* Transmit all data */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002171 transmit_dl_data(bts, tlli1, &fn);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002172 OSMO_ASSERT(llc_queue_size(ms_llc_queue(ms2)) == 0);
2173 OSMO_ASSERT(ms_dl_tbf(ms2));
2174 OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(GPRS_RLCMAC_FINISHED));
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002175
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002176 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002177 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02002178}
2179
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002180static void test_tbf_gprs_egprs()
2181{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002182 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002183 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002184 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002185 uint8_t ts_no = 4;
2186 uint8_t ms_class = 45;
2187 int rc = 0;
2188 uint32_t tlli = 0xc0006789;
2189 const char *imsi = "001001123456789";
2190 unsigned delay_csec = 1000;
2191
2192 uint8_t buf[256] = {0};
2193
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002194 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002195
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002196 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2197 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002198 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2199 abort();
2200 }
2201
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002202 setup_bts(bts, ts_no);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002203
2204 /* EGPRS-only */
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002205
Alexander Couzens290d9032020-09-16 21:52:02 +02002206 gprs_bssgp_init(bts, 3234, 3234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002207
2208 /* Does not support EGPRS */
2209 rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0,
2210 delay_csec, buf, sizeof(buf));
2211
Pau Espin Pedrol569f0d22020-10-27 14:45:20 +01002212 OSMO_ASSERT(rc == 0);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002213 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002214
Alexander Couzens290d9032020-09-16 21:52:02 +02002215 gprs_bssgp_destroy(bts);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002216 TALLOC_FREE(the_pcu);
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01002217}
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02002218
Max4c112dc2018-02-01 16:49:23 +01002219static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws,
2220 bool free, bool end)
2221{
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002222 gprs_rlcmac_bts *bts = dl_tbf->bts;
Max4c112dc2018-02-01 16:49:23 +01002223 if (!dl_tbf) {
2224 fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test);
2225 return;
2226 }
2227
2228 fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d",
2229 dl_tbf->dl_slots(),
2230 pcu_bitcount(dl_tbf->dl_slots()),
2231 dl_tbf->window_size());
2232
2233 if (pcu_bitcount(dl_tbf->dl_slots()) != exp_slots || dl_tbf->window_size() != exp_ws)
2234 fprintf(stderr, "%s(): DL TBF FAILED: dl_slots = %u (exp. %u), WS = %u (exp. %u)",
2235 test, pcu_bitcount(dl_tbf->dl_slots()), 4, dl_tbf->window_size(), 128 + 4 * 64);
2236
2237 fprintf(stderr, "\n");
2238
2239 if (free)
2240 tbf_free(dl_tbf);
2241
2242 if (end) {
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002243 fprintf(stderr, "=== end %s ===\n", test);
Alexander Couzens290d9032020-09-16 21:52:02 +02002244 gprs_bssgp_destroy(bts);
Max4c112dc2018-02-01 16:49:23 +01002245 }
2246}
2247
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002248static void test_tbf_ws()
2249{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002250 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002251 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002252 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002253 GprsMs *ms;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002254 uint8_t ts_no = 4;
2255 uint8_t ms_class = 12;
2256 gprs_rlcmac_dl_tbf *dl_tbf;
2257
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002258 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002259
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002260 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2261 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002262 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2263 abort();
2264 }
2265
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002266 setup_bts(bts, ts_no);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002267
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002268 the_pcu->vty.ws_base = 128;
2269 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002270 the_pcu->alloc_algorithm = alloc_algorithm_b;
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002271 bts->trx[0].pdch[2].enable();
2272 bts->trx[0].pdch[3].enable();
2273 bts->trx[0].pdch[4].enable();
2274 bts->trx[0].pdch[5].enable();
2275
Alexander Couzens290d9032020-09-16 21:52:02 +02002276 gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002277
2278 /* Does no support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002279 ms = bts_alloc_ms(bts, ms_class, 0);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002280 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Max4c112dc2018-02-01 16:49:23 +01002281
2282 ws_check(dl_tbf, __func__, 4, 64, true, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002283
2284 /* EGPRS-only */
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002285
2286 /* Does support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002287 ms = bts_alloc_ms(bts, ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002288 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002289
Max4c112dc2018-02-01 16:49:23 +01002290 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002291 TALLOC_FREE(the_pcu);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01002292}
2293
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302294static void test_tbf_update_ws(void)
2295{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002296 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002297 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002298 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002299 GprsMs *ms;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302300 uint8_t ts_no = 4;
2301 uint8_t ms_class = 11;
2302 gprs_rlcmac_dl_tbf *dl_tbf;
2303
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002304 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302305
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002306 bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL);
2307 if (!bts->pcu->nsi) {
Alexander Couzens5c3783b2019-05-25 05:41:18 +02002308 LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
2309 abort();
2310 }
2311
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002312 setup_bts(bts, ts_no);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302313
Pau Espin Pedrol519d0712021-01-14 14:30:03 +01002314 the_pcu->vty.ws_base = 128;
2315 the_pcu->vty.ws_pdch = 64;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002316 the_pcu->alloc_algorithm = alloc_algorithm_b;
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302317 bts->trx[0].pdch[2].enable();
2318 bts->trx[0].pdch[3].enable();
2319 bts->trx[0].pdch[4].enable();
2320 bts->trx[0].pdch[5].enable();
2321
Alexander Couzens290d9032020-09-16 21:52:02 +02002322 gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302323
2324 /* EGPRS-only */
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302325
2326 /* Does support EGPRS */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002327 ms = bts_alloc_ms(bts, ms_class, ms_class);
Pau Espin Pedrol322456e2020-05-08 18:15:59 +02002328 dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, true);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302329
Max4c112dc2018-02-01 16:49:23 +01002330 ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302331
2332 dl_tbf->update();
2333
Aravind Sirsikar0ee31cf2016-09-15 17:54:46 +05302334 /* window size should be 384 */
Max4c112dc2018-02-01 16:49:23 +01002335 ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002336 TALLOC_FREE(the_pcu);
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05302337}
2338
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302339static void test_tbf_puan_urbb_len(void)
2340{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002341 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002342 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002343 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302344 int ts_no = 7;
2345 uint32_t fn = 2654218;
2346 uint16_t qta = 31;
2347 uint32_t tlli = 0xf1223344;
2348 const char *imsi = "0011223344";
2349 uint8_t ms_class = 1;
2350 uint8_t egprs_ms_class = 1;
2351 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302352 uint8_t test_data[256];
2353
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002354 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302355
2356 memset(test_data, 1, sizeof(test_data));
2357
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002358 setup_bts(bts, ts_no, 4);
2359 bts->initial_mcs_dl = 9;
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302360
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002361 ul_tbf = puan_urbb_len_issue(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302362 ms_class, egprs_ms_class);
2363
Max4c112dc2018-02-01 16:49:23 +01002364 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002365 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302366
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002367 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002368 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar02352b42016-08-25 16:37:30 +05302369}
2370
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002371static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302372 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
2373 uint8_t ms_class, uint8_t egprs_ms_class)
2374{
2375 GprsMs *ms;
2376 uint32_t rach_fn = *fn - 51;
2377 uint32_t sba_fn = *fn + 52;
2378 uint8_t trx_no = 0;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002379 int tfi = 0;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302380 gprs_rlcmac_ul_tbf *ul_tbf;
2381 struct gprs_rlcmac_pdch *pdch;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302382 RlcMacUplink_t ulreq = {0};
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302383 struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302384 Packet_Resource_Request_t *presreq = NULL;
2385 MS_Radio_Access_capability_t *pmsradiocap = NULL;
2386 Multislot_capability_t *pmultislotcap = NULL;
2387
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302388 /* needed to set last_rts_fn in the PDCH object */
2389 request_dl_rlc_block(bts, trx_no, ts_no, fn);
2390
2391 /*
2392 * simulate RACH, this sends an Immediate
2393 * Assignment Uplink on the AGCH
2394 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002395 bts_handle_rach(bts, 0x73, rach_fn, qta);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302396
2397 /* get next free TFI */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002398 tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302399
2400 /* fake a resource request */
2401 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
2402 presreq = &ulreq.u.Packet_Resource_Request;
2403 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
2404 presreq->ID.UnionType = 1; /* != 0 */
2405 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01002406 presreq->Exist_MS_Radio_Access_capability2 = 1;
2407 pmsradiocap = &presreq->MS_Radio_Access_capability2;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302408 pmsradiocap->Count_MS_RA_capability_value = 1;
2409 pmsradiocap->MS_RA_capability_value[0].u.Content.
2410 Exist_Multislot_capability = 1;
2411 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
2412 u.Content.Multislot_capability;
2413
2414 pmultislotcap->Exist_GPRS_multislot_class = 1;
2415 pmultislotcap->GPRS_multislot_class = ms_class;
2416 if (egprs_ms_class) {
2417 pmultislotcap->Exist_EGPRS_multislot_class = 1;
2418 pmultislotcap->EGPRS_multislot_class = ms_class;
2419 }
2420
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002421 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302422
2423 /* check the TBF */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002424 ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302425 OSMO_ASSERT(ul_tbf);
2426 OSMO_ASSERT(ul_tbf->ta() == qta / 4);
2427
2428 /* send packet uplink assignment */
2429 *fn = sba_fn;
2430 request_dl_rlc_block(ul_tbf, fn);
2431
2432 /* send real acknowledgement */
2433 send_control_ack(ul_tbf);
2434
2435 check_tbf(ul_tbf);
2436
2437 uint8_t data_msg[49] = {0};
2438
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002439 pdch = &bts->trx[trx_no].pdch[ts_no];
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302440
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002441 ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302442 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002443 OSMO_ASSERT(ms_ta(ms) == qta/4);
2444 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302445
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302446 egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
2447 egprs3->si = 0;
2448 egprs3->r = 1;
2449 egprs3->cv = 7;
2450 egprs3->tfi_hi = tfi & 0x03;
2451 egprs3->tfi_lo = (tfi & 0x1c) >> 2;
2452 egprs3->bsn1_hi = 0;
2453 egprs3->bsn1_lo = 0;
2454 egprs3->cps_hi = 1;
2455 data_msg[3] = 0xff;
2456 egprs3->pi = 0;
2457 egprs3->cps_lo = 1;
2458 egprs3->rsb = 0;
2459 egprs3->spb = 0;
2460 egprs3->pi = 0;
2461 pdch->rcv_block(data_msg, 49, *fn, &meas);
2462
2463 egprs3->bsn1_hi = 1;
2464 egprs3->bsn1_lo = 0;
2465 data_msg[3] = 0x7f;
2466 egprs3->cps_lo = 1;
2467 egprs3->rsb = 0;
2468 egprs3->spb = 0;
2469 egprs3->pi = 0;
2470 data_msg[4] = 0x2;
2471 data_msg[5] = 0x0;
2472 pdch->rcv_block(data_msg, 49, *fn, &meas);
2473
Aravind Sirsikar22a90192016-09-15 17:24:49 +05302474 OSMO_ASSERT(ul_tbf->m_llc.m_index == 43);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302475
2476 return ul_tbf;
2477}
2478
2479static void test_tbf_li_decoding(void)
2480{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002481 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002482 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002483 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302484 int ts_no = 7;
2485 uint32_t fn = 2654218;
2486 uint16_t qta = 31;
2487 uint32_t tlli = 0xf1223344;
2488 const char *imsi = "0011223344";
2489 uint8_t ms_class = 1;
2490 uint8_t egprs_ms_class = 1;
2491 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302492 uint8_t test_data[256];
2493
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002494 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302495
2496 memset(test_data, 1, sizeof(test_data));
2497
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002498 setup_bts(bts, ts_no, 4);
2499 bts->initial_mcs_dl = 9;
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302500
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002501 ul_tbf = tbf_li_decoding(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302502 ms_class, egprs_ms_class);
2503
Max4c112dc2018-02-01 16:49:23 +01002504 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002505 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302506
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002507 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002508 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05302509}
2510
aravind sirsikarf2761382016-10-25 12:45:24 +05302511/*
2512 * Test that a bit within the uncompressed bitmap whose BSN is not within
2513 * the transmit window shall be ignored. See section 9.1.8.2.4 of 44.060
2514 * version 7.27.0 Release 7.
2515 */
2516static void test_tbf_epdan_out_of_rx_window(void)
2517{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002518 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002519 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002520 struct gprs_rlcmac_bts *bts = the_pcu->bts;
aravind sirsikarf2761382016-10-25 12:45:24 +05302521 uint8_t ms_class = 11;
2522 uint8_t egprs_ms_class = 11;
2523 uint8_t trx_no;
2524 uint32_t tlli = 0xffeeddcc;
2525 gprs_rlcmac_dl_tbf *dl_tbf;
2526 int ts_no = 4;
2527 bitvec *block;
2528 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
2529 bitvec bits;
2530 int bsn_begin, bsn_end;
2531 EGPRS_PD_AckNack_t *ack_nack;
2532 RlcMacUplink_t ul_control_block;
2533 gprs_rlc_v_b *prlcmvb;
2534 gprs_rlc_dl_window *prlcdlwindow;
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002535 int rc;
aravind sirsikarf2761382016-10-25 12:45:24 +05302536
aravind sirsikarcc4214a2016-12-09 16:12:42 +05302537 memset(&ul_control_block, 0, sizeof(RlcMacUplink_t));
2538
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002539 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302540
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002541 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01002542 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302543 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01002544 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
aravind sirsikarf2761382016-10-25 12:45:24 +05302545
2546 /*
2547 * Simulate a message captured during over-the-air testing,
2548 * where the following values were observed:
2549 * v_a = 1176, vs = 1288, max sns = 2048, window size = 480.
2550 */
2551 uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
2552 0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
2553 0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
2554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2555
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002556 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
aravind sirsikarf2761382016-10-25 12:45:24 +05302557 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002558 prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window());
aravind sirsikarf2761382016-10-25 12:45:24 +05302559 prlcmvb = &prlcdlwindow->m_v_b;
2560 prlcdlwindow->m_v_s = 1288;
2561 prlcdlwindow->m_v_a = 1176;
2562 prlcdlwindow->set_sns(2048);
2563 prlcdlwindow->set_ws(480);
2564 prlcmvb->mark_unacked(1176);
2565 prlcmvb->mark_unacked(1177);
2566 prlcmvb->mark_unacked(1286);
2567 prlcmvb->mark_unacked(1287);
2568
2569 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2570
Alexander Couzensccde5c92017-02-04 03:10:08 +01002571 block = bitvec_alloc(23, tall_pcu_ctx);
aravind sirsikarf2761382016-10-25 12:45:24 +05302572
2573 bitvec_unpack(block, data_msg);
2574
2575 bits.data = bits_data;
2576 bits.data_len = sizeof(bits_data);
2577 bits.cur_bit = 0;
2578
Pau Espin Pedrol5e300ce2020-02-03 17:18:03 +01002579 rc = decode_gsm_rlcmac_uplink(block, &ul_control_block);
2580 OSMO_ASSERT(rc == 0);
aravind sirsikarf2761382016-10-25 12:45:24 +05302581
2582 ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
2583
2584 OSMO_ASSERT(prlcmvb->is_unacked(1176));
2585 OSMO_ASSERT(prlcmvb->is_unacked(1177));
2586 OSMO_ASSERT(prlcmvb->is_unacked(1286));
2587 OSMO_ASSERT(prlcmvb->is_unacked(1287));
2588
2589 Decoding::decode_egprs_acknack_bits(
2590 &ack_nack->EGPRS_AckNack.Desc, &bits,
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002591 &bsn_begin, &bsn_end, prlcdlwindow);
aravind sirsikarf2761382016-10-25 12:45:24 +05302592
2593 dl_tbf->rcvd_dl_ack(
2594 ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
2595 bsn_begin, &bits);
aravind sirsikarf2761382016-10-25 12:45:24 +05302596
aravind sirsikarfb41afa2016-11-02 15:48:00 +05302597 OSMO_ASSERT(prlcmvb->is_invalid(1176));
2598 OSMO_ASSERT(prlcmvb->is_invalid(1177));
2599 OSMO_ASSERT(prlcmvb->is_acked(1286));
2600 OSMO_ASSERT(prlcmvb->is_acked(1287));
aravind sirsikarf2761382016-10-25 12:45:24 +05302601
2602 bitvec_free(block);
2603 tbf_free(dl_tbf);
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002604 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002605 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikarf2761382016-10-25 12:45:24 +05302606}
2607
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302608static void test_tbf_egprs_two_phase_spb(void)
2609{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002610 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002611 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002612 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302613 int ts_no = 7;
2614 uint32_t fn = 2654218;
2615 uint16_t qta = 31;
2616 uint32_t tlli = 0xf1223344;
2617 const char *imsi = "0011223344";
2618 uint8_t ms_class = 1;
2619 uint8_t egprs_ms_class = 1;
2620 gprs_rlcmac_ul_tbf *ul_tbf;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302621 uint8_t test_data[256];
2622
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002623 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302624
2625 memset(test_data, 1, sizeof(test_data));
2626
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002627 setup_bts(bts, ts_no, 4);
2628 bts->initial_mcs_dl = 9;
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302629
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002630 ul_tbf = establish_ul_tbf_two_phase_spb(bts, ts_no, tlli, &fn, qta,
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302631 ms_class, egprs_ms_class);
2632
Max4c112dc2018-02-01 16:49:23 +01002633 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002634 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302635
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002636 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002637 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05302638}
2639
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002640static void test_tbf_egprs_two_phase()
2641{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002642 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01002643 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002644 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002645 int ts_no = 7;
2646 uint32_t fn = 2654218;
2647 uint16_t qta = 31;
2648 uint32_t tlli = 0xf1223344;
2649 const char *imsi = "0011223344";
2650 uint8_t ms_class = 1;
2651 uint8_t egprs_ms_class = 1;
2652 gprs_rlcmac_ul_tbf *ul_tbf;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002653 uint8_t test_data[256];
2654
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002655 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002656
2657 memset(test_data, 1, sizeof(test_data));
2658
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002659 setup_bts(bts, ts_no, 4);
2660 bts->initial_mcs_dl = 9;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002661
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002662 ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta,
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002663 ms_class, egprs_ms_class);
2664
Max4c112dc2018-02-01 16:49:23 +01002665 print_ta_tlli(ul_tbf, true);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002666 send_dl_data(bts, tlli, imsi, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002667
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01002668 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002669 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002670}
2671
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002672static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs)
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002673{
2674 unsigned i;
2675 uint8_t ms_class = 11;
2676 uint8_t egprs_ms_class = 11;
2677 uint32_t fn = 0;
2678 uint8_t trx_no;
2679 uint32_t tlli = 0xffeeddcc;
2680 uint8_t test_data[512];
2681
2682 uint8_t rbb[64/8];
2683
2684 gprs_rlcmac_dl_tbf *dl_tbf;
2685
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002686 fprintf(stderr, "Testing MCS-%d\n", mcs);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002687
2688 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002689 bts->initial_mcs_dl = mcs;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002690
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002691 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002692 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2693
2694 for (i = 0; i < sizeof(llc_data); i++)
2695 llc_data[i] = i%256;
2696
2697 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2698
2699 /* Schedule a small LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002700 dl_tbf->append_data(1000, test_data, 10);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002701
2702 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2703
2704 /* Drain the queue */
2705 while (dl_tbf->have_data())
2706 /* Request to send one RLC/MAC block */
2707 request_dl_rlc_block(dl_tbf, &fn);
2708
2709 /* Schedule a large LLC frame */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002710 dl_tbf->append_data(1000, test_data, sizeof(test_data));
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002711
2712 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2713
2714 /* Drain the queue */
2715 while (dl_tbf->have_data())
2716 /* Request to send one RLC/MAC block */
2717 request_dl_rlc_block(dl_tbf, &fn);
2718
2719 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2720
Max7d32f552017-12-15 11:25:14 +01002721 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002722
2723 /* Clean up and ensure tbfs are in the correct state */
2724 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002725 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01002726 check_tbf(dl_tbf);
2727 tbf_free(dl_tbf);
2728}
2729
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002730static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302731 int mcs)
2732{
2733 unsigned i;
2734 uint8_t ms_class = 11;
2735 uint8_t egprs_ms_class = 11;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302736 uint8_t trx_no;
2737 uint32_t tlli = 0xffeeddcc;
2738 uint8_t test_data[512];
2739
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302740 gprs_rlcmac_dl_tbf *dl_tbf;
2741
2742 memset(test_data, 1, sizeof(test_data));
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002743 bts->initial_mcs_dl = mcs;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302744
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002745 dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302746 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
2747
2748 for (i = 0; i < sizeof(test_data); i++)
2749 test_data[i] = i%256;
2750
2751 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2752
2753 /* Schedule a LLC frame
2754 * passing only 100 bytes, since it is enough to construct
2755 * 2 RLC data blocks. Which are enough to test Header Type 1
2756 * cases
2757 */
Pau Espin Pedrol758ace82020-10-28 19:58:17 +01002758 dl_tbf->append_data(1000, test_data, 100);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302759
2760 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
2761
2762 return dl_tbf;
2763
2764}
2765
2766static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
2767{
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302768 uint8_t rbb[64/8];
2769
Max7d32f552017-12-15 11:25:14 +01002770 RCV_ACK(true, dl_tbf, rbb); /* Receive a final ACK */
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302771
2772 /* Clean up and ensure tbfs are in the correct state */
2773 OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE));
Max0e599802018-01-23 20:09:06 +01002774 TBF_SET_ASS_STATE_DL(dl_tbf, GPRS_RLCMAC_DL_ASS_NONE);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302775 check_tbf(dl_tbf);
2776 tbf_free(dl_tbf);
2777
2778}
2779
Max7d32f552017-12-15 11:25:14 +01002780#define NACK(tbf, x) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002781 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2782 w->m_v_b.mark_nacked(x); \
2783 OSMO_ASSERT(w->m_v_b.is_nacked(x)); \
Max7d32f552017-12-15 11:25:14 +01002784 } while(0)
2785
2786#define CHECK_UNACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002787 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2788 OSMO_ASSERT(w->m_v_b.is_unacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002789 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002790 } while(0)
2791
2792#define CHECK_NACKED(tbf, cs, bsn) do { \
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +02002793 gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window()); \
2794 OSMO_ASSERT(w->m_v_b.is_nacked(bsn)); \
Max898dddb2019-03-12 15:50:57 +01002795 OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \
Max7d32f552017-12-15 11:25:14 +01002796 } while(0)
2797
2798#define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \
2799 m = tbf->create_dl_acked_block(fn, tbf->control_ts); \
2800 OSMO_ASSERT(m); \
2801 if (check_unacked) \
2802 CHECK_UNACKED(tbf, cs, 0); \
2803 else \
2804 CHECK_NACKED(tbf, cs, 0); \
2805 } while(0)
2806
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002807static void egprs_spb_to_normal_validation(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002808 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302809{
2810 uint32_t fn = 0;
2811 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302812 uint16_t bsn1, bsn2, bsn3;
2813 struct msgb *msg;
2814 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2815 struct gprs_rlc_dl_header_egprs_2 *egprs2;
2816
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002817 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302818
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002819 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302820
2821 /*
2822 * Table 10.4.8a.3.1 of 44.060.
2823 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2824 * (MCS5, MCS6) to (MCS2, MCS3) transition
2825 */
2826 if (!(mcs == 6 && demanded_mcs == 3))
2827 return;
2828
2829 fn = fn_add_blocks(fn, 1);
2830 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002831 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302832
2833 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
Maxb4d368b2017-12-01 17:54:39 +01002834 bsn1 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Max7d32f552017-12-15 11:25:14 +01002835
2836 NACK(dl_tbf, 0);
2837
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302838 OSMO_ASSERT(bsn1 == 0);
2839
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002840 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302841
2842 fn = fn_add_blocks(fn, 1);
2843
2844 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002845 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302846 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2847 == EGPRS_RESEG_FIRST_SEG_SENT);
2848
2849 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2850 OSMO_ASSERT(egprs3->spb == 2);
2851
2852 /* Table 10.4.8a.3.1 of 44.060 */
2853 OSMO_ASSERT(egprs3->cps == 3);
2854
2855 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002856 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302857 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2858 == EGPRS_RESEG_SECOND_SEG_SENT);
2859
2860 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2861 /* Table 10.4.8a.3.1 of 44.060 */
2862 OSMO_ASSERT(egprs3->spb == 3);
Maxb4d368b2017-12-01 17:54:39 +01002863 bsn2 = (egprs3->bsn1_hi << 9) | (egprs3->bsn1_mid << 1) | (egprs3->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302864 OSMO_ASSERT(bsn2 == bsn1);
2865
2866 /* Table 10.4.8a.3.1 of 44.060 */
2867 OSMO_ASSERT(egprs3->cps == 3);
2868
2869 /* Handle (MCS3, MCS3) -> MCS6 case */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002870 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302871
Max7d32f552017-12-15 11:25:14 +01002872 NACK(dl_tbf, 0);
2873
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302874 msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
2875 egprs2 = (struct gprs_rlc_dl_header_egprs_2 *) msg->data;
2876
2877 /* Table 10.4.8a.3.1 of 44.060 */
2878 OSMO_ASSERT(egprs2->cps == 0);
Maxb4d368b2017-12-01 17:54:39 +01002879 bsn3 = (egprs2->bsn1_hi << 9) | (egprs2->bsn1_mid << 1) | (egprs2->bsn1_lo);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302880 OSMO_ASSERT(bsn3 == bsn2);
2881
2882 tbf_cleanup(dl_tbf);
2883}
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002884
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002885static void establish_and_use_egprs_dl_tbf_for_spb(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002886 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302887{
2888 uint32_t fn = 0;
2889 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302890 struct msgb *msg;
2891 struct gprs_rlc_dl_header_egprs_3 *egprs3;
2892
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002893 fprintf(stderr, "Testing retx for MCS %u to reseg_mcs %u\n", mcs, demanded_mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302894
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002895 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302896
2897 /*
2898 * Table 10.4.8a.3.1 of 44.060.
2899 * (MCS7, MCS9) to (MCS2, MCS3) is not handled since it is same as
2900 * (MCS5, MCS6) to (MCS2, MCS3) transition
2901 */
2902 /* TODO: Need to support of MCS8 -> MCS6 ->MCS3 transistion
2903 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2904 * dated 2016-02-07 23:45:40 (UTC)
2905 */
2906 if (!(((mcs == 5) && (demanded_mcs == 2)) ||
2907 ((mcs == 6) && (demanded_mcs == 3)) ||
2908 ((mcs == 4) && (demanded_mcs == 1))))
2909 return;
2910
2911 fn = fn_add_blocks(fn, 1);
2912 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01002913 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302914
Max7d32f552017-12-15 11:25:14 +01002915 NACK(dl_tbf, 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302916
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01002917 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302918
2919 fn = fn_add_blocks(fn, 1);
2920
2921 /* Send first segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002922 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, false);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302923 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2924 == EGPRS_RESEG_FIRST_SEG_SENT);
2925
2926 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2927 OSMO_ASSERT(egprs3->spb == 2);
2928
2929 /* Table 10.4.8a.3.1 of 44.060 */
2930 switch (demanded_mcs) {
2931 case 3:
2932 OSMO_ASSERT(egprs3->cps == 3);
2933 break;
2934 case 2:
2935 OSMO_ASSERT(egprs3->cps == 9);
2936 break;
2937 case 1:
2938 OSMO_ASSERT(egprs3->cps == 11);
2939 break;
2940 default:
2941 OSMO_ASSERT(false);
2942 break;
2943 }
2944
2945 /* Send second segment with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01002946 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05302947 OSMO_ASSERT(dl_tbf->m_rlc.block(0)->spb_status.block_status_dl
2948 == EGPRS_RESEG_SECOND_SEG_SENT);
2949
2950 egprs3 = (struct gprs_rlc_dl_header_egprs_3 *) msg->data;
2951 /* Table 10.4.8a.3.1 of 44.060 */
2952 OSMO_ASSERT(egprs3->spb == 3);
2953
2954 /* Table 10.4.8a.3.1 of 44.060 */
2955 switch (demanded_mcs) {
2956 case 3:
2957 OSMO_ASSERT(egprs3->cps == 3);
2958 break;
2959 case 2:
2960 OSMO_ASSERT(egprs3->cps == 9);
2961 break;
2962 case 1:
2963 OSMO_ASSERT(egprs3->cps == 11);
2964 break;
2965 default:
2966 OSMO_ASSERT(false);
2967 break;
2968 }
2969 tbf_cleanup(dl_tbf);
2970}
2971
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002972static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts,
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01002973 unsigned int mcs, unsigned int demanded_mcs)
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302974{
2975 uint32_t fn = 0;
2976 gprs_rlcmac_dl_tbf *dl_tbf;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302977 struct msgb *msg;
2978
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02002979 fprintf(stderr, "Testing retx for MCS %u - %u\n", mcs, demanded_mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302980
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01002981 dl_tbf = tbf_init(bts, mcs);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302982
2983 /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5
2984 * The MCS transition are referred from table Table 8.1.1.2
2985 * of TS 44.060
2986 */
2987 /* TODO: Need to support of MCS8 -> MCS6 transistion
2988 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
2989 * dated 2016-02-07 23:45:40 (UTC)
2990 */
2991 if (((mcs == 9) && (demanded_mcs < 9)) ||
2992 ((mcs == 7) && (demanded_mcs < 7))) {
2993 fn = fn_add_blocks(fn, 1);
2994 /* Send 2 RLC data block */
Max7d32f552017-12-15 11:25:14 +01002995 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
2996 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05302997
Max7d32f552017-12-15 11:25:14 +01002998 NACK(dl_tbf, 0);
2999 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303000
3001 /* Set the demanded MCS to demanded_mcs */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003002 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303003
3004 fn = fn_add_blocks(fn, 1);
3005 /* Retransmit the first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003006 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3007 CHECK_NACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303008
3009 fn = fn_add_blocks(fn, 1);
3010 /* Retransmit the second RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003011 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3012 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303013 } else if (((mcs == 5) && (demanded_mcs > 6)) ||
3014 ((mcs == 6) && (demanded_mcs > 8))) {
3015 fn = fn_add_blocks(fn, 1);
3016 /* Send first RLC data block BSN 0 */
Max7d32f552017-12-15 11:25:14 +01003017 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303018
3019 fn = fn_add_blocks(fn, 1);
3020 /* Send second RLC data block BSN 1 */
Max7d32f552017-12-15 11:25:14 +01003021 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3022 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303023
Max7d32f552017-12-15 11:25:14 +01003024 NACK(dl_tbf, 0);
3025 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303026
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003027 ms_set_current_cs_dl(dl_tbf->ms(), static_cast < enum CodingScheme > (CS4 + demanded_mcs));
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303028
3029 fn = fn_add_blocks(fn, 1);
3030 /* Send first, second RLC data blocks with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003031 MAKE_ACKED(msg, dl_tbf, fn, demanded_mcs, true);
3032 CHECK_UNACKED(dl_tbf, demanded_mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303033 } else if (mcs > 6) {
3034 /* No Mcs change cases are handled here for mcs > MCS6*/
3035 fn = fn_add_blocks(fn, 1);
3036 /* Send first,second RLC data blocks */
Max7d32f552017-12-15 11:25:14 +01003037 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3038 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303039
Max7d32f552017-12-15 11:25:14 +01003040 NACK(dl_tbf, 0);
3041 NACK(dl_tbf, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303042
3043 fn = fn_add_blocks(fn, 1);
3044 /* Send first,second RLC data blocks with demanded_mcs*/
Max7d32f552017-12-15 11:25:14 +01003045 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
3046 CHECK_UNACKED(dl_tbf, mcs, 1);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303047 } else {
3048
3049 /* No MCS change cases are handled here for mcs <= MCS6*/
3050 fn = fn_add_blocks(fn, 1);
3051 /* Send first RLC data block */
Max7d32f552017-12-15 11:25:14 +01003052 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303053
Max7d32f552017-12-15 11:25:14 +01003054 NACK(dl_tbf, 0);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303055
3056 fn = fn_add_blocks(fn, 1);
3057 /* Send first RLC data block with demanded_mcs */
Max7d32f552017-12-15 11:25:14 +01003058 MAKE_ACKED(msg, dl_tbf, fn, mcs, true);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303059 }
3060
3061 tbf_cleanup(dl_tbf);
3062}
3063
3064static void test_tbf_egprs_retx_dl(void)
3065{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003066 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003067 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003068 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303069 uint8_t ts_no = 4;
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303070
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003071 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303072
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003073 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003074 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003075 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303076 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003077 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303078
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303079
3080 /* First parameter is current MCS, second one is demanded_mcs */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003081 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 6);
3082 establish_and_use_egprs_dl_tbf_for_retx(bts, 1, 9);
3083 establish_and_use_egprs_dl_tbf_for_retx(bts, 2, 8);
3084 establish_and_use_egprs_dl_tbf_for_retx(bts, 5, 7);
3085 establish_and_use_egprs_dl_tbf_for_retx(bts, 6, 9);
3086 establish_and_use_egprs_dl_tbf_for_retx(bts, 7, 5);
3087 establish_and_use_egprs_dl_tbf_for_retx(bts, 9, 6);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303088
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003089 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003090 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303091}
3092
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303093static void test_tbf_egprs_spb_dl(void)
3094{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003095 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003096 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003097 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303098 uint8_t ts_no = 4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303099
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003100 fprintf(stderr, "=== start %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303101
Pau Espin Pedrolad79b852021-01-14 13:20:55 +01003102 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003103 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003104 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303105
3106 /* ARQ I resegmentation support */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003107 the_pcu->vty.dl_arq_type = EGPRS_ARQ1;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303108
3109 /*
3110 * First parameter is current MCS, second one is demanded_mcs
3111 * currently only MCS5->MCS2, MCS6->3, MCS4->MCS1 is tested in UT
3112 * rest scenarios has been integration tested
3113 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003114 establish_and_use_egprs_dl_tbf_for_spb(bts, 6, 3);
3115 establish_and_use_egprs_dl_tbf_for_spb(bts, 5, 2);
3116 establish_and_use_egprs_dl_tbf_for_spb(bts, 4, 1);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303117 /* check MCS6->(MCS3+MCS3)->MCS6 case */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003118 egprs_spb_to_normal_validation(bts, 6, 3);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303119
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003120 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003121 fprintf(stderr, "=== end %s ===\n", __func__);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303122}
3123
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003124static void test_tbf_egprs_dl()
3125{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003126 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003127 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003128 struct gprs_rlcmac_bts *bts = the_pcu->bts;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003129 uint8_t ts_no = 4;
3130 int i;
3131
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003132 fprintf(stderr, "=== start %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003133
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003134 setup_bts(bts, ts_no);
Pau Espin Pedrol924aaad2021-01-14 12:01:42 +01003135 OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303136 /* ARQ II */
Pau Espin Pedrol97296b22021-01-14 13:08:02 +01003137 the_pcu->vty.dl_arq_type = EGPRS_ARQ2;
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003138
3139 for (i = 1; i <= 9; i++)
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003140 establish_and_use_egprs_dl_tbf(bts, i);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003141
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003142 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003143 fprintf(stderr, "=== end %s ===\n", __func__);
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003144}
3145
3146
3147
aravind sirsikare9a138e2017-01-24 12:36:08 +05303148static void test_packet_access_rej_prr_no_other_tbfs()
3149{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003150 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003151 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003152 struct gprs_rlcmac_bts *bts = the_pcu->bts;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303153 uint32_t fn = 2654218;
3154 int ts_no = 7;
3155 uint8_t trx_no = 0;
3156 uint32_t tlli = 0xffeeddcc;
3157 struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
3158
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003159 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303160
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003161 setup_bts(bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303162
3163 int rc = 0;
3164
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003165 ul_tbf = handle_tbf_reject(bts, NULL, tlli,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303166 trx_no, ts_no);
3167
3168 OSMO_ASSERT(ul_tbf != 0);
3169
3170 /* trigger packet access reject */
3171 uint8_t bn = fn2bn(fn);
3172
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003173 rc = gprs_rlcmac_rcv_rts_block(bts,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303174 trx_no, ts_no, fn, bn);
3175
3176 OSMO_ASSERT(rc == 0);
3177
3178 ul_tbf->handle_timeout();
3179
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003180 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003181 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303182}
3183
3184static void test_packet_access_rej_prr()
3185{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003186 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003187 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003188 struct gprs_rlcmac_bts *bts = the_pcu->bts;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303189 uint32_t fn = 2654218;
3190 uint16_t qta = 31;
3191 int ts_no = 7;
3192 uint8_t trx_no = 0;
3193 RlcMacUplink_t ulreq = {0};
3194 Packet_Resource_Request_t *presreq = NULL;
3195 uint8_t ms_class = 11;
3196 uint8_t egprs_ms_class = 11;
3197 uint32_t rach_fn = fn - 51;
3198 uint32_t sba_fn = fn + 52;
3199 uint32_t tlli = 0xffeeddcc;
3200 MS_Radio_Access_capability_t *pmsradiocap = NULL;
3201 Multislot_capability_t *pmultislotcap = NULL;
3202
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003203 fprintf(stderr, "=== start %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303204
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003205 setup_bts(bts, ts_no, 4);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303206
3207 int rc = 0;
3208
3209 /*
3210 * Trigger rach till resources(USF) exhaust
3211 */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003212 rc = bts_handle_rach(bts, 0x78, rach_fn, qta);
3213 rc = bts_handle_rach(bts, 0x79, rach_fn, qta);
3214 rc = bts_handle_rach(bts, 0x7a, rach_fn, qta);
3215 rc = bts_handle_rach(bts, 0x7b, rach_fn, qta);
3216 rc = bts_handle_rach(bts, 0x7c, rach_fn, qta);
3217 rc = bts_handle_rach(bts, 0x7d, rach_fn, qta);
3218 rc = bts_handle_rach(bts, 0x7e, rach_fn, qta);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303219
3220 /* fake a resource request */
3221 ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST;
3222 presreq = &ulreq.u.Packet_Resource_Request;
3223 presreq->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
3224 presreq->ID.UnionType = 1; /* != 0 */
3225 presreq->ID.u.TLLI = tlli;
Pau Espin Pedrole50ce6e2020-03-23 18:49:16 +01003226 presreq->Exist_MS_Radio_Access_capability2 = 1;
3227 pmsradiocap = &presreq->MS_Radio_Access_capability2;
aravind sirsikare9a138e2017-01-24 12:36:08 +05303228 pmsradiocap->Count_MS_RA_capability_value = 1;
3229 pmsradiocap->MS_RA_capability_value[0].u.Content.
3230 Exist_Multislot_capability = 1;
3231 pmultislotcap = &pmsradiocap->MS_RA_capability_value[0].
3232 u.Content.Multislot_capability;
3233
3234 pmultislotcap->Exist_GPRS_multislot_class = 1;
3235 pmultislotcap->GPRS_multislot_class = ms_class;
3236 if (egprs_ms_class) {
3237 pmultislotcap->Exist_EGPRS_multislot_class = 1;
3238 pmultislotcap->EGPRS_multislot_class = egprs_ms_class;
3239 }
3240
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003241 send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303242
3243 /* trigger packet access reject */
3244 uint8_t bn = fn2bn(fn);
3245
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003246 rc = gprs_rlcmac_rcv_rts_block(bts,
aravind sirsikare9a138e2017-01-24 12:36:08 +05303247 trx_no, ts_no, fn, bn);
3248
3249 OSMO_ASSERT(rc == 0);
3250
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003251 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003252 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikare9a138e2017-01-24 12:36:08 +05303253}
3254
aravind sirsikared3413e2016-11-11 17:15:10 +05303255void test_packet_access_rej_epdan()
3256{
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003257 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01003258 the_pcu->bts = bts_alloc(the_pcu);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003259 struct gprs_rlcmac_bts *bts = the_pcu->bts;
aravind sirsikared3413e2016-11-11 17:15:10 +05303260 uint32_t tlli = 0xffeeddcc;
Maxd3a0d912019-03-05 16:15:01 +01003261 static uint8_t exp[] = { 0x40, 0x84, 0x7f, 0xf7, 0x6e, 0xe6, 0x41, 0x4b,
3262 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
3263 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
3264 };
aravind sirsikared3413e2016-11-11 17:15:10 +05303265
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003266 fprintf(stderr, "=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01003267 setup_bts(bts, 4);
3268 static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1);
aravind sirsikared3413e2016-11-11 17:15:10 +05303269
3270 dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
3271
3272 struct msgb *msg = dl_tbf->create_packet_access_reject();
3273
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003274 fprintf(stderr, "packet reject: %s\n",
aravind sirsikared3413e2016-11-11 17:15:10 +05303275 osmo_hexdump(msg->data, 23));
3276
Maxd3a0d912019-03-05 16:15:01 +01003277 if (!msgb_eq_data_print(msg, exp, GSM_MACBLOCK_LEN))
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003278 fprintf(stderr, "%s test failed!\n", __func__);
Maxd3a0d912019-03-05 16:15:01 +01003279
Pau Espin Pedrol47f15fb2021-01-14 14:28:26 +01003280 TALLOC_FREE(the_pcu);
Pau Espin Pedrol474dc772019-09-09 14:09:48 +02003281 fprintf(stderr, "=== end %s ===\n", __func__);
aravind sirsikared3413e2016-11-11 17:15:10 +05303282}
3283
3284
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003285int main(int argc, char **argv)
3286{
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003287 struct vty_app_info pcu_vty_info = {0};
3288
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003289 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context");
3290 if (!tall_pcu_ctx)
3291 abort();
3292
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01003293 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02003294 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003295 log_set_use_color(osmo_stderr_target, 0);
3296 log_set_print_filename(osmo_stderr_target, 0);
Maxfdd79e92018-01-24 11:04:59 +01003297 log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:"
Harald Welte398f60e2020-12-10 13:39:21 +01003298 "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:"
Max86e35e42019-03-07 12:20:42 +01003299 "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:");
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003300 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02003301 pcu_vty_init();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003302
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003303 /* Initialize shared UL measurements */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +01003304 pcu_l1_meas_set_link_qual(&meas, 12);
3305 pcu_l1_meas_set_rssi(&meas, 31);
Vadim Yanitskiy87b6e7d2019-11-08 04:44:04 +07003306
Jacob Erlbeckac89a552015-06-29 14:18:46 +02003307 test_tbf_base();
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003308 test_tbf_tlli_update();
Jacob Erlbeck5e9f40d2015-02-23 14:26:59 +01003309 test_tbf_final_ack(TEST_MODE_STANDARD);
3310 test_tbf_final_ack(TEST_MODE_REVERSE_FREE);
Jacob Erlbeck2cbe80b2015-03-25 10:48:52 +01003311 test_tbf_delayed_release();
Jacob Erlbeckb0e5eaf2015-05-21 11:07:16 +02003312 test_tbf_imsi();
Jacob Erlbeckd58b7112015-04-09 19:17:21 +02003313 test_tbf_exhaustion();
Jacob Erlbeck41168642015-06-12 13:41:00 +02003314 test_tbf_dl_llc_loss();
Jacob Erlbeckddfc0d52015-05-27 13:03:15 +02003315 test_tbf_single_phase();
3316 test_tbf_two_phase();
Jacob Erlbeckb1395982015-08-21 18:15:38 +02003317 test_tbf_ra_update_rach();
3318 test_tbf_dl_flow_and_rach_two_phase();
3319 test_tbf_dl_flow_and_rach_single_phase();
Jacob Erlbeck23c4b3f2015-08-21 15:04:39 +02003320 test_tbf_dl_reuse();
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +01003321 test_tbf_gprs_egprs();
Jacob Erlbeck36df7742016-01-19 15:53:30 +01003322 test_tbf_ws();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003323 test_tbf_egprs_two_phase();
Aravind Sirsikar505a86d2016-07-26 18:26:21 +05303324 test_tbf_egprs_two_phase_spb();
Jacob Erlbeck2d2efb12016-02-04 11:09:19 +01003325 test_tbf_egprs_dl();
Aravind Sirsikar1a679122016-07-12 15:50:29 +05303326 test_tbf_egprs_retx_dl();
Aravind Sirsikar50b09702016-08-22 17:21:10 +05303327 test_tbf_egprs_spb_dl();
Aravind Sirsikar02352b42016-08-25 16:37:30 +05303328 test_tbf_puan_urbb_len();
Aravind Sirsikar3c2eaeb2016-08-30 15:39:04 +05303329 test_tbf_update_ws();
Aravind Sirsikar3463bd42016-09-15 17:19:54 +05303330 test_tbf_li_decoding();
aravind sirsikarf2761382016-10-25 12:45:24 +05303331 test_tbf_epdan_out_of_rx_window();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +05303332 test_immediate_assign_rej();
sivasankari1d8744c2017-01-24 15:53:35 +05303333 test_tbf_egprs_two_phase_puan();
aravind sirsikared3413e2016-11-11 17:15:10 +05303334 test_packet_access_rej_epdan();
aravind sirsikare9a138e2017-01-24 12:36:08 +05303335 test_packet_access_rej_prr();
3336 test_packet_access_rej_prr_no_other_tbfs();
Jacob Erlbeck67c38502015-05-11 10:32:40 +02003337
3338 if (getenv("TALLOC_REPORT_FULL"))
3339 talloc_report_full(tall_pcu_ctx, stderr);
Holger Hans Peter Freytherb8098662013-10-30 14:50:17 +01003340 return EXIT_SUCCESS;
3341}
3342
3343/*
3344 * stubs that should not be reached
3345 */
3346extern "C" {
3347void l1if_pdch_req() { abort(); }
3348void l1if_connect_pdch() { abort(); }
3349void l1if_close_pdch() { abort(); }
3350void l1if_open_pdch() { abort(); }
3351}