aboutsummaryrefslogtreecommitdiffstats
path: root/pcu/PCU_selftest.ttcn
blob: 70138bff5e3219929fc6fcbf2de2a473fb4e3de1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
module PCU_selftest {
/*
 * Osmocom PCU test suite in TTCN-3, selftest procedures
 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
 * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

import from BSSGP_Types all;
import from BSSGP_Emulation all;
import from NS_Types all;
import from NS_Emulation all;
import from GPRS_Context all;
import from Osmocom_Gb_Types all;
import from Osmocom_Types all;
import from LLC_Types all;
import from LLC_Templates all;
import from L3_Templates all;
import from GSM_RR_Types all;
import from RLCMAC_CSN1_Types all;
import from RLCMAC_Types all;
import from RLCMAC_Templates all;
import from GPRS_Components all;
import from PCU_Tests all;

type component dummy_CT extends BSSGP_Client_CT {
	var NS_CT ns_component;
	var BSSGP_CT bssgp_component;

	var MmContext g_mmctx := {
		tlli := 'FFFFFFFF'O,
		n_u := 0
	};

	var boolean g_initialized := false;
}


///////////////////
// BSSGP selftest
///////////////////
function f_bssgp_dec_and_log(in octetstring inp) {
	log("BSSGP Input: ", inp);
	var PDU_BSSGP dec := dec_PDU_BSSGP(inp);
	log("BSSGP Decoded: ", dec);
}

testcase TC_selftest_bssgp() runs on dummy_CT {
	const octetstring c_bvc_reset_pcu := '2204820000078108088832f44000c80051e0'O;
	const octetstring c_bvc_reset_q := '2204820000078100'O;
	const octetstring c_status_pcu := '4107810515882204820000078103'O;
	const octetstring c_reset_ack_q := '2304820000'O;
	const octetstring c_reset_ack_pcu := '23048200c4'O;
	const octetstring c_unblock_pcu := '24048200c4'O;
	const octetstring c_unblock_ack_q := '25048200c4'O;
	const octetstring c_fc_bvc_pcu := '261e8101058200fa038200c8018200fa1c8200c806820000'O;
	const octetstring c_fc_bvc_ack_q := '271e8101'O;
	const octetstring c_gmm_mo_att_req := '01bb146ddd000004088832f44000c80051e000800e003b01c001080103e5e000110a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c0002017057bf0ec'O;
	const octetstring c_gmm_mt_ac_req := '00bb146ddd0050001682ffff0a8204030e9c41c001081200102198c72477ea104895e8b959acc58b108182f4d045'O;
	const octetstring c_gmm_mo_ac_resp := '01bb146ddd000004088832f44000c80051e000800e000e01c00508130122fa361f5fdd623d'O;
	const octetstring c_gmm_mt_att_acc := '00bb146ddd0050001682ffff0a8204030e9841c005080201340432f44000c8001805f4fb146ddd0967d0'O;
	const octetstring c_gmm_mt_det_req := '00bb146ddd0050001682ffff0a8204030e8941c00908050215f0b6'O;
	const octetstring c_gmm_mo_att_cpl := '01fb146ddd000004088832f44000c80051e000800e000801c009080339d7bc'O;

	f_bssgp_dec_and_log(c_bvc_reset_pcu);
	f_bssgp_dec_and_log(c_bvc_reset_q);
	f_bssgp_dec_and_log(c_status_pcu);
	f_bssgp_dec_and_log(c_reset_ack_q);
	f_bssgp_dec_and_log(c_reset_ack_pcu);
	f_bssgp_dec_and_log(c_unblock_pcu);
	f_bssgp_dec_and_log(c_unblock_ack_q);
	f_bssgp_dec_and_log(c_fc_bvc_pcu);
	f_bssgp_dec_and_log(c_fc_bvc_ack_q);
	f_bssgp_dec_and_log(c_gmm_mo_att_req);
	f_bssgp_dec_and_log(c_gmm_mt_ac_req);
	f_bssgp_dec_and_log(c_gmm_mo_ac_resp);
	f_bssgp_dec_and_log(c_gmm_mt_att_acc);
	f_bssgp_dec_and_log(c_gmm_mt_det_req);
	f_bssgp_dec_and_log(c_gmm_mo_att_cpl);

	log(ts_BSSGP_PS_PAGING_IMSI(196, '262420123456789'H));
}

/////////////////
// NS selftest
/////////////////
function f_ns_assert_prepr(in octetstring a, in octetstring b) {
	log("NS Input: ", a);
	log("NS Expected: ", b);

	if (a != b) {
		setverdict(fail, "Values mismatch", a, b);
		mtc.stop;
	} else {
		setverdict(pass);
	}
}

function f_ns_dec_and_log(in octetstring inp) {
	log("NS Input: ", inp);
	var PDU_NS dec := dec_PDU_NS(inp);
	log("NS Decoded: ", dec);
}

testcase TC_selftest_ns() runs on dummy_CT {
	const octetstring c_ns_reset_pcu := '000000c4271e813d'O;

	/* single byte length to two byte length */
	f_ns_assert_prepr('04058101'O, '0405000101'O);
	f_ns_assert_prepr('040589000102030405060708'O, '04050009000102030405060708'O);
	/* two byte length to two byte length */
	f_ns_assert_prepr('0405000101'O, '0405000101'O);
	/* special case: NS-UNITDATA */
	f_ns_assert_prepr('00aabbccddeeffaa29822342'O, '00aabbccddeeffaa2900022342'O);
	/* multiple TLVs */
	f_ns_assert_prepr('234281aa4382bbbb'O, '23420001aa430002bbbb'O);
	/* zero-length */
	f_ns_assert_prepr('230080'O, '23000000'O);

