blob: ac7ec9f73436390510185a7fed93d273146a9000 [file] [log] [blame]
Harald Welte505cf9b2018-09-15 17:47:23 +03001module BTS_Tests_SMSCB {
2
3/* Integration Tests for OsmoBTS
4 * (C) 2019 by Harald Welte <laforge@gnumonks.org>
5 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
10 * This test suite tests the SMSCB (Cell Broadcast) related functionality of
11 * OsmoBTS by attaching to the A-bis RSL and Um interface and emulating both
12 * BSC and MS.
13 */
14
15import from Misc_Helpers all;
16import from General_Types all;
17import from Osmocom_Types all;
18import from GSM_Types all;
19import from L1CTL_PortType all;
20import from L1CTL_Types all;
21import from LAPDm_Types all;
22
23import from RSL_Types all;
24
25import from Osmocom_VTY_Functions all;
26
27import from BTS_Tests all;
28
29/***********************************************************************
30 * Cell Broadcast related tests
31 ***********************************************************************/
32
Harald Weltea3ff6702019-05-20 20:03:50 +020033/* Test parameters for one channel (e.g. Basic, Extended) */
34type record CbchTestParsChan {
35 /* list of "normal" (sent-once) SMSCB messages */
36 CbchTestMsgs msgs,
37 /* default message, if any */
38 CbchTestMsg default_msg optional
39}
40
41private template (value) CbchTestParsChan
42t_CbchPC(template (value) CbchTestMsgs msgs, template (omit) CbchTestMsg def := omit) := {
43 msgs := msgs,
44 default_msg := def
45}
46
47/* CBCH test parameters for most of our tests */
Harald Welte505cf9b2018-09-15 17:47:23 +030048type record CbchTestPars {
Harald Weltea3ff6702019-05-20 20:03:50 +020049 /* should we execute on SDCCH4 (true) or SDCCH8 (false) ? */
Harald Welte505cf9b2018-09-15 17:47:23 +030050 boolean use_sdcch4,
Harald Weltea3ff6702019-05-20 20:03:50 +020051 /* Parameters for BASIC CBCH */
52 CbchTestParsChan basic,
53 /* Parameters for EXTENDED CBCH */
54 CbchTestParsChan extended optional
Harald Welte505cf9b2018-09-15 17:47:23 +030055};
56
57type record CbchTestMsg {
58 /* config / input data */
59 RSL_CbCommand rsl_cb_cmd,
60 uint2_t last_block, /* 0..3 */
61 octetstring payload,
62 /* computed / result data */
63 CbchBlocks blocks optional
64};
65type record of CbchTestMsg CbchTestMsgs;
66
67/* a single 22byte block within a CbchTestMsg */
68type record CbchBlock {
69 uint4_t seq_nr, /* as per TS 04.12 */
70 boolean is_last,
71 OCT22 payload,
72 boolean seen_once
73};
74type record of CbchBlock CbchBlocks;
75
76/* compute the expected blocks for given test parameters */
77private function f_cbch_compute_exp_blocks(inout CbchTestPars pars) {
Harald Weltea3ff6702019-05-20 20:03:50 +020078 f_cbch_compute_exp_blocks_chan(pars.basic);
79 if (ispresent(pars.extended)) {
80 f_cbch_compute_exp_blocks_chan(pars.extended);
81 }
82}
83private function f_cbch_compute_exp_blocks_chan(inout CbchTestParsChan pars_chan) {
Harald Welte505cf9b2018-09-15 17:47:23 +030084 var integer i;
Harald Weltea3ff6702019-05-20 20:03:50 +020085 for (i := 0; i < lengthof(pars_chan.msgs); i := i+1) {
86 pars_chan.msgs[i].blocks := f_comp_blocks(pars_chan.msgs[i]);
87 }
88 if (ispresent(pars_chan.default_msg)) {
89 pars_chan.default_msg.blocks := f_comp_blocks(pars_chan.default_msg);
Harald Welte505cf9b2018-09-15 17:47:23 +030090 }
91}
92private function f_comp_blocks(in CbchTestMsg msg) return CbchBlocks {
93 var CbchBlocks blocks := {};
94 var integer i;
95
96 for (i := 0; i <= msg.last_block; i := i+1) {
97 var CbchBlock block := {
98 seq_nr := i,
99 is_last := false,
100 payload := substr(msg.payload, 22*i, 22),
101 seen_once := false
102 };
103 if (msg.rsl_cb_cmd == RSL_CB_CMD_SCHEDULE and i == 0) {
104 block.seq_nr := 8;
105 }
106 if (i == msg.last_block) {
107 block.is_last := true;
108 }
109 blocks := blocks & {block};
110 }
111
112 return blocks;
113};
114
115/* TS 48.058 Section 9.3.41 */
116private function f_cbch_block_nr2rsl(uint2_t nr) return uint2_t {
117 select (nr) {
118 case (0) { return 1; }
119 case (1) { return 2; }
120 case (2) { return 3; }
121 case (3) { return 0; }
122 }
123 setverdict(fail, "Invalid block number");
124 mtc.stop;
125}
126
Harald Welte88e5dff2019-05-20 15:14:46 +0200127private function f_cbch_fn2tb(uint32_t fn) return integer
128{
129 return (fn/51) mod 8; /* TS 05.02 Section 6.5.4 */
130}
131
Harald Welte505cf9b2018-09-15 17:47:23 +0300132/* Verify the CBCH TB scheduling rules of TS 05.02 Section 6.5.4 */
133private function f_cbch_fn_verify(uint32_t fn, CBCH_Block cb)
134{
Harald Welte88e5dff2019-05-20 15:14:46 +0200135 var integer tb := f_cbch_fn2tb(fn);
Harald Welte505cf9b2018-09-15 17:47:23 +0300136 if (cb.block_type.seq_nr == 15 /* null */) {
137 /* always permitted */
138 return;
139 } else if (cb.block_type.seq_nr == 8 /* schedule */) {
140 if (tb != 0) {
141 setverdict(fail, "Schedule block at TB=", tb);
142 }
143 } else if (cb.block_type.seq_nr < 4) {
144 if (cb.block_type.seq_nr != tb and cb.block_type.seq_nr+4 != tb) {
145 setverdict(fail, "Normal block at wrong TB=", tb, ": ", cb);
146 }
147 }
148}
149
Harald Weltedf4d0f02019-05-20 16:04:11 +0200150private function f_rsl_smscb_default_null() runs on test_CT
151{
152 var RSL_IE_CbCommandType cmd_type :=
153 valueof(ts_RSL_IE_CbCmdType(RSL_CB_CMD_DEFAULT, 1, true));
154 RSL_CCHAN.send(ts_RSL_UD(ts_RSL_SMSCB_CMD(cmd_type, ''O)));
155}
156
Harald Weltea3ff6702019-05-20 20:03:50 +0200157template RSL_IE t_RSL_IE_SMSCB_EXT := t_RSL_IE(RSL_IE_SMSCB_CHAN_INDICATOR, {smscb_chan_ind := 1});
158
159private function f_smscb_setup_rsl_chan(inout CbchTestParsChan pars_chan, boolean extd := false)
160runs on test_CT {
Harald Welte88e5dff2019-05-20 15:14:46 +0200161 var integer i;
Harald Weltea3ff6702019-05-20 20:03:50 +0200162 var CbchTestMsg msg;
163 var uint2_t rsl_last_block;
164 var RSL_IE_CbCommandType cmd_type;
165 var RSL_Message rsl;
166
167 /* send SMSCB[s] via RSL */
168 for (i := 0; i < lengthof(pars_chan.msgs); i := i+1) {
169 msg := pars_chan.msgs[i];
170 rsl_last_block := f_cbch_block_nr2rsl(msg.last_block);
171 cmd_type := valueof(ts_RSL_IE_CbCmdType(msg.rsl_cb_cmd, rsl_last_block));
172 rsl := valueof(ts_RSL_SMSCB_CMD(cmd_type, msg.payload));
173 if (extd) {
174 rsl.ies := rsl.ies & { valueof(t_RSL_IE_SMSCB_EXT) };
175 }
176 RSL_CCHAN.send(ts_RSL_UD(rsl));
177 }
178 if (ispresent(pars_chan.default_msg)) {
179 msg := pars_chan.default_msg;
180 rsl_last_block := f_cbch_block_nr2rsl(msg.last_block);
181 cmd_type := valueof(ts_RSL_IE_CbCmdType(msg.rsl_cb_cmd, rsl_last_block, false));
182 rsl := valueof(ts_RSL_SMSCB_CMD(cmd_type, msg.payload));
183 if (extd) {
184 rsl.ies := rsl.ies & { valueof(t_RSL_IE_SMSCB_EXT) };
185 }
186 RSL_CCHAN.send(ts_RSL_UD(rsl));
187 }
188}
189private function f_smscb_setup(inout CbchTestPars pars) runs on test_CT {
Harald Welte505cf9b2018-09-15 17:47:23 +0300190
191 f_cbch_compute_exp_blocks(pars);
192
193 f_init_vty_bsc();
194 /* ensure that a CBCH is present in channel combination */
195 if (pars.use_sdcch4) {
196 f_vty_config2(BSCVTY, {"network", "bts 0", "trx 0", "timeslot 0"},
197 "phys_chan_config CCCH+SDCCH4+CBCH");
198 f_vty_config2(BSCVTY, {"network", "bts 0", "trx 0", "timeslot 6"},
199 "phys_chan_config SDCCH8");
200 } else {
201 f_vty_config2(BSCVTY, {"network", "bts 0", "trx 0", "timeslot 0"},
202 "phys_chan_config CCCH+SDCCH4");
203 f_vty_config2(BSCVTY, {"network", "bts 0", "trx 0", "timeslot 6"},
204 "phys_chan_config SDCCH8+CBCH");
205 }
206 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
207 f_sleep(2.0);
208 f_init(testcasename());
209
210 f_init_l1ctl();
211 f_l1_tune(L1CTL);
212 /* FIXME: switch to dedicated mode for SDCCH/8 */
213
214 /* send SMSCB[s] via RSL */
Harald Weltea3ff6702019-05-20 20:03:50 +0200215 f_smscb_setup_rsl_chan(pars.basic, false);
216 if (ispresent(pars.extended)) {
217 f_smscb_setup_rsl_chan(pars.extended, true);
Harald Welte505cf9b2018-09-15 17:47:23 +0300218 }
Harald Welte88e5dff2019-05-20 15:14:46 +0200219}
220
221private function f_smscb_cleanup() runs on test_CT {
222 /* reset timeslot 0 channel combination to default */
223 f_vty_config2(BSCVTY, {"network", "bts 0", "trx 0", "timeslot 0"},
224 "phys_chan_config CCCH+SDCCH4");
225 f_vty_config2(BSCVTY, {"network", "bts 0", "trx 0", "timeslot 6"},
226 "phys_chan_config SDCCH8");
227}
228
Harald Weltea3ff6702019-05-20 20:03:50 +0200229/* construct a receive/match template for given block_nr in given msg */
230private function f_get_block_template(CbchTestMsg msg, integer block_nr) return template CBCH_Block {
231 var template CBCH_Block tr;
232 if (block_nr < lengthof(msg.blocks)) {
233 var CbchBlock b := msg.blocks[block_nr];
234 tr := tr_CBCH_Block(b.seq_nr, b.is_last, b.payload);
235 } else {
236 tr := tr_CBCH_Block(15, ?, ?);
237 }
238 return tr;
239}
240
241/* the heart of the CBCH test case matching engine for one channel (basic, extended) */
242private function f_cbch_match(inout CbchTestParsChan pars_chan, CBCH_Block cb, integer tb)
243{
244 var integer block_nr := tb mod 4;
245 var integer i;
246
247 if (not match(cb, tr_CBCH_Block)) {
248 setverdict(fail, "Illegal CBCH Block received: ", cb);
249 } else {
250 var boolean matched := false;
251 /* check if it's any of our expected blocks */
252 for (i := 0; i < lengthof(pars_chan.msgs); i := i+1) {
253 if (block_nr < lengthof(pars_chan.msgs[i].blocks)) {
254 if (match(cb, f_get_block_template(pars_chan.msgs[i], block_nr))) {
255 log("Found block_nr ", block_nr, " of msg ", i);
256 if (not pars_chan.msgs[i].blocks[block_nr].seen_once) {
257 pars_chan.msgs[i].blocks[block_nr].seen_once := true;
258 setverdict(pass);
259 } else {
260 setverdict(fail, "Received SMSCB twice! ", cb);
261 }
262 matched := true;
263 break;
264 }
265 }
266 }
267 if (not matched) {
268 var template CBCH_Block tr;
269 if (ispresent(pars_chan.default_msg)) {
270 /* it must be a block of the default message */
271 tr := f_get_block_template(pars_chan.default_msg, block_nr);
272 } else {
273 /* it must be a NULL block */
274 tr := tr_CBCH_Block(15, ?, ?);
275 }
276 if (not match(cb, tr)) {
277 setverdict(fail, "Received unexpected CBCH block: ", cb);
278 } else {
279 log("Found block_nr ", block_nr, " of DEFAULT/NULL");
280 if (ispresent(pars_chan.default_msg) and
281 block_nr < lengthof(pars_chan.default_msg.blocks)) {
282 pars_chan.default_msg.blocks[block_nr].seen_once := true;
283 }
284 }
285 }
286 }
287}
288
289/* Report/Evaluate the per-channel CBCH test results */
290private function f_cbch_report(CbchTestParsChan pars_chan, charstring id)
291{
292 var integer i, j;
293
294 /* verify that each block of each message has been seen once */
295 for (i := 0; i < lengthof(pars_chan.msgs); i := i+1) {
296 for (j := 0; j < lengthof(pars_chan.msgs[i].blocks); j := j+1) {
297 var CbchBlock b := pars_chan.msgs[i].blocks[j];
298 if (not b.seen_once) {
299 setverdict(fail, "Timeout waiting for ", id, " CBCH block ",
300 j, " of msg ", i);
301 }
302 }
303 }
304 if (ispresent(pars_chan.default_msg)) {
305 /* verify that each block of default message has been seen at least once */
306 for (j := 0; j < lengthof(pars_chan.default_msg.blocks); j := j+1) {
307 var CbchBlock b := pars_chan.default_msg.blocks[j];
308 if (not b.seen_once) {
309 setverdict(fail, "Timeout waiting for at leaset one instance of ",
310 "CBCH block ", j, " of DEFAULT msg");
311 }
312 }
313 }
314}
315
Harald Welte88e5dff2019-05-20 15:14:46 +0200316/* shared function doing the heavy lifting for most CBCH tests */
317private function f_TC_smscb(CbchTestPars pars) runs on test_CT {
318 var L1ctlDlMessage dl;
Harald Weltea3ff6702019-05-20 20:03:50 +0200319 var integer msg_count;
320 timer T;
321
322 msg_count := lengthof(pars.basic.msgs);
323 if (ispresent(pars.basic.default_msg)) {
324 msg_count := msg_count + 1;
325 }
326 if (ispresent(pars.extended)) {
327 msg_count := msg_count + lengthof(pars.extended.msgs);
328 if (ispresent(pars.extended.default_msg)) {
329 msg_count := msg_count + 1;
330 }
331 }
Harald Welte88e5dff2019-05-20 15:14:46 +0200332
333 f_smscb_setup(pars);
334
Harald Weltea3ff6702019-05-20 20:03:50 +0200335 /* dynamically adjust timeout based on number of messages */
336 T.start(5.0 + 3.0 * int2float(msg_count));
Harald Welte505cf9b2018-09-15 17:47:23 +0300337 /* Expect this to show up exactly once on the basic CBCH (four blocks) */
338 alt {
339 /* FIXME: Channel Nr for SDCCH/8 */
340 [] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_CBCH(0))) -> value dl {
Harald Weltea3ff6702019-05-20 20:03:50 +0200341 var integer tb := f_cbch_fn2tb(dl.dl_info.frame_nr);
Harald Welte505cf9b2018-09-15 17:47:23 +0300342 var CBCH_Block cb := dec_CBCH_Block(dl.payload.data_ind.payload);
Harald Weltea3ff6702019-05-20 20:03:50 +0200343 log("Tb=", tb, ", CBCH: ", dl, ", block: ", cb);
344
Harald Welte505cf9b2018-09-15 17:47:23 +0300345 /* detect the proper CBCH messages; check frame number */
346 f_cbch_fn_verify(dl.dl_info.frame_nr, cb);
Harald Weltea3ff6702019-05-20 20:03:50 +0200347
348 if (tb < 4) {
349 f_cbch_match(pars.basic, cb, tb);
Harald Welte505cf9b2018-09-15 17:47:23 +0300350 } else {
Harald Weltea3ff6702019-05-20 20:03:50 +0200351 if (not ispresent(pars.extended)) {
352 /* no parameters for ext. BCCH given: ignore */
353 repeat;
Harald Welte505cf9b2018-09-15 17:47:23 +0300354 }
Harald Weltea3ff6702019-05-20 20:03:50 +0200355 f_cbch_match(pars.extended, cb, tb);
Harald Welte505cf9b2018-09-15 17:47:23 +0300356 }
Harald Weltea3ff6702019-05-20 20:03:50 +0200357 repeat;
Harald Welte505cf9b2018-09-15 17:47:23 +0300358 }
359 [] L1CTL.receive { repeat; }
360 [] T.timeout {
Harald Weltea3ff6702019-05-20 20:03:50 +0200361 f_cbch_report(pars.basic, "Basic");
362 if (ispresent(pars.extended)) {
363 f_cbch_report(pars.extended, "Extended");
Harald Welte505cf9b2018-09-15 17:47:23 +0300364 }
365 }
366 }
367
Harald Welte88e5dff2019-05-20 15:14:46 +0200368 f_smscb_cleanup();
369 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
370}
371
372private function f_TC_smscb_default_only(CbchTestPars pars) runs on test_CT {
373 var L1ctlDlMessage dl;
374 timer T := 5.0;
375
376 f_smscb_setup(pars);
377
378 /* ensure whatever initial NULL messages have all been drained */
379 f_sleep(5.0);
380 L1CTL.clear;
381
382 T.start;
383 alt {
384 [] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_CBCH(0))) -> value dl {
385 var integer tb := f_cbch_fn2tb(dl.dl_info.frame_nr);
386 log("CBCH: ", dl);
387 var CBCH_Block cb := dec_CBCH_Block(dl.payload.data_ind.payload);
388 /* detect the proper CBCH messages; check frame number */
389 f_cbch_fn_verify(dl.dl_info.frame_nr, cb);
390 if (tb >= 4) {
391 /* skip extended CBCH for now */
392 repeat;
393 }
394 if (not match(cb, tr_CBCH_Block)) {
395 setverdict(fail, "Illegal CBCH Block received: ", cb);
396 } else {
397 var uint4_t rx_seq_nr := cb.block_type.seq_nr;
398 var template CBCH_Block tr;
Harald Weltea3ff6702019-05-20 20:03:50 +0200399 if (rx_seq_nr < lengthof(pars.basic.msgs[0].blocks)) {
400 var CbchBlock b := pars.basic.msgs[0].blocks[rx_seq_nr];
Harald Welte88e5dff2019-05-20 15:14:46 +0200401 tr := tr_CBCH_Block(b.seq_nr, b.is_last, b.payload);
402 } else {
403 tr := tr_CBCH_Block(15, ?, ?);
404 }
405 if (match(cb, tr)) {
406 setverdict(pass); /* FIXME: check that all blocks are received? */
407 repeat;
408 } else {
409 setverdict(fail, "Unexpected CBCH block ", cb, ", expected ", tr);
410 }
411 }
412 }
413 [] L1CTL.receive { repeat; }
414 [] T.timeout {}
415 }
416
417 f_smscb_cleanup();
418 /* don't shut down; some tests still want to continue */
Harald Welte505cf9b2018-09-15 17:47:23 +0300419}
420
421private const CbchTestMsgs msgs_1m_1b_norm := {
422 { RSL_CB_CMD_NORMAL, 0, '001000320f1141660c344dd3cba09a0c000000000000'O, omit }
423}
424
425private const CbchTestMsgs msgs_1m_2b_norm := {
426 { RSL_CB_CMD_NORMAL, 1, '001000320f1141660c344dd3cba09a0c000000000000'O &
427 '000102030405060708090a0b0c0d0e0f101213141516'O,
428 omit }
429}
430
431private const CbchTestMsgs msgs_1m_3b_norm := {
432 { RSL_CB_CMD_NORMAL, 2, '001000320f1141660c344dd3cba09a0c000000000000'O &
433 '000102030405060708090a0b0c0d0e0f101213141516'O &
434 '101112131415161718191a1b1c1d1e1f202223242526'O,
435 omit }
436}
437
438private const CbchTestMsgs msgs_1m_4b_norm := {
439 { RSL_CB_CMD_NORMAL, 3, '001000320f1141660c344dd3cba09a0c000000000000'O &
440 '000102030405060708090a0b0c0d0e0f101213141516'O &
441 '101112131415161718191a1b1c1d1e1f202223242526'O &
442 '202122232425262728292a2b2c2d2e2f303233343536'O,
443 omit }
444}
445
446private const CbchTestMsgs msgs_1m_4b_sched := {
447 { RSL_CB_CMD_SCHEDULE, 3, '001000320f1141660c344dd3cba09a0c000000000000'O &
448 '000102030405060708090a0b0c0d0e0f101213141516'O &
449 '101112131415161718191a1b1c1d1e1f202223242526'O &
450 '202122232425262728292a2b2c2d2e2f303233343536'O,
451 omit }
452}
453
Harald Weltee0026c32019-05-20 00:27:30 +0200454private const CbchTestMsgs msgs_3m_4b_norm := {
455 { RSL_CB_CMD_NORMAL, 3, '001000320f1141660c344dd3cba09a0c000000000000'O &
456 '000102030405060708090a0b0c0d0e0f101213141516'O &
457 '101112131415161718191a1b1c1d1e1f202223242526'O &
458 '201122232425262728292a2b2c2d2e2f303233343536'O,
459 omit },
460 { RSL_CB_CMD_NORMAL, 3, '002000320f1141660c344dd3cba09a0c000000000000'O &
461 '002102030405060708090a0b0c0d0e0f101213141516'O &
462 '102112131415161718191a1b1c1d1e1f202223242526'O &
463 '202122232425262728292a2b2c2d2e2f303233343536'O,
464 omit },
465 { RSL_CB_CMD_NORMAL, 3, '003000320f1141660c344dd3cba09a0c000000000000'O &
466 '003102030405060708090a0b0c0d0e0f101213141516'O &
467 '103112131415161718191a1b1c1d1e1f202223242526'O &
468 '203122232425262728292a2b2c2d2e2f303233343536'O,
469 omit }
470}
471
Harald Welte88e5dff2019-05-20 15:14:46 +0200472private const CbchTestMsgs msgs_1m_3b_default := {
473 { RSL_CB_CMD_DEFAULT, 2, '001000320f1141660c344dd3cba09a0c000000000000'O &
474 '000102030405060708090a0b0c0d0e0f101213141516'O &
475 '101112131415161718191a1b1c1d1e1f202223242526'O,
476 omit }
477}
Harald Weltea3ff6702019-05-20 20:03:50 +0200478private const CbchTestMsg msg_default := {
479 RSL_CB_CMD_DEFAULT, 0, '010203040506070708090a0b0c0d0e0f101112131415'O,
480 omit
481}
Harald Welte88e5dff2019-05-20 15:14:46 +0200482
Harald Welte505cf9b2018-09-15 17:47:23 +0300483/* transmit single-block SMSCB COMMAND */
484testcase TC_sms_cb_cmd_sdcch4_1block() runs on test_CT {
485 var CbchTestPars pars := {
486 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200487 basic := valueof(t_CbchPC(msgs_1m_1b_norm)),
488 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300489 };
490 f_TC_smscb(pars);
491}
492testcase TC_sms_cb_cmd_sdcch8_1block() runs on test_CT {
493 var CbchTestPars pars := {
494 use_sdcch4 := false,
Harald Weltea3ff6702019-05-20 20:03:50 +0200495 basic := valueof(t_CbchPC(msgs_1m_1b_norm)),
496 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300497 };
498 f_TC_smscb(pars);
499}
500
501/* transmit dual-block SMSCB COMMAND */
502testcase TC_sms_cb_cmd_sdcch4_2block() runs on test_CT {
503 var CbchTestPars pars := {
504 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200505 basic := valueof(t_CbchPC(msgs_1m_2b_norm)),
506 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300507 };
508 f_TC_smscb(pars);
509}
510testcase TC_sms_cb_cmd_sdcch8_2block() runs on test_CT {
511 var CbchTestPars pars := {
512 use_sdcch4 := false,
Harald Weltea3ff6702019-05-20 20:03:50 +0200513 basic := valueof(t_CbchPC(msgs_1m_2b_norm)),
514 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300515 };
516 f_TC_smscb(pars);
517}
518
519/* transmit triple-block SMSCB COMMAND */
520testcase TC_sms_cb_cmd_sdcch4_3block() runs on test_CT {
521 var CbchTestPars pars := {
522 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200523 basic := valueof(t_CbchPC(msgs_1m_3b_norm)),
524 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300525 };
526 f_TC_smscb(pars);
527}
528testcase TC_sms_cb_cmd_sdcch8_3block() runs on test_CT {
529 var CbchTestPars pars := {
530 use_sdcch4 := false,
Harald Weltea3ff6702019-05-20 20:03:50 +0200531 basic := valueof(t_CbchPC(msgs_1m_3b_norm)),
532 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300533 };
534 f_TC_smscb(pars);
535}
536
537/* transmit quad-block SMSCB COMMAND */
538testcase TC_sms_cb_cmd_sdcch4_4block() runs on test_CT {
539 var CbchTestPars pars := {
540 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200541 basic := valueof(t_CbchPC(msgs_1m_4b_norm)),
542 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300543 };
544 f_TC_smscb(pars);
545}
546testcase TC_sms_cb_cmd_sdcch8_4block() runs on test_CT {
547 var CbchTestPars pars := {
548 use_sdcch4 := false,
Harald Weltea3ff6702019-05-20 20:03:50 +0200549 basic := valueof(t_CbchPC(msgs_1m_4b_norm)),
550 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300551 };
552 f_TC_smscb(pars);
553}
554
Harald Weltee0026c32019-05-20 00:27:30 +0200555/* transmit multiple commands of each 4 blocks */
556testcase TC_sms_cb_cmd_sdcch4_multi() runs on test_CT {
557 var CbchTestPars pars := {
558 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200559 basic := valueof(t_CbchPC(msgs_3m_4b_norm)),
560 extended := omit
Harald Weltee0026c32019-05-20 00:27:30 +0200561 };
562 f_TC_smscb(pars);
563}
564testcase TC_sms_cb_cmd_sdcch8_multi() runs on test_CT {
565 var CbchTestPars pars := {
566 use_sdcch4 := false,
Harald Weltea3ff6702019-05-20 20:03:50 +0200567 basic := valueof(t_CbchPC(msgs_3m_4b_norm)),
568 extended := omit
Harald Weltee0026c32019-05-20 00:27:30 +0200569 };
570 f_TC_smscb(pars);
571}
572
Harald Welte60bd92b2019-05-20 21:42:21 +0200573/* transmit multiple commands of each 4 blocks on CBCH EXTD */
574testcase TC_sms_cb_cmd_sdcch4_extd_multi() runs on test_CT {
575 var CbchTestPars pars := {
576 use_sdcch4 := true,
577 basic := valueof(t_CbchPC({})),
578 extended := valueof(t_CbchPC(msgs_3m_4b_norm))
579 };
580 f_TC_smscb(pars);
581}
582testcase TC_sms_cb_cmd_sdcch8_extd_multi() runs on test_CT {
583 var CbchTestPars pars := {
584 use_sdcch4 := false,
585 basic := valueof(t_CbchPC({})),
586 extended := valueof(t_CbchPC(msgs_3m_4b_norm))
587 };
588 f_TC_smscb(pars);
589}
590
Harald Welte505cf9b2018-09-15 17:47:23 +0300591/* transmit SMSCB COMMAND with SCHEDULE payload */
592testcase TC_sms_cb_cmd_sdcch4_schedule() runs on test_CT {
593 var CbchTestPars pars := {
594 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200595 basic := valueof(t_CbchPC(msgs_1m_4b_sched)),
596 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300597 };
598 f_TC_smscb(pars);
599}
600testcase TC_sms_cb_cmd_sdcch8_schedule() runs on test_CT {
601 var CbchTestPars pars := {
602 use_sdcch4 := false,
Harald Weltea3ff6702019-05-20 20:03:50 +0200603 basic := valueof(t_CbchPC(msgs_1m_4b_sched)),
604 extended := omit
Harald Welte505cf9b2018-09-15 17:47:23 +0300605 };
606 f_TC_smscb(pars);
607}
608
Harald Welte88e5dff2019-05-20 15:14:46 +0200609/* set a DEFAULT message; verify it gets transmitted all the time */
610testcase TC_sms_cb_cmd_sdcch4_default_only() runs on test_CT {
611 var CbchTestPars pars := {
612 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200613 basic := valueof(t_CbchPC(msgs_1m_3b_default)),
614 extended := omit
Harald Welte88e5dff2019-05-20 15:14:46 +0200615 };
616 f_TC_smscb_default_only(pars);
617 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
618}
619testcase TC_sms_cb_cmd_sdcch8_default_only() runs on test_CT {
620 var CbchTestPars pars := {
621 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200622 basic := valueof(t_CbchPC(msgs_1m_3b_default)),
623 extended := omit
Harald Welte88e5dff2019-05-20 15:14:46 +0200624 };
625 f_TC_smscb_default_only(pars);
626 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
627}
628
Harald Welted522ca02019-05-20 20:06:12 +0200629testcase TC_sms_cb_cmd_sdcch4_default_and_normal() runs on test_CT {
630 var CbchTestPars pars := {
631 use_sdcch4 := true,
632 basic := valueof(t_CbchPC(msgs_1m_3b_norm, msg_default)),
633 extended := omit
634 };
635 f_TC_smscb(pars);
636}
637testcase TC_sms_cb_cmd_sdcch8_default_and_normal() runs on test_CT {
638 var CbchTestPars pars := {
639 use_sdcch4 := true,
640 basic := valueof(t_CbchPC(msgs_1m_3b_norm, msg_default)),
641 extended := omit
642 };
643 f_TC_smscb(pars);
644}
645
Harald Weltedf4d0f02019-05-20 16:04:11 +0200646/* first set a DEFAULT message, then disable it again */
647testcase TC_sms_cb_cmd_sdcch4_default_then_null() runs on test_CT {
648 var CbchTestPars pars := {
649 use_sdcch4 := true,
Harald Weltea3ff6702019-05-20 20:03:50 +0200650 basic := valueof(t_CbchPC(msgs_1m_3b_default)),
651 extended := omit
Harald Weltedf4d0f02019-05-20 16:04:11 +0200652 };
653 var L1ctlDlMessage dl;
654 timer T := 5.0;
655
656 f_TC_smscb_default_only(pars);
657
658 /* disable DEFAULT message; switch back to NULL */
659 f_rsl_smscb_default_null();
660
661 /* ensure whatever initial non-NULL messages have all been drained */
662 f_sleep(5.0);
663 L1CTL.clear;
664
665 T.start;
666 alt {
667 [] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_CBCH(0))) -> value dl {
668 log("CBCH: ", dl);
669 var CBCH_Block cb := dec_CBCH_Block(dl.payload.data_ind.payload);
670 /* detect the proper CBCH messages; check frame number */
671 f_cbch_fn_verify(dl.dl_info.frame_nr, cb);
672 if (not match(cb, tr_CBCH_Block)) {
673 setverdict(fail, "Illegal CBCH Block received: ", cb);
674 } else {
675 if (not match(cb, tr_CBCH_Block(15, ?, ?))) {
676 setverdict(fail, "Unexpected non-NULL CBCH block received");
677 }
678 repeat;
679 }
680 }
681 [] L1CTL.receive { repeat; }
682 [] T.timeout {
683 setverdict(pass);
684 }
685 }
686
687 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
688}
689
690
Harald Welte88e5dff2019-05-20 15:14:46 +0200691
Harald Welte505cf9b2018-09-15 17:47:23 +0300692/* SMSCB TODO:
693 * multiple SMS BC CMD at the same time: Ensure all of them are sent exactly once
694 * extended CBCH vs. normal CBCH
695 *
696 */
697
698control {
699 execute( TC_sms_cb_cmd_sdcch4_1block() );
700 execute( TC_sms_cb_cmd_sdcch4_2block() );
701 execute( TC_sms_cb_cmd_sdcch4_3block() );
702 execute( TC_sms_cb_cmd_sdcch4_4block() );
Harald Weltee0026c32019-05-20 00:27:30 +0200703 execute( TC_sms_cb_cmd_sdcch4_multi() );
Harald Welte505cf9b2018-09-15 17:47:23 +0300704 execute( TC_sms_cb_cmd_sdcch4_schedule() );
Harald Welte88e5dff2019-05-20 15:14:46 +0200705 execute( TC_sms_cb_cmd_sdcch4_default_only() );
Harald Welted522ca02019-05-20 20:06:12 +0200706 execute( TC_sms_cb_cmd_sdcch4_default_and_normal() );
Harald Weltedf4d0f02019-05-20 16:04:11 +0200707 execute( TC_sms_cb_cmd_sdcch4_default_then_null() );
Harald Welte505cf9b2018-09-15 17:47:23 +0300708 if (false) { /* FIXME: SDCCH/8 support broken, needs trxcon + L1CTL work */
709 execute( TC_sms_cb_cmd_sdcch8_1block() );
710 execute( TC_sms_cb_cmd_sdcch8_2block() );
711 execute( TC_sms_cb_cmd_sdcch8_3block() );
712 execute( TC_sms_cb_cmd_sdcch8_4block() );
Harald Weltee0026c32019-05-20 00:27:30 +0200713 execute( TC_sms_cb_cmd_sdcch8_multi() );
Harald Welte505cf9b2018-09-15 17:47:23 +0300714 execute( TC_sms_cb_cmd_sdcch8_schedule() );
Harald Welte88e5dff2019-05-20 15:14:46 +0200715 execute( TC_sms_cb_cmd_sdcch8_default_only() );
Harald Welted522ca02019-05-20 20:06:12 +0200716 execute( TC_sms_cb_cmd_sdcch8_default_and_normal() );
Harald Welte505cf9b2018-09-15 17:47:23 +0300717 }
718}
719
720
721}