blob: 07928637774db56fd7d981224e31cbf2371c7c58 [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
20function f_init() runs on lapdm_test_CT {
21 /* create the LAPDm component */
22 lapdm_component := lapdm_CT.create;
23 /* connect our own LAPDM port to the LAPDM Service Provider of the LAPDm component */
24 connect(self:LAPDM, lapdm_component:LAPDM_SP);
25 /* connect the LAPDm compoent's lower-side port to the system L1CTL port (which is internally
26 * connected to the Unix Domain Socket test port */
27 map(lapdm_component:L1CTL, system:L1CTL);
28
29 /* start the LAPDm parallel component calling it's local function LAPDmStart */
30 lapdm_component.start(LAPDmStart());
31}
32
33/* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */
34function f_establish_dcch() runs on lapdm_test_CT {
35 var BCCH_tune_req tune_req := { arfcn := { false, 871 }, combined_ccch := true };
36 var DCCH_establish_req est_req := { ra := 23 };
37
38 LAPDM.send(tune_req);
39 LAPDM.send(est_req);
40 LAPDM.receive(DCCH_establish_res:?);
41}
42
43/* helper function releasing dedicated radio channel physically (no Um signaling!) */
44function f_release_dcch() runs on lapdm_test_CT {
45 var DCCH_release_req rel_req := {};
46 LAPDM.send(rel_req);
47}
48
49template LAPDm_ph_data t_PH_DATA(template GsmSapi sapi, template boolean sacch, template LapdmFrame frame) := {
50 sacch := sacch,
51 sapi := sapi,
52 lapdm := frame
53}
54/* template for a valid SABM frame */
55template LapdmFrame LAPDm_B_SABM(template GsmSapi sapi, octetstring payload) := {
56 ab := {
57 addr := tr_LapdmAddr(sapi, false),
58 ctrl := tr_LapdmCtrlSABM(true),
59 len := lengthof(payload),
60 m := false,
61 el := 1,
62 payload := payload
Harald Weltec38611b2019-05-30 16:33:58 +020063 }
Harald Welte72c81e72019-05-30 16:36:11 +020064}
Harald Weltec38611b2019-05-30 16:33:58 +020065
Harald Welte72c81e72019-05-30 16:36:11 +020066/* template for a valid UA frame */
67template LapdmFrame tr_LAPDm_B_UA(template GsmSapi sapi, template octetstring payload) := {
68 ab := {
69 addr := tr_LapdmAddr(sapi, false),
70 ctrl := tr_LapdmCtrlUA(true),
71 len := ?,
72 m := false,
73 el := 1,
74 payload := payload
Harald Welte52c713c2017-07-16 15:44:44 +020075 }
Harald Welte72c81e72019-05-30 16:36:11 +020076}
Harald Welte52c713c2017-07-16 15:44:44 +020077
Harald Welte72c81e72019-05-30 16:36:11 +020078/* template for a valid UA frame */
79template LapdmFrame LAPDm_B_UA(template GsmSapi sapi, octetstring payload) := {
80 ab := {
81 addr := tr_LapdmAddr(sapi, false),
82 ctrl := tr_LapdmCtrlUA(true),
83 len := lengthof(payload),
84 m := false,
85 el := 1,
86 payload := payload
Harald Welte9e4725d2017-07-16 23:18:09 +020087 }
Harald Welte72c81e72019-05-30 16:36:11 +020088}
Harald Welte66110f02017-07-16 21:05:18 +020089
Harald Welte72c81e72019-05-30 16:36:11 +020090/* template for a valid UI frame */
91template LapdmFrame LAPDm_B_UI(template GsmSapi sapi, octetstring payload) := {
92 ab := {
93 addr := tr_LapdmAddr(sapi, true),
94 ctrl := tr_LapdmCtrlUI(false),
95 len := lengthof(payload),
96 m := false,
97 el := 1,
98 payload := payload
Harald Welte9e4725d2017-07-16 23:18:09 +020099 }
Harald Welte72c81e72019-05-30 16:36:11 +0200100}
Harald Welte9e4725d2017-07-16 23:18:09 +0200101
Harald Welte72c81e72019-05-30 16:36:11 +0200102template LapdmFrame t_nopayload(template GsmSapi sapi) := {
103 ab := {
104 addr := tr_LapdmAddr(sapi, true),
105 ctrl := ?,
106 len := 0,
107 m := false,
108 el := 1,
109 payload := ''O
Harald Welted4ba7ff2017-07-17 21:00:48 +0200110 }
Harald Welte72c81e72019-05-30 16:36:11 +0200111}
112
113template LapdmFrame LAPDm_B_DISC(template GsmSapi sapi) modifies t_nopayload := {
114 ab := {
115 ctrl := tr_LapdmCtrlDISC(true)
116 }
117}
118
119template LapdmFrame LAPDm_B_RR(template GsmSapi sapi, template uint3_t nr) modifies t_nopayload := {
120 ab := {
121 ctrl := tr_LapdmCtrlRR(nr, false)
122 }
123}
124
125
126function f_test_sabm_results_in_ua(uint8_t sapi, boolean use_sacch, octetstring payload) runs on lapdm_test_CT return boolean {
127 var LAPDm_ph_data phd;
128 var boolean result := false;
129 timer T := 5.0;
130
131 f_establish_dcch();
132 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
133 log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
134 T.start
135 alt {
136 [] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { result := true; }
137 [] LAPDM.receive(t_PH_DATA(?, use_sacch, ?)) -> value phd { log("Other msg on DCH: ", phd); repeat; }
138 [] LAPDM.receive(t_PH_DATA(?, ?, ?)) -> value phd { log("Other PH-DATA: ", phd); repeat; }
139 [] T.timeout { }
140 }
141 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_RR(sapi, 0)));
142 f_release_dcch();
143 return result;
144}
145
146testcase TC_sabm_ua_dcch_sapi0() runs on lapdm_test_CT {
147 f_init();
148 if (not f_test_sabm_results_in_ua(0, false, 'FEFE'O)) {
149 setverdict(fail);
150 }
151 setverdict(pass);
152}
153
154testcase TC_sabm_ua_dcch_sapi0_nopayload() runs on lapdm_test_CT {
155 f_init();
156 if (f_test_sabm_results_in_ua(0, false, ''O)) {
157 setverdict(fail, "Initial SABM/UA must contain L3 payload but BTS accepts without");
158 }
159 setverdict(pass);
160}
161
162testcase TC_sabm_ua_dcch_sapi3() runs on lapdm_test_CT {
163 f_init();
164 if (f_test_sabm_results_in_ua(3, false, 'FEFE'O)) {
165 setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=3");
166 }
167 setverdict(pass);
168}
169
170testcase TC_sabm_ua_dcch_sapi4() runs on lapdm_test_CT {
171 f_init();
172 if (f_test_sabm_results_in_ua(4, false, 'FEFE'O)) {
173 setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=4");
174 }
175 setverdict(pass);
176}
177
178testcase TC_sabm_contention() runs on lapdm_test_CT {
179 var LAPDm_ph_data phd;
180 const octetstring payload := '0102030405'O;
181 const GsmSapi sapi := 0;
182 const boolean use_sacch := false;
183 timer T := 5.0;
184
185 f_init();
186
187 f_establish_dcch();
188 /* first frame is our real SABM */
189 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
190 /* second frame is a SABM with different payload, which BTS has to ignore according to 8.4.1.4 */
191 LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, 'ABCDEF'O)));
192 log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
193 T.start
194 alt {
195 [] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { setverdict(pass); repeat; }
196 [] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_B_UA(sapi, ?))) {
197 setverdict(fail, "Second SABM was responded to during contention resolution");
Harald Welted4ba7ff2017-07-17 21:00:48 +0200198 }
Harald Welte72c81e72019-05-30 16:36:11 +0200199 [] LAPDM.receive { repeat };
200 [] T.timeout { }
Harald Welte9e4725d2017-07-16 23:18:09 +0200201 }
Harald Welte72c81e72019-05-30 16:36:11 +0200202 f_release_dcch();
203}
Harald Welte9e4725d2017-07-16 23:18:09 +0200204
Harald Welte72c81e72019-05-30 16:36:11 +0200205/* we test that a re-transmitted SABM with identical payload will result in the retransmission of a
206 * UA. This is required during the contention resolution procedure as specified in 8.4.1.4 */
207testcase TC_sabm_retransmit() runs on lapdm_test_CT {
208 const octetstring payload := '00FEFEDEADBEEF'O;
209 f_init();
210 if (not f_test_sabm_results_in_ua(0, false, payload)) {
211 setverdict(fail, "UA not received for first SABM");
Harald Welte599faa12017-07-17 21:49:24 +0200212 }
Harald Welte72c81e72019-05-30 16:36:11 +0200213 if (not f_test_sabm_results_in_ua(0, false, payload)) {
214 setverdict(fail, "UA not received for second SABM");
Harald Welted4ba7ff2017-07-17 21:00:48 +0200215 }
Harald Welte72c81e72019-05-30 16:36:11 +0200216 setverdict(pass);
217}
Harald Welted4ba7ff2017-07-17 21:00:48 +0200218
Harald Welte72c81e72019-05-30 16:36:11 +0200219testcase TC_foo() runs on lapdm_test_CT {
220 var LapdmFrame lf;
Harald Welted4ba7ff2017-07-17 21:00:48 +0200221/*
Harald Welte72c81e72019-05-30 16:36:11 +0200222 var LapdmFrame lf := valueof(LAPDm_B_UA(0, ''O));
223 log("ENC UA: ", enc_LapdmFrame(lf));
224 lf := valueof(LAPDm_B_UI(0, ''O));
225 log("ENC UI B: ", enc_LapdmFrame(lf));
226 log("ENC UI B: ", enc_LapdmFrameB(lf.b));
Harald Welted4ba7ff2017-07-17 21:00:48 +0200227
Harald Welte72c81e72019-05-30 16:36:11 +0200228 log("DEC UI AF: ", dec_LapdmAddressField('03'O));
Harald Welted4ba7ff2017-07-17 21:00:48 +0200229*/
Harald Welteffcad682017-07-30 22:51:04 +0200230
Harald Welte72c81e72019-05-30 16:36:11 +0200231 lf := valueof(LAPDm_B_RR(0, 0));
232 log("ENC RR: ", enc_LapdmFrame(lf));
Harald Welteffcad682017-07-30 22:51:04 +0200233
Harald Welte72c81e72019-05-30 16:36:11 +0200234 lf := valueof(LAPDm_B_UA(0, ''O));
235 log("ENC UA: ", enc_LapdmFrame(lf));
Harald Welteffcad682017-07-30 22:51:04 +0200236
Harald Welte72c81e72019-05-30 16:36:11 +0200237 lf := valueof(LAPDm_B_UI(0, ''O));
238 log("ENC UI: ", enc_LapdmFrame(lf));
Harald Welteffcad682017-07-30 22:51:04 +0200239
Harald Welte72c81e72019-05-30 16:36:11 +0200240 log("DEC UI CU: ", dec_LapdmCtrlU('03'O));
241 log("DEC UI CT: ", dec_LapdmCtrl('03'O));
Harald Welted4ba7ff2017-07-17 21:00:48 +0200242
Harald Welte72c81e72019-05-30 16:36:11 +0200243 log("DEC UA: ", dec_LapdmFrameAB('017301'O));
244 log("DEC UI: ", dec_LapdmFrameAB('030301'O));
245 log("DEC I: ", dec_LapdmFrameAB('030001'O));
246 log("DEC S: ", dec_LapdmFrameAB('030101'O));
247 log("DEC: ", dec_LapdmFrameAB('030301'O));
248 log("DEC: ", dec_LapdmFrameAB('0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O));
249}
Harald Welted4ba7ff2017-07-17 21:00:48 +0200250
Harald Welte72c81e72019-05-30 16:36:11 +0200251control {
252 execute(TC_foo());
253 execute(TC_sabm_ua_dcch_sapi0());
254 execute(TC_sabm_ua_dcch_sapi0_nopayload());
255 execute(TC_sabm_ua_dcch_sapi3());
256 execute(TC_sabm_ua_dcch_sapi4());
257 execute(TC_sabm_contention());
258 execute(TC_sabm_retransmit());
259}
260
Harald Weltef6543322017-07-16 07:35:10 +0200261}