blob: 287d8694e8bf7f61af950c002f20da5bb30557de [file] [log] [blame]
Harald Welte70767382018-02-21 12:16:40 +01001module BTS_Tests {
2
3import from General_Types all;
4import from GSM_Types all;
5import from GSM_RR_Types all;
6import from Osmocom_Types all;
7import from GSM_Types all;
8import from GSM_RR_Types all;
9import from L1CTL_PortType all;
10import from L1CTL_Types all;
11import from LAPDm_Types all;
12import from Osmocom_CTRL_Adapter all;
13
14import from RSL_Types all;
Harald Welte7484fc42018-02-24 14:09:45 +010015import from IPA_Types all;
Harald Welte70767382018-02-21 12:16:40 +010016import from IPA_Emulation all;
17import from RSL_Emulation all;
18
19import from IPL4asp_Types all;
20import from TRXC_Types all;
21import from TRXC_CodecPort all;
22import from TRXC_CodecPort_CtrlFunct all;
23
Harald Welte7484fc42018-02-24 14:09:45 +010024import from L3_Templates all;
25import from MobileL3_CommonIE_Types all;
26
Harald Welte70767382018-02-21 12:16:40 +010027/* The tests assume a BTS with the following timeslot configuration:
28 * TS0 : Combined CCCH + SDCCH/4
29 * TS1 .. TS 4: TCH/F
30 * TS5 : TCH/H
31 * TS6 : SDCCH/8
32 * TS7 : PDCH
33 */
34
35modulepar {
36 charstring mp_rsl_ip := "127.0.0.2";
37 integer mp_rsl_port := 3003;
38 integer mp_trx0_arfcn := 871;
39 integer mp_bb_trxc_port := 5704;
40}
41
42type component test_CT extends CTRL_Adapter_CT {
43 var IPA_Emulation_CT vc_IPA;
44
45 var RSL_Emulation_CT vc_RSL;
46 port RSL_CCHAN_PT RSL_CCHAN;
47}
48
49/* an individual call / channel */
50type component ConnHdlr extends RSL_DchanHdlr {
51 port L1CTL_PT L1CTL;
52
53 port TRXC_CODEC_PT BB_TRXC;
54 var integer g_bb_trxc_conn_id;
55
56 timer g_Tguard;
57 timer g_Tmeas_exp := 2.0; /* >= 103 SACCH multiframe ~ 500ms */
58
59 var ConnHdlrPars g_pars;
60 var uint8_t g_next_meas_res_nr := 0;
61}
62
63function f_init_rsl(charstring id) runs on test_CT {
64 vc_IPA := IPA_Emulation_CT.create(id & "-RSL-IPA");
65 vc_RSL := RSL_Emulation_CT.create(id & "-RSL");
66
67 map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
68 connect(vc_IPA:IPA_RSL_PORT, vc_RSL:IPA_PT);
69 connect(self:RSL_CCHAN, vc_RSL:CCHAN_PT);
70
71 vc_IPA.start(IPA_Emulation.main_server(mp_rsl_ip, mp_rsl_port));
72 vc_RSL.start(RSL_Emulation.main(false));
73}
74
75type record ConnHdlrPars {
76 RslChannelNr chan_nr,
77 RSL_IE_ChannelMode chan_mode,
78 float t_guard,
79 ConnL1Pars l1_pars
80}
81
Harald Welte7484fc42018-02-24 14:09:45 +010082/* Default SYSTEM INFORMATION 3 */
83template (value) GsmRrMessage ts_SI3_default := {
84 header := t_RrHeader(SYSTEM_INFORMATION_TYPE_3, 0),
85 payload := {
86 si3 := {
87 cell_id := 23,
88 lai := {
89 mcc_mnc := '262F42'H,
90 lac := 42
91 },
92 ctrl_chan_desc := {
93 msc_r99 := true,
94 att := true,
95 bs_ag_blks_res := 1,
96 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
97 si22_ind := false,
98 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
99 spare := '00'B,
100 bs_pa_mfrms := 0, /* 2 multiframes */
101 t3212 := 1 /* 6 minutes */
102 },
103 cell_opts := {
104 dn_ind := false,
105 pwrc := false,
106 dtx := MS_MAY_USE_UL_DTX,
107 radio_link_tout_div4 := 4/4
108 },
109 cell_sel_pars := {
110 cell_resel_hyst_2dB := 0,
111 ms_txpwr_max_cch := 0,
112 acs := '0'B,
113 neci := true,
114 rxlev_access_min := 0
115 },
116 rach_ctrl_pars := {
117 max_retrans := RACH_MAX_RETRANS_1,
118 tx_integer := '0000'B, /* 3 slots */
119 cell_bar_access := false,
120 re_not_allowed := true,
121 acc := '1111111111111111'B
122 },
123 rest_octets := ''O
124 }
125 }
126}
Harald Welte70767382018-02-21 12:16:40 +0100127
128/* global init function */
129function f_init(charstring id) runs on test_CT {
130 f_init_rsl(id);
131 RSL_CCHAN.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP});
Harald Welte7484fc42018-02-24 14:09:45 +0100132
133 /* Send SI3 to the BTS, it is needed for various computations */
134 var GsmRrMessage si3 := valueof(ts_SI3_default);
135 log("Sending SI3 ", si3);
136 var octetstring si3_enc := enc_GsmRrMessage(si3);
137 RSL_CCHAN.send(ts_RSL_UD(ts_RSL_BCCH_INFO(RSL_SYSTEM_INFO_3, si3_enc)));
Harald Welte70767382018-02-21 12:16:40 +0100138}
139
140type function void_fn(charstring id) runs on ConnHdlr;
141
142/* create a new test component */
143function f_start_handler(void_fn fn, ConnHdlrPars pars)
144runs on test_CT return ConnHdlr {
145 var charstring id := testcasename();
146 var ConnHdlr vc_conn;
147
148 vc_conn := ConnHdlr.create(id);
149 /* connect to RSL Emulation main component */
150 connect(vc_conn:RSL, vc_RSL:CLIENT_PT);
151 connect(vc_conn:RSL_PROC, vc_RSL:RSL_PROC);
152
153 vc_conn.start(f_handler_init(fn, id, pars));
154 return vc_conn;
155}
156
Harald Welte7484fc42018-02-24 14:09:45 +0100157template ASP_RSL_Unitdata ts_RSL_UD(template RSL_Message rsl, IpaStreamId sid := IPAC_PROTO_RSL_TRX0) := {
158 streamId := sid,
159 rsl := rsl
160}
161
162template ASP_RSL_Unitdata tr_RSL_UD(template RSL_Message rsl,
163 template IpaStreamId sid := IPAC_PROTO_RSL_TRX0) := {
164 streamId := sid,
165 rsl := rsl
166}
167
Harald Welte70767382018-02-21 12:16:40 +0100168private altstep as_Tguard() runs on ConnHdlr {
169 [] g_Tguard.timeout {
170 setverdict(fail, "Tguard timeout");
171 self.stop;
172 }
173}
174
175private function f_l1_tune() runs on ConnHdlr {
176 /* tune our virtual L1 to the right ARFCN */
177 //var BCCH_tune_req tune_req := { arfcn := { false, mp_trx0_arfcn }, combined_ccch := true };
178 //L1.send(tune_req);
179 f_L1CTL_FBSB(L1CTL, { false, mp_trx0_arfcn }, CCCH_MODE_COMBINED);
180}
181
182private function f_trxc_connect() runs on ConnHdlr {
183 map(self:BB_TRXC, system:BB_TRXC);
184 var Result res;
185 res := TRXC_CodecPort_CtrlFunct.f_IPL4_connect(BB_TRXC, "127.0.0.1", mp_bb_trxc_port,
186 "127.0.0.1", 0, -1, {udp:={}}, {});
187 g_bb_trxc_conn_id := res.connId;
188}
189
190private function f_trxc_fake_rssi(uint8_t rssi) runs on ConnHdlr {
191 BB_TRXC.send(ts_TRXC_Send(g_bb_trxc_conn_id, ts_TRXC_FAKE_RSSI(rssi)));
192}
193
194private function f_trx_fake_toffs256(int16_t toffs256) runs on ConnHdlr {
195 BB_TRXC.send(ts_TRXC_Send(g_bb_trxc_conn_id, ts_TRXC_FAKE_TIMING(toffs256)));
196}
197
198/* first function started in ConnHdlr component */
199private function f_handler_init(void_fn fn, charstring id, ConnHdlrPars pars)
200runs on ConnHdlr {
201 g_pars := pars;
202 g_chan_nr := pars.chan_nr;
203
204 map(self:L1CTL, system:L1CTL);
205 f_connect_reset(L1CTL);
206
207 f_trxc_connect();
208
209 g_Tguard.start(pars.t_guard);
210 activate(as_Tguard());
211
212 f_rslem_register(0, pars.chan_nr);
213
214 /* call the user-supplied test case function */
215 fn.apply(id);
216}
217
218
219function f_rsl_chan_act(RSL_IE_ChannelMode mode) runs on ConnHdlr {
220 RSL.send(ts_RSL_CHAN_ACT(g_chan_nr, mode));
221 alt {
222 [] RSL.receive(tr_RSL_CHAN_ACT_ACK(g_chan_nr)) {
223 g_Tmeas_exp.start;
224 }
225 [] RSL.receive(tr_RSL_CHAN_ACT_NACK(g_chan_nr)) {
226 setverdict(fail, "Unexpected RF CHAN ACT NACK");
227 }
228 }
229}
230
231function f_rsl_chan_deact() runs on ConnHdlr {
232 timer T := 3.0;
233 RSL.send(ts_RSL_RF_CHAN_REL(g_chan_nr));
234 T.start;
235 alt {
236 [] RSL.receive(tr_RSL_RF_CHAN_REL_ACK(g_chan_nr)) {
237 g_Tmeas_exp.stop;
238 }
239 [] T.timeout {
240 setverdict(fail, "Timeout waiting for RF CHAN REL ACK");
241 }
242 }
243}
244
245
246private template ConnHdlrPars t_Pars(template RslChannelNr chan_nr,
247 template RSL_IE_ChannelMode chan_mode,
248 float t_guard := 20.0) := {
249 chan_nr := valueof(chan_nr),
250 chan_mode := valueof(chan_mode),
251 t_guard := t_guard,
252 l1_pars := {
253 dtx_enabled := false,
254 meas_ul := {
255 full := {
256 rxlev := dbm2rxlev(-53),
257 rxqual := 0
258 },
259 sub := {
260 rxlev := dbm2rxlev(-53),
261 rxqual := 0
262 }
263 },
264 timing_offset_256syms := 0,
265 bs_power_level := 0,
266 ms_power_level := 0,
267 ms_actual_ta := 0
268 }
269}
270
271/* Stress test: Do 500 channel activations/deactivations in rapid succession */
272function f_TC_chan_act_stress(charstring id) runs on ConnHdlr {
273 for (var integer i := 0; i < 500; i := i+1) {
274 f_rsl_chan_act(g_pars.chan_mode);
275 f_rsl_chan_deact();
276 }
277 setverdict(pass);
278}
279testcase TC_chan_act_stress() runs on test_CT {
280 var ConnHdlr vc_conn;
281 var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
282 f_init(testcasename());
283 vc_conn := f_start_handler(refers(f_TC_chan_act_stress), pars);
284 vc_conn.done;
285}
286
287/* Test if re-activation of an already active channel fails as expected */
288function f_TC_chan_act_react(charstring id) runs on ConnHdlr {
289 f_rsl_chan_act(g_pars.chan_mode);
290 /* attempt to activate the same lchan again -> expect reject */
291 RSL.send(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode));
292 alt {
293 [] RSL.receive(tr_RSL_CHAN_ACT_ACK(g_chan_nr)) {
294 setverdict(fail, "Unexpected CHAN ACT ACK on double activation");
295 }
296 [] RSL.receive(tr_RSL_CHAN_ACT_NACK(g_chan_nr)) {
297 setverdict(pass);
298 }
299 }
300 f_rsl_chan_deact();
301}
302testcase TC_chan_act_react() runs on test_CT {
303 var ConnHdlr vc_conn;
304 var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
305 f_init(testcasename());
306 vc_conn := f_start_handler(refers(f_TC_chan_act_react), pars);
307 vc_conn.done;
308}
309
310/* Attempt to de-activate a channel that's not active */
311function f_TC_chan_deact_not_active(charstring id) runs on ConnHdlr {
312 timer T := 3.0;
313 RSL.send(ts_RSL_RF_CHAN_REL(g_chan_nr));
314 T.start;
315 alt {
316 [] RSL.receive(tr_RSL_RF_CHAN_REL_ACK(g_chan_nr)) {
317 setverdict(pass);
318 }
319 [] T.timeout {
320 setverdict(fail, "Timeout expecting RF_CHAN_REL_ACK");
321 }
322 }
323}
324testcase TC_chan_deact_not_active() runs on test_CT {
325 var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
326 f_init(testcasename());
327 var ConnHdlr vc_conn := f_start_handler(refers(f_TC_chan_deact_not_active), pars);
328 vc_conn.done;
329}
330
331/* attempt to activate channel with wrong RSL Channel Nr IE; expect NACK */
332function f_TC_chan_act_wrong_nr(charstring id) runs on ConnHdlr {
333 RSL.send(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode));
334 alt {
335 [] RSL.receive(tr_RSL_CHAN_ACT_ACK(g_chan_nr)) {
336 setverdict(fail, "Unexpected CHAN ACT ACK");
337 }
338 [] RSL.receive(tr_RSL_CHAN_ACT_NACK(g_chan_nr)) {
339 setverdict(pass);
340 }
341 }
342}
343private type record WrongChanNrCase {
344 RslChannelNr chan_nr,
345 charstring description
346}
347private type record of WrongChanNrCase WrongChanNrCases;
348private template WrongChanNrCase t_WCN(template RslChannelNr chan_nr, charstring desc) := {
349 chan_nr := chan_nr,
350 description := desc
351}
352
353testcase TC_chan_act_wrong_nr() runs on test_CT {
354 var ConnHdlr vc_conn;
355 var ConnHdlrPars pars;
356
357 f_init(testcasename());
358
359 var WrongChanNrCases wrong := {
360 valueof(t_WCN(t_RslChanNr_RACH(0), "RACH is not a dedicated channel")),
361 valueof(t_WCN(t_RslChanNr_RACH(1), "RACH doesn't exist on timeslot")),
362 valueof(t_WCN(t_RslChanNr_BCCH(0), "BCCH is not a dedicated channel")),
363 valueof(t_WCN(t_RslChanNr_PCH_AGCH(0), "PCH/AGCH is not a dedicated channel")),
364 valueof(t_WCN(t_RslChanNr_Bm(0), "TS0 cannot be TCH/F")),
365 valueof(t_WCN(t_RslChanNr_Lm(0, 0), "TS0 cannot be TCH/H")),
366 valueof(t_WCN(t_RslChanNr_Lm(0, 1), "TS0 cannot be TCH/H")),
367 valueof(t_WCN(t_RslChanNr_PDCH(0), "TS0 cannot be PDCH")),
368 valueof(t_WCN(t_RslChanNr_SDCCH8(0, 0), "TS0 cannot be SDCCH/8")),
369 valueof(t_WCN(t_RslChanNr_SDCCH8(0, 7), "TS0 cannot be SDCCH/8")),
370 valueof(t_WCN(t_RslChanNr_SDCCH4(7, 0), "TS7 cannot be SDCCH/4")),
371 valueof(t_WCN(t_RslChanNr_SDCCH4(7, 3), "TS7 cannot be SDCCH/4")),
372 valueof(t_WCN(t_RslChanNr_Lm(1, 0), "TS1 cannot be TCH/H"))
373 };
374
375 for (var integer i := 0; i < sizeof(wrong); i := i+1) {
376 pars := valueof(t_Pars(wrong[i].chan_nr, ts_RSL_ChanMode_SIGN));
377 vc_conn := f_start_handler(refers(f_TC_chan_act_wrong_nr), pars);
378 vc_conn.done;
379 }
380}
381
382function f_TC_chan_req(charstring id) runs on ConnHdlr {
383 f_l1_tune();
384
385 RSL.clear;
386 //L1.send(DCCH_establish_req:{ra := 23});
387 /* This arrives on CCHAN, so we cannot test here */
388 //RSL.receive(tr_RSL_CHAN_RQD(int2oct(23,1)));
389}
390testcase TC_chan_req() runs on test_CT {
391 var ConnHdlr vc_conn;
392 var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
393 f_init(testcasename());
394 vc_conn := f_start_handler(refers(f_TC_chan_req), pars);
395 vc_conn.done;
396}
397
398template LapdmAddressField ts_LapdmAddr(LapdmSapi sapi, boolean c_r) := {
399 spare := '0'B,
400 lpd := 0,
401 sapi := sapi,
402 c_r := c_r,
403 ea := true
404}
405
406template LapdmFrameB ts_LAPDm_B(LapdmSapi sapi, boolean c_r, boolean p, octetstring pl) := {
407 addr := ts_LapdmAddr(sapi, c_r),
408 ctrl := t_LapdmCtrlUI(p),
409 len := 0, /* overwritten */
410 m := false,
411 el := 1,
412 payload := pl
413}
414
415/* handle incoming downlink SACCH and respond with uplink SACCH (meas res) */
416altstep as_l1_sacch() runs on ConnHdlr {
417 var L1ctlDlMessage l1_dl;
418 [] L1CTL.receive(t_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
419 log("SACCH received: ", l1_dl.payload.data_ind.payload);
420 var GsmRrL3Message meas_rep := valueof(ts_MEAS_REP(true, 23, 23, 0, 0, omit));
421 var LapdmFrameB lb := valueof(ts_LAPDm_B(0, false, false, enc_GsmRrL3Message(meas_rep)));
422 log("LAPDm: ", lb);
423 var octetstring pl := '0000'O & enc_LapdmFrameB(lb);
424 L1CTL.send(t_L1CTL_DATA_REQ(g_chan_nr, ts_RslLinkID_SACCH(0), pl));
425 repeat;
426 }
427}
428
429altstep as_l1_dcch() runs on ConnHdlr {
430 var L1ctlDlMessage l1_dl;
431 [] L1CTL.receive(t_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_DCCH(?))) -> value l1_dl {
432 log("DCCH received: ", l1_dl.payload.data_ind.payload);
433 var octetstring pl := '010301'O;
434 L1CTL.send(t_L1CTL_DATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0), pl));
435 repeat;
436 }
437}
438
439type record MeasElem {
440 uint6_t rxlev,
441 uint3_t rxqual
442}
443
444type record MeasElemFS {
445 MeasElem full,
446 MeasElem sub
447}
448
449type record ConnL1Pars {
450 boolean dtx_enabled,
451 MeasElemFS meas_ul,
452 int16_t timing_offset_256syms,
453 uint5_t bs_power_level,
454 uint5_t ms_power_level,
455 uint8_t ms_actual_ta
456}
457
458/* Convert tiing offset from 1/256th symbol to RSL Timing Offset */
459private function toffs256s_to_rsl(int16_t toffs256s) return uint8_t {
460 return 63 + (toffs256s/256);
461}
462
463/* build a template for matching measurement results against */
464private function f_build_meas_res_tmpl() runs on ConnHdlr return template RSL_Message {
465 var ConnL1Pars l1p := g_pars.l1_pars;
466 var template RSL_IE_UplinkMeas ul_meas := {
467 len := 3,
468 rfu := '0'B,
469 dtx_d := l1p.dtx_enabled,
470 rxlev_f_u := l1p.meas_ul.full.rxlev,
471 reserved1 := '00'B,
472 rxlev_s_u := l1p.meas_ul.sub.rxlev,
473 reserved2 := '00'B,
474 rxq_f_u := l1p.meas_ul.full.rxqual,
475 rxq_s_u := l1p.meas_ul.sub.rxqual,
476 supp_meas_info := omit
477 };
478 /* HACK HACK HACK FIXME HACK HACK HACK see https://osmocom.org/issues/2988 */
479 ul_meas.rxlev_f_u := ?;
480 ul_meas.rxlev_s_u := ?;
481 ul_meas.rxq_f_u := ?;
482 ul_meas.rxq_s_u := ?;
483 var template RSL_IE_BS_Power bs_power := {
484 reserved := 0,
485 epc := false,
486 fpc := false,
487 power_level := l1p.bs_power_level
488 };
489 var template RSL_IE_L1Info l1_info := {
490 ms_power_lvl := l1p.ms_power_level,
491 fpc := false,
492 reserved := 0,
493 actual_ta := l1p.ms_actual_ta
494 };
495 var uint8_t offs := toffs256s_to_rsl(l1p.timing_offset_256syms);
496 var template uint8_t t_toffs := (offs-1 .. offs+1); /* some tolerance */
497 return tr_RSL_MEAS_RES_OSMO(g_chan_nr, g_next_meas_res_nr, ul_meas, bs_power, l1_info,
498 ?, t_toffs);
499}
500
501/* verify we regularly receive measurement reports with incrementing numbers */
502altstep as_meas_res() runs on ConnHdlr {
503 var RSL_Message rsl;
504 [] RSL.receive(f_build_meas_res_tmpl()) -> value rsl {
505 /* increment counter of next to-be-expected meas rep */
506 g_next_meas_res_nr := (g_next_meas_res_nr + 1) mod 256;
507 /* Re-start the timer expecting the next MEAS RES */
508 g_Tmeas_exp.start;
509 repeat;
510 }
511 [] RSL.receive(tr_RSL_MEAS_RES(g_chan_nr, g_next_meas_res_nr)) -> value rsl {
512 setverdict(fail, "Received unspecific MEAS RES ", rsl);
513 self.stop;
514 }
515 [] RSL.receive(tr_RSL_MEAS_RES(?)) -> value rsl {
516 setverdict(fail, "Received unexpected MEAS RES ", rsl);
517 self.stop;
518 }
519 [] g_Tmeas_exp.timeout {
520 setverdict(fail, "Didn't receive expected measurement result")
521 self.stop;
522 }
523}
524
525/* Establish dedicated channel: L1CTL + RSL side */
526private function f_est_dchan() runs on ConnHdlr {
527 var GsmFrameNumber fn;
528 var ImmediateAssignment imm_ass;
529 var integer ra := 23;
530
531 fn := f_L1CTL_RACH(L1CTL, ra);
532 /* This arrives on CCHAN, so we cannot test for receiving CHAN RQDhere */
533 //RSL.receive(tr_RSL_CHAN_RQD(int2oct(23,1)));
534
535 /* Activate channel on BTS side */
536 f_rsl_chan_act(g_pars.chan_mode);
537
538 /* Send IMM.ASS via CCHAN */
539 var ChannelDescription ch_desc := {
540 chan_nr := g_pars.chan_nr,
541 tsc := 7,
542 h := false,
543 arfcn := mp_trx0_arfcn,
544 maio_hsn := omit
545 };
546 var MobileAllocation ma := {
547 len := 0,
548 ma := ''B
549 };
550 var GsmRrMessage rr_msg := valueof(ts_IMM_ASS(ra, fn, 0, ch_desc, ma));
551 RSL.send(ts_RSL_IMM_ASSIGN(enc_GsmRrMessage(rr_msg)));
552
553 /* receive IMM.ASS on MS side */
554 var ImmediateAssignment ia_um;
555 ia_um := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, fn);
556 /* enable dedicated mode */
557 f_L1CTL_DM_EST_REQ_IA(L1CTL, ia_um);
558}
559
560/* establish DChan, verify existance + contents of measurement reports */
561function f_TC_meas_res_periodic(charstring id) runs on ConnHdlr {
562 f_l1_tune();
563 RSL.clear;
564
565 g_pars.l1_pars.meas_ul.full.rxlev := dbm2rxlev(-100);
566 g_pars.l1_pars.meas_ul.sub.rxlev := g_pars.l1_pars.meas_ul.full.rxlev;
567 f_trxc_fake_rssi(100);
568
569 g_pars.l1_pars.timing_offset_256syms := 512; /* 2 symbols */
570 f_trx_fake_toffs256(g_pars.l1_pars.timing_offset_256syms);
571
572 f_est_dchan();
573
574 /* run for a number of seconds, send SACCH + FACCH from MS side and verify
575 * RSL measurement reports on Abis side */
576 timer T := 8.0;
577 T.start;
578 alt {
579 [] as_l1_sacch();
580 [] as_meas_res();
581 [] as_l1_dcch();
582 [] L1CTL.receive { repeat; }
583 [g_Tmeas_exp.running] T.timeout {
584 /* as_meas_res() would have done setverdict(fail) / self.stop in case
585 * of any earlier errors, so if we reach this timeout, we're good */
586 setverdict(pass);
587 }
588 [] T.timeout {
589 setverdict(fail, "No MEAS RES received at all");
590 }
591 }
592 f_rsl_chan_deact();
593}
594testcase TC_meas_res_sign_tchf() runs on test_CT {
595 var ConnHdlr vc_conn;
596 var ConnHdlrPars pars;
597 f_init(testcasename());
598 for (var integer tn := 1; tn <= 4; tn := tn+1) {
599 pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN));
600 vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars);
601 vc_conn.done;
602 }
603}
604testcase TC_meas_res_sign_tchh() runs on test_CT {
605 var ConnHdlr vc_conn;
606 var ConnHdlrPars pars;
607 f_init(testcasename());
608 for (var integer ss := 0; ss <= 1; ss := ss+1) {
609 pars := valueof(t_Pars(t_RslChanNr_Lm(5, ss), ts_RSL_ChanMode_SIGN));
610 vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars);
611 vc_conn.done;
612 }
613}
614testcase TC_meas_res_sign_sdcch4() runs on test_CT {
615 var ConnHdlr vc_conn;
616 var ConnHdlrPars pars;
617 f_init(testcasename());
618 for (var integer ss := 0; ss <= 3; ss := ss+1) {
619 pars := valueof(t_Pars(t_RslChanNr_SDCCH4(0, ss), ts_RSL_ChanMode_SIGN));
620 vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars);
621 vc_conn.done;
622 }
623}
624testcase TC_meas_res_sign_sdcch8() runs on test_CT {
625 var ConnHdlr vc_conn;
626 var ConnHdlrPars pars;
627 f_init(testcasename());
628 for (var integer ss := 0; ss <= 7; ss := ss+1) {
629 pars := valueof(t_Pars(t_RslChanNr_SDCCH8(6, ss), ts_RSL_ChanMode_SIGN));
630 vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars);
631 vc_conn.done;
632 }
633}
634
635/* Test if a channel without valid uplink bursts generates RSL CONN FAIL IND */
636private function f_TC_conn_fail_crit(charstring id) runs on ConnHdlr {
637 f_l1_tune();
638 RSL.clear;
639
640 f_est_dchan();
641 f_sleep(2.0);
642 L1CTL.send(t_L1CTL_DM_REL_REQ(g_chan_nr));
643
644 timer T := 40.0;
645 T.start;
646 alt {
647 [] RSL.receive(tr_RSL_CONN_FAIL_IND(g_chan_nr, ?)) {
648 setverdict(pass)
649 }
650 [] RSL.receive { repeat };
651 [] T.timeout {
652 setverdict(fail, "No CONN FAIL IND received");
653 }
654 }
655 f_rsl_chan_deact();
656}
657testcase TC_conn_fail_crit() runs on test_CT {
658 var ConnHdlr vc_conn;
659 var ConnHdlrPars pars;
660 f_init(testcasename());
661 pars := valueof(t_Pars(t_RslChanNr_SDCCH8(6, 3), ts_RSL_ChanMode_SIGN));
662 pars.t_guard := 60.0;
663 vc_conn := f_start_handler(refers(f_TC_conn_fail_crit), pars);
664 vc_conn.done;
665}
666
667
668
669
670control {
671 execute( TC_chan_act_stress() );
672 execute( TC_chan_act_react() );
673 execute( TC_chan_deact_not_active() );
674 execute( TC_chan_act_wrong_nr() );
675 execute( TC_chan_req() );
676 execute( TC_meas_res_sign_tchf() );
677 execute( TC_meas_res_sign_tchh() );
678 execute( TC_meas_res_sign_sdcch4() );
679 execute( TC_meas_res_sign_sdcch8() );
680 execute( TC_conn_fail_crit() );
681}
682
683
684}