blob: 33aa174d2188506ce9fd2fdcb5804cbadcf518b6 [file] [log] [blame]
Harald Welte97cca2f2019-05-30 16:33:38 +02001module BTS_Tests_LAPDm {
Harald Weltef6543322017-07-16 07:35:10 +02002
Harald Welte72c81e72019-05-30 16:36:11 +02003import from GSM_Types all;
4import from Osmocom_Types all;
5import from LAPDm_RAW_PT all;
6import from LAPDm_Types all;
7import from BTS_Tests all;
Harald Welte66110f02017-07-16 21:05:18 +02008
Harald Welte72c81e72019-05-30 16:36:11 +02009/* test that use exclusively only LAPDm over L1CTL */
10type component lapdm_test_CT {
11 port LAPDm_PT LAPDM;
12 var lapdm_CT lapdm_component;
13};
14
15/* contrary to BTS_Tests.ttcn, we use LAPDm_PT here, a convenience wrapper
16 * around L1CTL to perform encode/decode of abstract LAPDm frames */
17type component lapdm_bts_CT extends lapdm_test_CT, test_CT {
18}
19
Harald Welte61332c02019-05-30 16:45:15 +020020/*********************************************************************************
21 * Test using only L1CTL/LAPDm
22 *********************************************************************************/
23
24function f_lapdm_init() runs on lapdm_test_CT {
Harald Welte72c81e72019-05-30 16:36:11 +020025 /* create the LAPDm component */
26 lapdm_component := lapdm_CT.create;
27 /* connect our own LAPDM port to the LAPDM Service Provider of the LAPDm component */
28 connect(self:LAPDM, lapdm_component:LAPDM_SP);
29 /* connect the LAPDm compoent's lower-side port to the system L1CTL port (which is internally
30 * connected to the Unix Domain Socket test port */
31 map(lapdm_component:L1CTL, system:L1CTL);
32
33 /* start the LAPDm parallel component calling it's local function LAPDmStart */
34 lapdm_component.start(LAPDmStart());
35}
36
37/* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */
38function f_establish_dcch() runs on lapdm_test_CT {
39 var BCCH_tune_req tune_req := { arfcn := { false, 871 }, combined_ccch := true };
40 var DCCH_establish_req est_req := { ra := 23 };
41
42 LAPDM.send(tune_req);
43 LAPDM.send(est_req);
44 LAPDM.receive(DCCH_establish_res:?);
45}
46
47/* helper function releasing dedicated radio channel physically (no Um signaling!) */
48function f_release_dcch() runs on lapdm_test_CT {
49 var DCCH_release_req rel_req := {};
50 LAPDM.send(rel_req);
51}
52
53template LAPDm_ph_data t_PH_DATA(template GsmSapi sapi, template boolean sacch, template LapdmFrame frame) := {
54 sacch := sacch,
55 sapi := sapi,
56 lapdm := frame
57}
58/* template for a valid SABM frame */
59template LapdmFrame LAPDm_B_SABM(template GsmSapi sapi, octetstring payload) := {
60 ab := {
61 addr := tr_LapdmAddr(sapi, false),
62 ctrl := tr_LapdmCtrlSABM(true),
63 len := lengthof(payload),
64 m := false,
65 el := 1,
66 payload := payload
Harald Weltec38611b2019-05-30 16:33:58 +020067 }
Harald Welte72c81e72019-05-30 16:36:11 +020068}
Harald Weltec38611b2019-05-30 16:33:58 +020069
Harald Welte72c81e72019-05-30 16:36:11 +020070/* template for a valid UA frame */
71template LapdmFrame tr_LAPDm_B_UA(template GsmSapi sapi, template octetstring payload) := {
72 ab := {
73 addr := tr_LapdmAddr(sapi, false),
74 ctrl := tr_LapdmCtrlUA(true),
75 len := ?,
76 m := false,
77 el := 1,
78 payload := payload
Harald Welte52c713c2017-07-16 15:44:44 +020079 }
Harald Welte72c81e72019-05-30 16:36:11 +020080}
Harald Welte52c713c2017-07-16 15:44:44 +020081
Harald Welte72c81e72019-05-30 16:36:11 +020082/* template for a valid UA frame */
83template LapdmFrame LAPDm_B_UA(template GsmSapi sapi, octetstring payload) := {
84 ab := {
85 addr := tr_LapdmAddr(sapi, false),
86 ctrl := tr_LapdmCtrlUA(true),
87 len := lengthof(payload),
88 m := false,
89 el := 1,
90 payload := payload
Harald Welte9e4725d2017-07-16 23:18:09 +020091 }
Harald Welte72c81e72019-05-30 16:36:11 +020092}
Harald Welte66110f02017-07-16 21:05:18 +020093
Harald Welte72c81e72019-05-30 16:36:11 +020094/* template for a valid UI frame */
95template LapdmFrame LAPDm_B_UI(template GsmSapi sapi, octetstring payload) := {
96 ab := {
97 addr := tr_LapdmAddr(sapi, true),
98 ctrl := tr_LapdmCtrlUI(false),
99 len := lengthof(payload),
100 m := false,
101 el := 1,
102 payload := payload
Harald Welte9e4725d2017-07-16 23:18:09 +0200103 }
Harald Welte72c81e72019-05-30 16:36:11 +0200104}
Harald Welte9e4725d2017-07-16 23:18:09 +0200105
Harald Welte72c81e72019-05-30 16:36:11 +0200106template LapdmFrame t_nopayload(template GsmSapi sapi) := {
107 ab := {
108 addr := tr_LapdmAddr(sapi, true),
109 ctrl := ?,
110 len := 0,
111 m := false,
112 el := 1,
113 payload := ''O
Harald Welted4ba7ff2017-07-17 21:00:48 +0200114 }
Harald Welte72c81e72019-05-30 16:36:11 +0200115}
116
117template LapdmFrame LAPDm_B_DISC(template GsmSapi sapi) modifies t_nopayload := {
118 ab := {
119 ctrl := tr_LapdmCtrlDISC(true)
120 }
121}
122
123template LapdmFrame LAPDm_B_RR(template GsmSapi sapi, template uint3_t nr) modifies t_nopayload := {
124 ab := {
125 ctrl := tr_LapdmCtrlRR(nr, false)
126 }
127}
128
129
130function f_test_sabm_results_in_ua(uint8_t sapi, boolean use_sacch, octetstring payload) runs on lapdm_test_CT return boolean {
131 var LAPDm_ph_data phd;
132 var boolean result := false;
133 timer T := 5.0;
134
135 f_establish_dcch();
136 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
137 log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
138 T.start
139 alt {
140 [] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { result := true; }
141 [] LAPDM.receive(t_PH_DATA(?, use_sacch, ?)) -> value phd { log("Other msg on DCH: ", phd); repeat; }
142 [] LAPDM.receive(t_PH_DATA(?, ?, ?)) -> value phd { log("Other PH-DATA: ", phd); repeat; }
143 [] T.timeout { }
144 }
145 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_RR(sapi, 0)));
146 f_release_dcch();
147 return result;
148}
149
150testcase TC_sabm_ua_dcch_sapi0() runs on lapdm_test_CT {
Harald Welte61332c02019-05-30 16:45:15 +0200151 f_lapdm_init();
Harald Welte72c81e72019-05-30 16:36:11 +0200152 if (not f_test_sabm_results_in_ua(0, false, 'FEFE'O)) {
153 setverdict(fail);
154 }
155 setverdict(pass);
156}
157
158testcase TC_sabm_ua_dcch_sapi0_nopayload() runs on lapdm_test_CT {
Harald Welte61332c02019-05-30 16:45:15 +0200159 f_lapdm_init();
Harald Welte72c81e72019-05-30 16:36:11 +0200160 if (f_test_sabm_results_in_ua(0, false, ''O)) {
161 setverdict(fail, "Initial SABM/UA must contain L3 payload but BTS accepts without");
162 }
163 setverdict(pass);
164}
165
166testcase TC_sabm_ua_dcch_sapi3() runs on lapdm_test_CT {
Harald Welte61332c02019-05-30 16:45:15 +0200167 f_lapdm_init();
Harald Welte72c81e72019-05-30 16:36:11 +0200168 if (f_test_sabm_results_in_ua(3, false, 'FEFE'O)) {
169 setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=3");
170 }
171 setverdict(pass);
172}
173
174testcase TC_sabm_ua_dcch_sapi4() runs on lapdm_test_CT {
Harald Welte61332c02019-05-30 16:45:15 +0200175 f_lapdm_init();
Harald Welte72c81e72019-05-30 16:36:11 +0200176 if (f_test_sabm_results_in_ua(4, false, 'FEFE'O)) {
177 setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=4");
178 }
179 setverdict(pass);
180}
181
182testcase TC_sabm_contention() runs on lapdm_test_CT {
183 var LAPDm_ph_data phd;
184 const octetstring payload := '0102030405'O;
185 const GsmSapi sapi := 0;
186 const boolean use_sacch := false;
187 timer T := 5.0;
188
Harald Welte61332c02019-05-30 16:45:15 +0200189 f_lapdm_init();
Harald Welte72c81e72019-05-30 16:36:11 +0200190
191 f_establish_dcch();
192 /* first frame is our real SABM */
193 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
194 /* second frame is a SABM with different payload, which BTS has to ignore according to 8.4.1.4 */
195 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, 'ABCDEF'O)));
196 log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
197 T.start
198 alt {
199 [] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { setverdict(pass); repeat; }
200 [] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_B_UA(sapi, ?))) {
201 setverdict(fail, "Second SABM was responded to during contention resolution");
Harald Welted4ba7ff2017-07-17 21:00:48 +0200202 }
Harald Welte72c81e72019-05-30 16:36:11 +0200203 [] LAPDM.receive { repeat };
204 [] T.timeout { }
Harald Welte9e4725d2017-07-16 23:18:09 +0200205 }
Harald Welte72c81e72019-05-30 16:36:11 +0200206 f_release_dcch();
207}
Harald Welte9e4725d2017-07-16 23:18:09 +0200208
Harald Welte72c81e72019-05-30 16:36:11 +0200209/* we test that a re-transmitted SABM with identical payload will result in the retransmission of a
210 * UA. This is required during the contention resolution procedure as specified in 8.4.1.4 */
211testcase TC_sabm_retransmit() runs on lapdm_test_CT {
212 const octetstring payload := '00FEFEDEADBEEF'O;
Harald Welte61332c02019-05-30 16:45:15 +0200213 f_lapdm_init();
Harald Welte72c81e72019-05-30 16:36:11 +0200214 if (not f_test_sabm_results_in_ua(0, false, payload)) {
215 setverdict(fail, "UA not received for first SABM");
Harald Welte599faa12017-07-17 21:49:24 +0200216 }
Harald Welte72c81e72019-05-30 16:36:11 +0200217 if (not f_test_sabm_results_in_ua(0, false, payload)) {
218 setverdict(fail, "UA not received for second SABM");
Harald Welted4ba7ff2017-07-17 21:00:48 +0200219 }
Harald Welte72c81e72019-05-30 16:36:11 +0200220 setverdict(pass);
221}
Harald Welted4ba7ff2017-07-17 21:00:48 +0200222
Harald Welte72c81e72019-05-30 16:36:11 +0200223testcase TC_foo() runs on lapdm_test_CT {
224 var LapdmFrame lf;
Harald Welted4ba7ff2017-07-17 21:00:48 +0200225/*
Harald Welte72c81e72019-05-30 16:36:11 +0200226 var LapdmFrame lf := valueof(LAPDm_B_UA(0, ''O));
227 log("ENC UA: ", enc_LapdmFrame(lf));
228 lf := valueof(LAPDm_B_UI(0, ''O));
229 log("ENC UI B: ", enc_LapdmFrame(lf));
230 log("ENC UI B: ", enc_LapdmFrameB(lf.b));
Harald Welted4ba7ff2017-07-17 21:00:48 +0200231
Harald Welte72c81e72019-05-30 16:36:11 +0200232 log("DEC UI AF: ", dec_LapdmAddressField('03'O));
Harald Welted4ba7ff2017-07-17 21:00:48 +0200233*/
Harald Welteffcad682017-07-30 22:51:04 +0200234
Harald Welte72c81e72019-05-30 16:36:11 +0200235 lf := valueof(LAPDm_B_RR(0, 0));
236 log("ENC RR: ", enc_LapdmFrame(lf));
Harald Welteffcad682017-07-30 22:51:04 +0200237
Harald Welte72c81e72019-05-30 16:36:11 +0200238 lf := valueof(LAPDm_B_UA(0, ''O));
239 log("ENC UA: ", enc_LapdmFrame(lf));
Harald Welteffcad682017-07-30 22:51:04 +0200240
Harald Welte72c81e72019-05-30 16:36:11 +0200241 lf := valueof(LAPDm_B_UI(0, ''O));
242 log("ENC UI: ", enc_LapdmFrame(lf));
Harald Welteffcad682017-07-30 22:51:04 +0200243
Harald Welte72c81e72019-05-30 16:36:11 +0200244 log("DEC UI CU: ", dec_LapdmCtrlU('03'O));
245 log("DEC UI CT: ", dec_LapdmCtrl('03'O));
Harald Welted4ba7ff2017-07-17 21:00:48 +0200246
Harald Welte72c81e72019-05-30 16:36:11 +0200247 log("DEC UA: ", dec_LapdmFrameAB('017301'O));
248 log("DEC UI: ", dec_LapdmFrameAB('030301'O));
249 log("DEC I: ", dec_LapdmFrameAB('030001'O));
250 log("DEC S: ", dec_LapdmFrameAB('030101'O));
251 log("DEC: ", dec_LapdmFrameAB('030301'O));
252 log("DEC: ", dec_LapdmFrameAB('0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O));
253}
Harald Welted4ba7ff2017-07-17 21:00:48 +0200254
Harald Welte72c81e72019-05-30 16:36:11 +0200255control {
256 execute(TC_foo());
257 execute(TC_sabm_ua_dcch_sapi0());
258 execute(TC_sabm_ua_dcch_sapi0_nopayload());
259 execute(TC_sabm_ua_dcch_sapi3());
260 execute(TC_sabm_ua_dcch_sapi4());
261 execute(TC_sabm_contention());
262 execute(TC_sabm_retransmit());
263}
264
Harald Weltef6543322017-07-16 07:35:10 +0200265}