	f_ns_dec_and_log(c_ns_reset_pcu);
}

/////////////////
// LLC selftest
/////////////////
function f_llc_dec_and_log(in octetstring inp) {
	log("LLC Input: ", inp);
	var PDU_LLC dec := dec_PDU_LLC(inp);
	log("LLC Decoded: ", dec);
}

function f_llc_assert(in octetstring a, in octetstring b) {
	log("LLC Input: ", a);
	log("LLC Expected: ", b);

	if (a != b) {
		setverdict(fail, "LLC input ", b, " != expected ", a);
		mtc.stop;
	} else {
		setverdict(pass);
	}
}

testcase TC_selftest_llc() runs on dummy_CT {
	const octetstring c_gmm_att_pcu := '01c001080103e5e000210a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c00020170580460b'O;
	const octetstring c_gmm_att_pcu_nofcs := '01c001080103e5e000210a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c000201705'O;
	const octetstring gmm_auth_req := '081200102198c72477ea104895e8b959acc58b108182'O;

	f_llc_dec_and_log(c_gmm_att_pcu);

	//f_llc_assert(f_LLC_append_fcs(c_gmm_att_pcu_nofcs), c_gmm_att_pcu);

	log(valueof(ts_LLC_UI(gmm_auth_req, c_LLC_SAPI_LLGMM, LLC_CR_DL_CMD, g_mmctx.n_u)));
	log(ts_LLC_UI(gmm_auth_req, c_LLC_SAPI_LLGMM, LLC_CR_DL_CMD, g_mmctx.n_u));
}


///////////////////
// RLCMAC selftest
///////////////////

function f_rlcmac_ul_decenc(in octetstring buf) {
	log("==================================");
	log("In: ", buf);
	var RlcmacUlBlock udb := dec_RlcmacUlBlock(buf);
	log("Dec: ", udb);
	var octetstring enc := enc_RlcmacUlBlock(udb);
	log("Enc: ", enc);
	if (enc != buf) {
		setverdict(fail, "Re-encoded data doesn't equal input data");
		mtc.stop;
	}
}

function f_rlcmac_uld_decenc(in octetstring buf) {
	log("==================================");
	log("In: ", buf);
	var RlcmacUlDataBlock udb := dec_RlcmacUlDataBlock(buf);
	log("Dec: ", udb);
	var octetstring enc := enc_RlcmacUlDataBlock(udb);
	log("Enc: ", enc);
	if (enc != buf) {
		setverdict(fail, "Re-encoded data doesn't equal input data");
		mtc.stop;
	}
}

function f_rlcmac_dld_decenc(in octetstring buf) {
	log("==================================");
	log("In: ", buf);
	var RlcmacDlDataBlock udb := dec_RlcmacDlDataBlock(buf);
	log("Dec: ", udb);
	var octetstring enc := enc_RlcmacDlDataBlock(udb);
	log("Enc: ", enc);
	if (enc != buf) {
		setverdict(fail, "Re-encoded data doesn't equal input data");
		mtc.stop;
	}
}

