blob: b069a116fd033ed615501f8451b7afd599ec9d48 [file] [log] [blame]
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +01001module HNBGW_ConnectionHandler {
2
3/* HNBGW Connection Handler of HNB_Tests in TTCN-3
4 * (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
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 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13import from Misc_Helpers all;
14import from General_Types all;
15import from Osmocom_Types all;
16import from IPL4asp_Types all;
17import from Native_Functions all;
18
19import from SDP_Types all;
20
21import from StatsD_Checker all;
22
23import from TELNETasp_PortType all;
24import from Osmocom_VTY_Functions all;
25
26import from HNBAP_Templates all;
27
28import from Iuh_Emulation all;
29
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +010030import from RTP_Types all;
31import from RTP_Emulation all;
32
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010033import from HNBLLIF_CodecPort all;
34import from HNBLLIF_Types all;
35import from HNBLLIF_Templates all;
36
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010037import from GTP_Emulation all;
38import from GTP_Templates all;
39import from GTP_CodecPort all;
40import from GTPU_Types all;
41
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010042/* this component represents a single Iuh connection at the HNBGW. */
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010043type component HNBGW_ConnHdlr extends StatsD_ConnHdlr, GTP_ConnHdlr {
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010044 port TELNETasp_PT HNBVTY;
45 port HNBAP_PT HNBAP;
46 port RUA_PT RUA;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010047 /* HNBLLIF Interface of HNodeB */
48 port HNBLLIF_CODEC_PT LLSK;
49 var integer g_llsk_conn_id;
50
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +010051 var RTP_Emulation_CT vc_RTPEM;
52 port RTPEM_CTRL_PT RTPEM_CTRL;
53 port RTPEM_DATA_PT RTPEM_DATA;
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010054
55 var GTP_Emulation_CT vc_GTP;
56
57
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010058 var TestHdlrParams g_pars;
59
60 var boolean g_vty_initialized := false;
61}
62
63function f_HNBGW_ConnHdlr_init_vty() runs on HNBGW_ConnHdlr {
64 if (not g_vty_initialized) {
65 map(self:HNBVTY, system:HNBVTY);
66 f_vty_set_prompts(HNBVTY);
67 f_vty_transceive(HNBVTY, "enable");
68 g_vty_initialized := true;
69 }
70}
71
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010072private function f_HNBGW_ConnHdlr_init_iuh(charstring id) runs on HNBGW_ConnHdlr {
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010073 var Iuh_Emulation_CT vc_Iuh;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010074 vc_Iuh := Iuh_Emulation_CT.create(id & "-HNBGW");
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010075 connect(self:HNBAP, vc_Iuh:HNBAP);
76 connect(self:RUA, vc_Iuh:RUA);
77
78 var Iuh_conn_parameters iuh_pars;
79 iuh_pars.remote_ip := g_pars.hnodeb_addr;
80 iuh_pars.remote_sctp_port := -1;
81 iuh_pars.local_ip := g_pars.hnbgw_addr;
82 iuh_pars.local_sctp_port := g_pars.hnbgw_port;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010083 vc_Iuh.start(Iuh_Emulation.main(iuh_pars, id & "-Iuh"));
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010084}
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010085
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010086private function f_HNBGW_ConnHdlr_init_gtp(charstring id) runs on HNBGW_ConnHdlr {
87 id := id & "-GTP";
88
89 var GtpEmulationCfg gtp_cfg := {
90 gtpc_bind_ip := g_pars.hnbgw_addr,
91 gtpc_bind_port := GTP1C_PORT,
92 gtpu_bind_ip := g_pars.hnbgw_addr,
93 gtpu_bind_port := GTP1U_PORT,
94 sgsn_role := false
95 };
96
97 vc_GTP := GTP_Emulation_CT.create(id);
98 connect(self:GTP, vc_GTP:CLIENT);
99 connect(self:GTP_PROC, vc_GTP:CLIENT_PROC);
100 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
101}
102
103/* initialize all parameters */
104function f_HNBGW_ConnHdlr_init(charstring id, TestHdlrParams pars) runs on HNBGW_ConnHdlr {
105 g_pars := valueof(pars);
106 f_HNBGW_ConnHdlr_init_iuh(id);
107 f_HNBGW_ConnHdlr_init_gtp(id);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100108 f_HNBGW_ConnHdlr_init_vty();
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100109
110 /* Connect to HNB on LLSK and do HELLO ping-pong */
111 f_start_hnbllif(LLSK, id & "-LLSK", g_pars.hnbllif_sk_path, g_llsk_conn_id);
112}
113
114
115function f_start_hnbllif(HNBLLIF_CODEC_PT pt, charstring id, charstring hnbllif_sk_path, out integer hnbllif_conn_id) {
116 timer T := 2.0;
117 var HNBLLIF_send_data sd;
118 var HNBLLIF_Message last_hello_cnf;
119 if (hnbllif_sk_path == "") {
120 hnbllif_conn_id := -1;
121 return;
122 }
123 hnbllif_conn_id := f_hnbllif_connect(pt, hnbllif_sk_path);
124
125 T.start;
126 pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_CTL, HNBLLIF_Types.mp_hnbllif_version)));
127 alt {
128 [] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_CTL, HNBLLIF_Types.mp_hnbllif_version);
129 [] T.timeout {
130 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=CTL");
131 }
132 }
133 pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_IUH, 0)));
134 alt {
135 [] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_IUH, 0);
136 [] T.timeout {
137 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=IUH");
138 }
139 }
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100140 pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_AUDIO, 0)));
141 alt {
142 [] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_AUDIO, 0);
143 [] T.timeout {
144 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=AUDIO");
145 }
146 }
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100147 pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_GTP, 0)));
148 alt {
149 [] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_GTP, 0);
150 [] T.timeout {
151 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=GTP");
152 }
153 }
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100154}
155
156type record TestHdlrParams {
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100157 charstring hnbllif_sk_path, /* "" means don't connect */
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100158 charstring hnbgw_addr,
159 charstring hnodeb_addr,
160 integer hnbgw_port,
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100161 integer hnbgw_rtp_port,
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100162 uint16_t rnc_id,
163 charstring hNB_Identity_Info,
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100164 uint16_t mcc,
165 uint16_t mnc,
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100166 uint32_t cell_identity,
167 uint16_t lac,
168 uint8_t rac,
169 uint8_t sac
170};
171
172/* Note: Do not use valueof() to get a value of this template, use
173 * f_gen_test_hdlr_pars() instead in order to get a configuration. */
174template (value) TestHdlrParams t_def_TestHdlrPars := {
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100175 hnbllif_sk_path := HNBLL_SOCK_DEFAULT,
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100176 hnbgw_addr := "127.0.0.1",
177 hnodeb_addr := "127.0.0.1",
178 hnbgw_port := 29169,
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100179 hnbgw_rtp_port := 9000,
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100180 rnc_id := 23,
181 hNB_Identity_Info := "OsmoHNodeB",
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100182 mcc := 1,
183 mnc := 1,
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100184 cell_identity := 1,
185 lac := 2,
186 rac := 3,
187 sac := 4
188}
189
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100190template (value) GtpPeer ts_GtpPeerU(charstring ip) := {
191 connId := 1,
192 remName := ip,
193 remPort := GTP1U_PORT
194}
195
196function f_gtpu_send(uint32_t tei, octetstring payload) runs on HNBGW_ConnHdlr {
197 var GtpPeer peer := valueof(ts_GtpPeerU(g_pars.hnodeb_addr));
198 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, int2oct(tei, 4), payload));
199}
200
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100201/* HNBLLIF socket may at any time receive a new INFO.ind */
202altstep as_hnbllif_hello_cnf(HNBLLIF_CODEC_PT pt, integer hnbllif_conn_id,
203 out HNBLLIF_Message last_hello_cnf,
204 template (present) HNBLLIF_Sapi exp_sapi := ?,
205 template (present) uint16_t exp_version := ?) {
206 var HNBLLIF_send_data sd;
207 [] pt.receive(t_SD_HNBLLIF(hnbllif_conn_id, tr_HNBLLIF_CTL_HELLO_CNF(exp_sapi, exp_version))) -> value sd {
208 last_hello_cnf := sd.data;
209 }
210 [] pt.receive(t_SD_HNBLLIF(hnbllif_conn_id, tr_HNBLLIF_CTL_HELLO_CNF(?))) -> value sd {
211 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Invalid API_VERSION received");
212 }
213}
214
215function f_llsk_rx(template (present) HNBLLIF_Message exp_tmpl) runs on HNBGW_ConnHdlr
216return template (present) HNBLLIF_send_data {
217 return t_SD_HNBLLIF(g_llsk_conn_id, exp_tmpl);
218}
219
220function f_llsk_tx(template (value) HNBLLIF_Message tx_msg) runs on HNBGW_ConnHdlr
221return template (value) HNBLLIF_send_data {
222 return ts_SD_HNBLLIF(g_llsk_conn_id, tx_msg);
223}
224
225function f_enc_mcc_mnc(uint16_t mcc_uint, uint16_t mnc_uint) return OCT3 {
226 var hexstring mnc;
227 var hexstring mcc := int2hex(mcc_uint, 3);
228
229 if (mnc_uint < 100) {
230 mnc := int2hex(mnc_uint, 2);
231 return hex2oct(mcc[1] & mcc[0] & 'F'H & mcc[2] & mnc[1] & mnc[0]);
232 } else {
233 mnc := int2hex(mnc_uint, 3);
234 return hex2oct(mcc[1] & mcc[0] & mnc[2] & mcc[2] & mnc[1] & mnc[0]);
235 }
236}
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100237
238function f_handle_hnbap_hnb_register_req()
239runs on HNBGW_ConnHdlr {
240 HNBAP.receive(tr_HNBAP_HNBRegisterRequest(char2oct(g_pars.hNB_Identity_Info),
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100241 f_enc_mcc_mnc(g_pars.mcc, g_pars.mnc),
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100242 int2bit(g_pars.cell_identity, 28),
243 int2oct(g_pars.lac, 2),
244 int2oct(g_pars.rac, 1),
245 int2oct(g_pars.sac, 2)
246 ));
247 HNBAP.send(ts_HNBAP_HNBRegisterAccept(g_pars.rnc_id));
248}
249
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100250/* Initialize and start the RTP emulation component for a ConnHdlr */
251function f_HNBGW_rtpem_activate(inout octetstring payload,
252 HostName remote_host,
253 PortNumber remote_port,
254 RtpemConfig cfg := c_RtpemDefaultCfg,
255 RtpemMode mode := RTPEM_MODE_BIDIR)
256runs on HNBGW_ConnHdlr {
257 /* Step 0: initialize, connect and start the emulation component */
258 vc_RTPEM := RTP_Emulation_CT.create(testcasename() & "-RTPEM");
259 map(vc_RTPEM:RTP, system:RTP);
260 map(vc_RTPEM:RTCP, system:RTCP);
261 connect(vc_RTPEM:CTRL, self:RTPEM_CTRL);
262 connect(vc_RTPEM:DATA, self:RTPEM_DATA);
263 vc_RTPEM.start(RTP_Emulation.f_main());
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100264
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100265 /* Configure the RTP parameters (TCH/FS). TODO: IuUP */
266 var integer payload_len := 33;
267 var octetstring hdr := 'D0'O;
268
269 /* Pad the payload to conform the expected length */
270 payload := f_pad_oct(hdr & payload, payload_len, '00'O);
271 cfg.tx_fixed_payload := payload;
272 f_rtpem_configure(RTPEM_CTRL, cfg);
273
274 /* Bind the RTP emulation to the configured address */
275 f_rtpem_bind(RTPEM_CTRL, g_pars.hnbgw_addr, g_pars.hnbgw_rtp_port);
276
277 /* Connect to the IUT's address/port parsed from CRCX ACK */
278 f_rtpem_connect(RTPEM_CTRL, remote_host, remote_port);
279
280 /* Set the given RTP emulation mode */
281 f_rtpem_mode(RTPEM_CTRL, mode);
282}
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100283
284}