testcase TC_selftest_rlcmac() runs on dummy_CT {
	const octetstring c_gmm_att_pcu := '402400804000000000000000'O;

	var RlcmacDlCtrlBlock dcb;
	var RlcmacUlCtrlBlock ucb;

	// Some octstrings are concatenated to avoid Atom editor hanging: https://github.com/karolwiniarski/language-ttcn-3/issues/3
	const octetstring c_dl_ul_ack_nack := '402400804000000000000000'O & '77628dbba14b2b2b2b2b2b'O;
	const octetstring c_dl_data := '0f00007341c001081200102198c72477ea104895e8b959acc58b108182f4d0454300'O;
	const octetstring c_dl_data2 := '070002165dc0012b2b2b43c0012b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b00'O;
	const octetstring c_ul_ctrl_ack := '4006ec51b7772b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b'O;
	const octetstring c_ul_dl_ack_nack := '4008004000000000000000'O & '701000edc0000b2b2b2b2b2b'O;
	const octetstring c_dl_ul_assign := '482857628dbbaf0126e68800082b2b2b2b2b2b2b2b2b2b'O;

	log(c_dl_ul_ack_nack);
	dcb := dec_RlcmacDlCtrlBlock(c_dl_ul_ack_nack);
	log(dcb);
	//log(dec_RlcmacDlCtrlMsg(dcb.payload));

	f_rlcmac_dld_decenc(c_dl_data);

	f_rlcmac_dld_decenc(c_dl_data2);

	log(c_ul_ctrl_ack);
	ucb := dec_RlcmacUlCtrlBlock(c_ul_ctrl_ack);
	log(ucb);
	//log(dec_RlcmacUlCtrlMsg(ucb.payload));

	log(c_ul_dl_ack_nack);
	ucb := dec_RlcmacUlCtrlBlock(c_ul_dl_ack_nack);
	log(ucb);
	//log(dec_RlcmacUlCtrlMsg(ucb.payload));

	log(c_dl_ul_assign);
	dcb := dec_RlcmacDlCtrlBlock(c_dl_ul_assign);
	log(dcb);
	//log(dec_RlcmacDlCtrlMsg(dcb.payload));

	const octetstring c_uld_tlli_noext := '080101a61cab5201c001080103e5e000310a0005f4e61cab5232f44000c8001d1b00'O;
	f_rlcmac_uld_decenc(c_uld_tlli_noext);

	const octetstring c_uld_tlli_ext7pad := '0001041da61cab5200201705a96e102b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b00'O;
	log("ULD_decenc");
	f_rlcmac_uld_decenc(c_uld_tlli_ext7pad);
	log("UL_decenc");
	f_rlcmac_ul_decenc(c_uld_tlli_ext7pad);

	f_rlcmac_ul_decenc(c_ul_dl_ack_nack);
}

testcase TC_selftest_rlcmac_egprs() runs on RAW_PCU_Test_CT
{
	var octetstring data;
	var CodingSchemeArray schemes := {
		//MCS_0,
		MCS_1,
		MCS_2,
		MCS_3,
		MCS_4,
		MCS_5,
		MCS_6,
		MCS_7,
		MCS_8,
		MCS_9
		};

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	log("Started Uplink test");
	for (var integer i := 0; i < sizeof(schemes); i := i+1) {
		log("Testing Coding Schema ", schemes[i]);
		var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_EGPRS_DATA(
			schemes[i],
			tfi := 4,
			cv := 1, /* num UL blocks to be sent (to be overridden in loop) */
			bsn1 := 2, /* TODO: what should be here? */
			blocks := { /* To be generated in loop */ });

		ul_data.data_egprs.tlli := '00100101'O;
		ul_data.data_egprs.blocks := { valueof(t_RLCMAC_LLCBLOCK_EGPRS('AABBCCDDEEFF00112233'O)) };

		/* Encode the payload of DATA.ind */
		log("Encoding ", valueof(ul_data));
		data := enc_RlcmacUlBlock(valueof(ul_data));
		data := f_pad_oct(data, f_rlcmac_cs_mcs2block_len(schemes[i]), '00'O);

		/* Send to PCU so that we get gsmtap traces to verify with wireshark */
		f_pcuif_tx_data_ind(data, 0, 0);

		log("Decoding ", schemes[i]);
		ul_data := dec_RlcmacUlBlock(data);
		log("Decoded: ", ul_data);
	}
	log("Done Uplink test");
}

///////////////////
// RR selftest
///////////////////

testcase TC_selftest_rr() runs on dummy_CT {
	//const octetstring c_paging_none := '06210001F02B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O
	const octetstring c_paging_none := '1506210001F0'O;
	const octetstring c_ia_tbf := '2d063f100fe3677bd8440000c800100b2b2b2b2b2b2b2b'O
	log(c_paging_none);
	log(dec_GsmRrMessage(c_paging_none));

	log(c_ia_tbf);
	log(dec_GsmRrMessage(c_ia_tbf));
}

}