hnb: Introduce HNB_Tests testsuite
A new Iuh CodecPort + Emulation is introduced to (de)mux RANAP and RUA in the same SCTP socket. The Iuh_CodecPort.ttcn file has currently a hack to be able to test HNBAP, since titan seem to be reporting sinfo_ppid=0 when in fact it received sinfo_ppid=20 (HNBAP). A couple tests are added to validate HNBAP HNBRegister Request + Accept or Reject. In current osmo-hnodeb state, both tests pass if run separately, but fail if run sequentially since osmo-hnodeb still doesn't re-connect properly after first test finishes and connection is dropped. Related: SYS#5516 Change-Id: I7227917148e98a2c777f4b05d8d2eca6e9c121b7
This commit is contained in:
parent
afe2ea5c4f
commit
b54acca15f
1
Makefile
1
Makefile
|
@ -24,6 +24,7 @@ SUBDIRS= \
|
||||||
gbproxy \
|
gbproxy \
|
||||||
ggsn_tests \
|
ggsn_tests \
|
||||||
hlr \
|
hlr \
|
||||||
|
hnodeb \
|
||||||
mgw \
|
mgw \
|
||||||
mme \
|
mme \
|
||||||
msc \
|
msc \
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
module HNBGW_ConnectionHandler {
|
||||||
|
|
||||||
|
/* HNBGW Connection Handler of HNB_Tests in TTCN-3
|
||||||
|
* (C) 2021 by sysmocom - s.m.f.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 Misc_Helpers all;
|
||||||
|
import from General_Types all;
|
||||||
|
import from Osmocom_Types all;
|
||||||
|
import from IPL4asp_Types all;
|
||||||
|
import from Native_Functions all;
|
||||||
|
|
||||||
|
import from SDP_Types all;
|
||||||
|
|
||||||
|
import from StatsD_Checker all;
|
||||||
|
|
||||||
|
import from TELNETasp_PortType all;
|
||||||
|
import from Osmocom_VTY_Functions all;
|
||||||
|
|
||||||
|
import from HNBAP_Templates all;
|
||||||
|
|
||||||
|
import from Iuh_Emulation all;
|
||||||
|
|
||||||
|
/* this component represents a single Iuh connection at the HNBGW. */
|
||||||
|
type component HNBGW_ConnHdlr extends StatsD_ConnHdlr {
|
||||||
|
port TELNETasp_PT HNBVTY;
|
||||||
|
port HNBAP_PT HNBAP;
|
||||||
|
port RUA_PT RUA;
|
||||||
|
var TestHdlrParams g_pars;
|
||||||
|
|
||||||
|
var boolean g_vty_initialized := false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_HNBGW_ConnHdlr_init_vty() runs on HNBGW_ConnHdlr {
|
||||||
|
if (not g_vty_initialized) {
|
||||||
|
map(self:HNBVTY, system:HNBVTY);
|
||||||
|
f_vty_set_prompts(HNBVTY);
|
||||||
|
f_vty_transceive(HNBVTY, "enable");
|
||||||
|
g_vty_initialized := true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize all parameters */
|
||||||
|
function f_HNBGW_ConnHdlr_init(TestHdlrParams pars) runs on HNBGW_ConnHdlr {
|
||||||
|
var integer i := 0;
|
||||||
|
var Iuh_Emulation_CT vc_Iuh;
|
||||||
|
|
||||||
|
g_pars := valueof(pars);
|
||||||
|
vc_Iuh := Iuh_Emulation_CT.create("HNBGW" & int2str(i));
|
||||||
|
connect(self:HNBAP, vc_Iuh:HNBAP);
|
||||||
|
connect(self:RUA, vc_Iuh:RUA);
|
||||||
|
|
||||||
|
var Iuh_conn_parameters iuh_pars;
|
||||||
|
iuh_pars.remote_ip := g_pars.hnodeb_addr;
|
||||||
|
iuh_pars.remote_sctp_port := -1;
|
||||||
|
iuh_pars.local_ip := g_pars.hnbgw_addr;
|
||||||
|
iuh_pars.local_sctp_port := g_pars.hnbgw_port;
|
||||||
|
vc_Iuh.start(Iuh_Emulation.main(iuh_pars, "Iuh" & int2str(i)));
|
||||||
|
|
||||||
|
f_HNBGW_ConnHdlr_init_vty();
|
||||||
|
}
|
||||||
|
|
||||||
|
type record TestHdlrParams {
|
||||||
|
charstring hnbgw_addr,
|
||||||
|
charstring hnodeb_addr,
|
||||||
|
integer hnbgw_port,
|
||||||
|
uint16_t rnc_id,
|
||||||
|
charstring hNB_Identity_Info,
|
||||||
|
OCT3 plmnid,
|
||||||
|
uint32_t cell_identity,
|
||||||
|
uint16_t lac,
|
||||||
|
uint8_t rac,
|
||||||
|
uint8_t sac
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Note: Do not use valueof() to get a value of this template, use
|
||||||
|
* f_gen_test_hdlr_pars() instead in order to get a configuration. */
|
||||||
|
template (value) TestHdlrParams t_def_TestHdlrPars := {
|
||||||
|
hnbgw_addr := "127.0.0.1",
|
||||||
|
hnodeb_addr := "127.0.0.1",
|
||||||
|
hnbgw_port := 29169,
|
||||||
|
rnc_id := 23,
|
||||||
|
hNB_Identity_Info := "OsmoHNodeB",
|
||||||
|
plmnid := '00F110'O,
|
||||||
|
cell_identity := 1,
|
||||||
|
lac := 2,
|
||||||
|
rac := 3,
|
||||||
|
sac := 4
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function f_handle_hnbap_hnb_register_req()
|
||||||
|
runs on HNBGW_ConnHdlr {
|
||||||
|
HNBAP.receive(tr_HNBAP_HNBRegisterRequest(char2oct(g_pars.hNB_Identity_Info),
|
||||||
|
g_pars.plmnid,
|
||||||
|
int2bit(g_pars.cell_identity, 28),
|
||||||
|
int2oct(g_pars.lac, 2),
|
||||||
|
int2oct(g_pars.rac, 1),
|
||||||
|
int2oct(g_pars.sac, 2)
|
||||||
|
));
|
||||||
|
HNBAP.send(ts_HNBAP_HNBRegisterAccept(g_pars.rnc_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
[ORDERED_INCLUDE]
|
||||||
|
# Common configuration, shared between test suites
|
||||||
|
"../Common.cfg"
|
||||||
|
# testsuite specific configuration, not expected to change
|
||||||
|
"./HNB_Tests.default"
|
||||||
|
|
||||||
|
# Local configuration below
|
||||||
|
|
||||||
|
[LOGGING]
|
||||||
|
|
||||||
|
[TESTPORT_PARAMETERS]
|
||||||
|
|
||||||
|
[MODULE_PARAMETERS]
|
||||||
|
|
||||||
|
[MAIN_CONTROLLER]
|
||||||
|
|
||||||
|
[EXECUTE]
|
||||||
|
HNB_Tests.control
|
|
@ -0,0 +1,27 @@
|
||||||
|
[LOGGING]
|
||||||
|
mtc.FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC;
|
||||||
|
|
||||||
|
[TESTPORT_PARAMETERS]
|
||||||
|
*.HNBVTY.CTRL_MODE := "client"
|
||||||
|
*.HNBVTY.CTRL_HOSTNAME := "127.0.0.1"
|
||||||
|
*.HNBVTY.CTRL_PORTNUM := "4273"
|
||||||
|
*.HNBVTY.CTRL_LOGIN_SKIPPED := "yes"
|
||||||
|
*.HNBVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes"
|
||||||
|
*.HNBVTY.CTRL_READMODE := "buffered"
|
||||||
|
*.HNBVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes"
|
||||||
|
*.HNBVTY.CTRL_DETECT_CONNECTION_ESTABLISHMENT_RESULT := "yes"
|
||||||
|
*.HNBVTY.PROMPT1 := "OsmoHNodeB> "
|
||||||
|
*.STATSVTY.CTRL_MODE := "client"
|
||||||
|
*.STATSVTY.CTRL_HOSTNAME := "127.0.0.1"
|
||||||
|
*.STATSVTY.CTRL_PORTNUM := "4274"
|
||||||
|
*.STATSVTY.CTRL_LOGIN_SKIPPED := "yes"
|
||||||
|
*.STATSVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes"
|
||||||
|
*.STATSVTY.CTRL_READMODE := "buffered"
|
||||||
|
*.STATSVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes"
|
||||||
|
*.STATSVTY.CTRL_DETECT_CONNECTION_ESTABLISHMENT_RESULT := "yes"
|
||||||
|
*.STATSVTY.PROMPT1 := "OsmoHNodeB> "
|
||||||
|
|
||||||
|
[MODULE_PARAMETERS]
|
||||||
|
Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoHNodeB";
|
||||||
|
|
||||||
|
[EXECUTE]
|
|
@ -0,0 +1,214 @@
|
||||||
|
module HNB_Tests {
|
||||||
|
|
||||||
|
/* Integration Tests for OsmoHNodeB
|
||||||
|
* (C) 2021 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
|
||||||
|
*
|
||||||
|
* This test suite tests OsmoHNodB while emulating both multiple UE as
|
||||||
|
* well as the HNBGW. See README for more details.
|
||||||
|
*
|
||||||
|
* There are test cases that run in so-called 'handler mode' and test cases
|
||||||
|
* that run directly on top of the BSSAP and RSL CodecPorts. The "handler mode"
|
||||||
|
* tests abstract the multiplexing/demultiplexing of multiple SCCP connections
|
||||||
|
* and/or RSL channels and are hence suitable for higher-level test cases, while
|
||||||
|
* the "raw" tests directly on top of the CodecPorts are more suitable for lower-
|
||||||
|
* level testing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import from Misc_Helpers all;
|
||||||
|
import from General_Types all;
|
||||||
|
import from Osmocom_Types all;
|
||||||
|
import from IPL4asp_Types all;
|
||||||
|
|
||||||
|
import from Osmocom_CTRL_Functions all;
|
||||||
|
import from Osmocom_CTRL_Types all;
|
||||||
|
import from Osmocom_CTRL_Adapter all;
|
||||||
|
|
||||||
|
import from StatsD_Types all;
|
||||||
|
import from StatsD_CodecPort all;
|
||||||
|
import from StatsD_CodecPort_CtrlFunct all;
|
||||||
|
import from StatsD_Checker all;
|
||||||
|
|
||||||
|
import from Osmocom_VTY_Functions all;
|
||||||
|
import from TELNETasp_PortType all;
|
||||||
|
|
||||||
|
import from HNBAP_Templates all;
|
||||||
|
|
||||||
|
import from HNBGW_ConnectionHandler all;
|
||||||
|
import from Iuh_Emulation all;
|
||||||
|
|
||||||
|
modulepar {
|
||||||
|
/* IP address at which the HNodeB can be reached */
|
||||||
|
charstring mp_hnodeb_ip := "127.0.0.1";
|
||||||
|
|
||||||
|
/* IP address at which the test binds */
|
||||||
|
charstring mp_hnbgw_iuh_ip := "127.0.0.1";
|
||||||
|
integer mp_hnbgw_iuh_port := 29169;
|
||||||
|
}
|
||||||
|
|
||||||
|
type component test_CT extends CTRL_Adapter_CT {
|
||||||
|
port TELNETasp_PT HNBVTY;
|
||||||
|
|
||||||
|
/* global test case guard timer (actual timeout value is set in f_init()) */
|
||||||
|
timer T_guard := 30.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* global altstep for global guard timer; */
|
||||||
|
altstep as_Tguard() runs on test_CT {
|
||||||
|
[] T_guard.timeout {
|
||||||
|
setverdict(fail, "Timeout of T_guard");
|
||||||
|
mtc.stop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
friend function f_logp(TELNETasp_PT pt, charstring log_msg)
|
||||||
|
{
|
||||||
|
// log on TTCN3 log output
|
||||||
|
log(log_msg);
|
||||||
|
// log in stderr log
|
||||||
|
f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_init_vty(charstring id := "foo") runs on test_CT {
|
||||||
|
if (HNBVTY.checkstate("Mapped")) {
|
||||||
|
/* skip initialization if already executed once */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map(self:HNBVTY, system:HNBVTY);
|
||||||
|
f_vty_set_prompts(HNBVTY);
|
||||||
|
f_vty_transceive(HNBVTY, "enable");
|
||||||
|
}
|
||||||
|
/* global initialization function */
|
||||||
|
function f_init(float guard_timeout := 30.0) runs on test_CT {
|
||||||
|
var integer bssap_idx;
|
||||||
|
|
||||||
|
T_guard.start(guard_timeout);
|
||||||
|
activate(as_Tguard());
|
||||||
|
|
||||||
|
f_init_vty("VirtHNBGW");
|
||||||
|
|
||||||
|
/* TODO: Wait for Iuh connection to be established */
|
||||||
|
}
|
||||||
|
|
||||||
|
friend function f_shutdown_helper() runs on test_CT {
|
||||||
|
all component.stop;
|
||||||
|
setverdict(pass);
|
||||||
|
mtc.stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend function f_gen_test_hdlr_pars() return TestHdlrParams {
|
||||||
|
|
||||||
|
var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
|
||||||
|
pars.hnodeb_addr := mp_hnodeb_ip;
|
||||||
|
pars.hnbgw_addr := mp_hnbgw_iuh_ip;
|
||||||
|
pars.hnbgw_port := mp_hnbgw_iuh_port;
|
||||||
|
return pars;
|
||||||
|
}
|
||||||
|
|
||||||
|
type function void_fn(charstring id) runs on HNBGW_ConnHdlr;
|
||||||
|
|
||||||
|
/* helper function to create and connect a HNBGW_ConnHdlr component */
|
||||||
|
private function f_connect_handler(inout HNBGW_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
|
||||||
|
/*connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
|
||||||
|
connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
|
||||||
|
connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
|
||||||
|
connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
|
||||||
|
if (isvalue(bts[1])) {
|
||||||
|
connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
|
||||||
|
connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
|
||||||
|
}
|
||||||
|
if (isvalue(bts[2])) {
|
||||||
|
connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
|
||||||
|
connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
|
||||||
|
}
|
||||||
|
connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
|
||||||
|
if (mp_enable_lcs_tests) {
|
||||||
|
connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
|
||||||
|
connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
|
||||||
|
}
|
||||||
|
connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
|
||||||
|
connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
|
||||||
|
connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_start_handler_create(TestHdlrParams pars)
|
||||||
|
runs on test_CT return HNBGW_ConnHdlr {
|
||||||
|
var charstring id := testcasename();
|
||||||
|
var HNBGW_ConnHdlr vc_conn;
|
||||||
|
vc_conn := HNBGW_ConnHdlr.create(id);
|
||||||
|
f_connect_handler(vc_conn);
|
||||||
|
return vc_conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_start_handler_run(HNBGW_ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars)
|
||||||
|
runs on test_CT return HNBGW_ConnHdlr {
|
||||||
|
var charstring id := testcasename();
|
||||||
|
/* Emit a marker to appear in the SUT's own logging output */
|
||||||
|
f_logp(HNBVTY, id & "() start");
|
||||||
|
vc_conn.start(f_handler_init(fn, id, pars));
|
||||||
|
return vc_conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars_tmpl := omit)
|
||||||
|
runs on test_CT return HNBGW_ConnHdlr {
|
||||||
|
var TestHdlrParams pars;
|
||||||
|
if (isvalue(pars)) {
|
||||||
|
pars := valueof(pars_tmpl);
|
||||||
|
} else {
|
||||||
|
pars := valueof(f_gen_test_hdlr_pars());
|
||||||
|
}
|
||||||
|
return f_start_handler_run(f_start_handler_create(pars), fn, pars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first function inside ConnHdlr component; sets g_pars + starts function */
|
||||||
|
private function f_handler_init(void_fn fn, charstring id, TestHdlrParams pars)
|
||||||
|
runs on HNBGW_ConnHdlr {
|
||||||
|
f_HNBGW_ConnHdlr_init(pars);
|
||||||
|
HNBAP.receive(IUHEM_Event:{up_down:=IUHEM_EVENT_UP}); /* Wait for HNB to connect to us */
|
||||||
|
fn.apply(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function f_tc_hnb_register_request(charstring id) runs on HNBGW_ConnHdlr {
|
||||||
|
f_handle_hnbap_hnb_register_req();
|
||||||
|
f_sleep(1.0);
|
||||||
|
}
|
||||||
|
testcase TC_hnb_register_request_accept() runs on test_CT {
|
||||||
|
var HNBGW_ConnHdlr vc_conn;
|
||||||
|
|
||||||
|
f_init();
|
||||||
|
vc_conn := f_start_handler(refers(f_tc_hnb_register_request));
|
||||||
|
vc_conn.done;
|
||||||
|
f_shutdown_helper();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function f_tc_hnb_register_reject(charstring id) runs on HNBGW_ConnHdlr {
|
||||||
|
HNBAP.receive(tr_HNBAP_HNBRegisterRequest(char2oct(g_pars.hNB_Identity_Info),
|
||||||
|
g_pars.plmnid,
|
||||||
|
int2bit(g_pars.cell_identity, 28),
|
||||||
|
int2oct(g_pars.lac, 2),
|
||||||
|
int2oct(g_pars.rac, 1),
|
||||||
|
int2oct(g_pars.sac, 2)
|
||||||
|
));
|
||||||
|
HNBAP.send(ts_HNBAP_HNBRegisterReject(ts_HnbapCause(overload)));
|
||||||
|
f_sleep(1.0);
|
||||||
|
}
|
||||||
|
testcase TC_hnb_register_request_reject() runs on test_CT {
|
||||||
|
var HNBGW_ConnHdlr vc_conn;
|
||||||
|
|
||||||
|
f_init();
|
||||||
|
vc_conn := f_start_handler(refers(f_tc_hnb_register_reject));
|
||||||
|
vc_conn.done;
|
||||||
|
f_shutdown_helper();
|
||||||
|
}
|
||||||
|
|
||||||
|
control {
|
||||||
|
execute( TC_hnb_register_request_accept() );
|
||||||
|
execute( TC_hnb_register_request_reject() );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
# HNB_Tests.ttcn
|
||||||
|
|
||||||
|
* external interfaces
|
||||||
|
* Iuh side (emulates HNBGW-side)
|
||||||
|
* SCTP/HNBAP
|
||||||
|
* SCTP/RUA/RANAP
|
||||||
|
* RTP side: emulates MGW
|
||||||
|
* GTP-U side: emulates GGSN
|
||||||
|
* UE side
|
||||||
|
* VTY
|
||||||
|
* CTRL
|
||||||
|
* StatsD
|
||||||
|
|
||||||
|
{% dot hnb_tests.svg
|
||||||
|
digraph G {
|
||||||
|
graph [label="HNB_Tests", labelloc=t, fontsize=30];
|
||||||
|
rankdir=LR;
|
||||||
|
{ rank=same; ATS; HNB; };
|
||||||
|
HNB [label="IUT\nosmo-bsc",shape="box"];
|
||||||
|
ATS [label="ATS\nHNB_Tests.ttcn"];
|
||||||
|
|
||||||
|
HNB <- ATS [label="Uu (or some intermediate lower layer)"];
|
||||||
|
HNB -> ATS [label="Iuh"];
|
||||||
|
HNB -> ATS [label="RTP"];
|
||||||
|
HNB -> ATS [label="GTP-U"];
|
||||||
|
HNB <- ATS [label="CTRL"];
|
||||||
|
HNB <- ATS [label="VTY"];
|
||||||
|
HNB -> ATS [label="StatsD"];
|
||||||
|
}
|
||||||
|
%}
|
|
@ -0,0 +1,32 @@
|
||||||
|
Integration Tests for OsmoHnodeB
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
This test suite tests OsmoHNodeB while emulating both multiple UE as
|
||||||
|
well as the HNBGW.
|
||||||
|
|
||||||
|
The included jenkins.sh script, together with the Dockerfiles from
|
||||||
|
http://git.osmocom.org/docker-playground/ can be used to run both the
|
||||||
|
osmo-hnodeb-under-test as well as the extenal entities and the tester.
|
||||||
|
|
||||||
|
|
||||||
|
Further Test Ideas
|
||||||
|
------------------
|
||||||
|
|
||||||
|
This is a random list of things about things possible to test.
|
||||||
|
Asterisks '*' are TODO, while 'x' means already implemented.
|
||||||
|
|
||||||
|
= exhaustion of resources
|
||||||
|
|
||||||
|
= paging
|
||||||
|
|
||||||
|
= assignment
|
||||||
|
|
||||||
|
= hand-over
|
||||||
|
|
||||||
|
= erroneous channel release
|
||||||
|
|
||||||
|
= misc
|
||||||
|
|
||||||
|
= counters
|
||||||
|
|
||||||
|
= VTY based/corresponding tests
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<testsuite name='HNB_Tests' tests='0' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'>
|
||||||
|
|
||||||
|
</testsuite>
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
BASEDIR=../deps
|
||||||
|
|
||||||
|
. ../gen_links.sh.inc
|
||||||
|
|
||||||
|
#DIR=$BASEDIR/titan.TestPorts.UNIX_DOMAIN_SOCKETasp/src
|
||||||
|
#FILES="UD_PT.cc UD_PT.hh UD_PortType.ttcn UD_Types.ttcn"
|
||||||
|
#gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
|
||||||
|
FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h"
|
||||||
|
FILES+=" TCCEncoding_Functions.ttcn TCCEncoding.cc " # GSM 7-bit coding
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
|
||||||
|
FILES="Socket_API_Definitions.ttcn"
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
# Required by MGCP and IPA
|
||||||
|
DIR=$BASEDIR/titan.TestPorts.IPL4asp/src
|
||||||
|
FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh"
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
# required by M3UA_Emulation
|
||||||
|
DIR=$BASEDIR/titan.TestPorts.SCTPasp/src
|
||||||
|
FILES="SCTPasp_PT.cc SCTPasp_PT.hh SCTPasp_PortType.ttcn SCTPasp_Types.ttcn"
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=$BASEDIR/titan.ProtocolModules.SDP/src
|
||||||
|
FILES="SDP_EncDec.cc SDP_Types.ttcn SDP_parse_.tab.c SDP_parse_.tab.h SDP_parse_parser.h SDP_parser.l
|
||||||
|
SDP_parser.y lex.SDP_parse_.c"
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=$BASEDIR/titan.ProtocolModules.RTP/src
|
||||||
|
FILES="RTP_EncDec.cc RTP_Types.ttcn"
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=$BASEDIR/titan.TestPorts.TELNETasp/src
|
||||||
|
FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn"
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=../library/hnbap
|
||||||
|
FILES="HNBAP_CommonDataTypes.asn HNBAP_Constants.asn HNBAP_Containers.asn HNBAP_IEs.asn HNBAP_PDU_Contents.asn HNBAP_PDU_Descriptions.asn "
|
||||||
|
FILES+="HNBAP_EncDec.cc HNBAP_Types.ttcn HNBAP_Templates.ttcn "
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=../library/rua
|
||||||
|
FILES="RUA_CommonDataTypes.asn RUA_Constants.asn RUA_Containers.asn RUA_IEs.asn RUA_PDU_Contents.asn RUA_PDU_Descriptions.asn "
|
||||||
|
FILES+="RUA_EncDec.cc RUA_Types.ttcn RUA_Templates.ttcn "
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
DIR=../library
|
||||||
|
FILES="Iuh_Types.ttcn Iuh_CodecPort.ttcn Iuh_CodecPort_CtrlFunctDef.cc Iuh_CodecPort_CtrlFunct.ttcn Iuh_Emulation.ttcn DNS_Helpers.ttcn "
|
||||||
|
FILES+="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn "
|
||||||
|
FILES+="StatsD_Types.ttcn StatsD_CodecPort.ttcn StatsD_CodecPort_CtrlFunct.ttcn StatsD_CodecPort_CtrlFunctdef.cc StatsD_Checker.ttcn "
|
||||||
|
|
||||||
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
|
ignore_pp_results
|
|
@ -0,0 +1,19 @@
|
||||||
|
log stderr
|
||||||
|
logging filter all 1
|
||||||
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
|
logging print extended-timestamp 1
|
||||||
|
logging print file basename
|
||||||
|
logging level set-all debug
|
||||||
|
line vty
|
||||||
|
no login
|
||||||
|
!
|
||||||
|
hnodeb
|
||||||
|
cell_identity 1
|
||||||
|
location_area_code 2
|
||||||
|
routing_area_code 3
|
||||||
|
service_area_code 4
|
||||||
|
iuh
|
||||||
|
local-ip 127.0.0.1
|
||||||
|
remote-ip 127.0.0.1
|
|
@ -0,0 +1,35 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
NAME=HNB_Tests
|
||||||
|
|
||||||
|
FILES="
|
||||||
|
*.asn
|
||||||
|
*.c
|
||||||
|
*.ttcn
|
||||||
|
*.ttcnpp
|
||||||
|
IPA_CodecPort_CtrlFunctDef.cc
|
||||||
|
IPL4asp_PT.cc
|
||||||
|
IPL4asp_discovery.cc
|
||||||
|
IuUP_EncDec.cc
|
||||||
|
Iuh_CodecPort_CtrlFunctDef.cc
|
||||||
|
Native_FunctionDefs.cc
|
||||||
|
RTP_CodecPort_CtrlFunctDef.cc
|
||||||
|
RTP_EncDec.cc
|
||||||
|
SCTPasp_PT.cc
|
||||||
|
SDP_EncDec.cc
|
||||||
|
StatsD_CodecPort_CtrlFunctdef.cc
|
||||||
|
TCCConversion.cc
|
||||||
|
TCCEncoding.cc
|
||||||
|
TCCInterface.cc
|
||||||
|
TELNETasp_PT.cc
|
||||||
|
HNBAP_EncDec.cc
|
||||||
|
RUA_EncDec.cc
|
||||||
|
"
|
||||||
|
|
||||||
|
export CPPFLAGS_TTCN3="
|
||||||
|
-DIPA_EMULATION_CTRL
|
||||||
|
"
|
||||||
|
|
||||||
|
../regen-makefile.sh -e $NAME $FILES
|
||||||
|
|
||||||
|
sed -i -e 's/^LINUX_LIBS = -lxml2 -lsctp/LINUX_LIBS = -lxml2 -lsctp -lfftranscode/' Makefile
|
|
@ -0,0 +1,141 @@
|
||||||
|
module Iuh_CodecPort {
|
||||||
|
|
||||||
|
/* Simple Iuh Codec Port, translating between raw SCTP primitives with
|
||||||
|
* octetstring payload towards the IPL4asp provider, and Iuh primitives
|
||||||
|
* which carry the decoded Iuh data types as payload.
|
||||||
|
*
|
||||||
|
* (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@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 IPL4asp_PortType all;
|
||||||
|
import from IPL4asp_Types all;
|
||||||
|
import from HNBAP_PDU_Descriptions all;
|
||||||
|
import from HNBAP_Types all;
|
||||||
|
import from RUA_PDU_Descriptions all;
|
||||||
|
import from RUA_Types all;
|
||||||
|
import from Iuh_Types all;
|
||||||
|
|
||||||
|
type record Iuh_RecvFrom {
|
||||||
|
ConnectionId connId,
|
||||||
|
HostName remName,
|
||||||
|
PortNumber remPort,
|
||||||
|
HostName locName,
|
||||||
|
PortNumber locPort,
|
||||||
|
Iuh_PDU msg
|
||||||
|
};
|
||||||
|
|
||||||
|
template Iuh_RecvFrom t_Iuh_RecvFrom(template Iuh_PDU msg) := {
|
||||||
|
connId := ?,
|
||||||
|
remName := ?,
|
||||||
|
remPort := ?,
|
||||||
|
locName := ?,
|
||||||
|
locPort := ?,
|
||||||
|
msg := msg
|
||||||
|
}
|
||||||
|
|
||||||
|
template Iuh_RecvFrom t_Iuh_RecvFrom_HNBAP(template HNBAP_PDU hnbap_msg := ?) := {
|
||||||
|
connId := ?,
|
||||||
|
remName := ?,
|
||||||
|
remPort := ?,
|
||||||
|
locName := ?,
|
||||||
|
locPort := ?,
|
||||||
|
msg := {
|
||||||
|
hnbap := hnbap_msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template Iuh_RecvFrom t_Iuh_RecvFrom_RUA(template RUA_PDU rua_msg := ?) := {
|
||||||
|
connId := ?,
|
||||||
|
remName := ?,
|
||||||
|
remPort := ?,
|
||||||
|
locName := ?,
|
||||||
|
locPort := ?,
|
||||||
|
msg := {
|
||||||
|
rua := rua_msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type record Iuh_Send {
|
||||||
|
ConnectionId connId,
|
||||||
|
Iuh_PDU msg
|
||||||
|
};
|
||||||
|
|
||||||
|
template Iuh_Send t_Iuh_Send_HNBAP(template ConnectionId connId, template HNBAP_PDU hnbap_msg) := {
|
||||||
|
connId := connId,
|
||||||
|
msg := {
|
||||||
|
hnbap := hnbap_msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template Iuh_Send t_Iuh_Send_RUA(template ConnectionId connId, template RUA_PDU rua_msg) := {
|
||||||
|
connId := connId,
|
||||||
|
msg := {
|
||||||
|
rua := rua_msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function IPL4_to_Iuh_RecvFrom(in ASP_RecvFrom pin, out Iuh_RecvFrom pout) {
|
||||||
|
pout.connId := pin.connId;
|
||||||
|
pout.remName := pin.remName;
|
||||||
|
pout.remPort := pin.remPort;
|
||||||
|
pout.locName := pin.locName;
|
||||||
|
pout.locPort := pin.locPort;
|
||||||
|
select (pin.proto.sctp.sinfo_ppid) {
|
||||||
|
case (19) {
|
||||||
|
pout.msg.rua := dec_RUA_PDU(pin.msg);
|
||||||
|
}
|
||||||
|
case (20) {
|
||||||
|
pout.msg.hnbap := dec_HNBAP_PDU(pin.msg);
|
||||||
|
}
|
||||||
|
case (0) {
|
||||||
|
/* FIXME: lower layers report sinfo_ppid=0: */
|
||||||
|
pout.msg.hnbap := dec_HNBAP_PDU(pin.msg);
|
||||||
|
}
|
||||||
|
case else {
|
||||||
|
pout.msg.payload := pin.msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} with { extension "prototype(fast)" };
|
||||||
|
|
||||||
|
private function Iuh_to_IPL4_Send(in Iuh_Send pin, out ASP_Send pout) {
|
||||||
|
var integer sctp_ppid;
|
||||||
|
if (ischosen(pin.msg.rua)) {
|
||||||
|
sctp_ppid := 19;
|
||||||
|
pout.msg := enc_RUA_PDU(pin.msg.rua);
|
||||||
|
} else if (ischosen(pin.msg.hnbap)) {
|
||||||
|
sctp_ppid := 20;
|
||||||
|
pout.msg := enc_HNBAP_PDU(pin.msg.hnbap);
|
||||||
|
} else { /*TODO: abort?*/
|
||||||
|
sctp_ppid := 0;
|
||||||
|
pout.msg := pin.msg.payload;
|
||||||
|
}
|
||||||
|
pout.connId := pin.connId;
|
||||||
|
pout.proto := {
|
||||||
|
sctp := {
|
||||||
|
sinfo_stream := omit,
|
||||||
|
sinfo_ppid := sctp_ppid,
|
||||||
|
remSocks := omit,
|
||||||
|
assocId := omit
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} with { extension "prototype(fast)" };
|
||||||
|
|
||||||
|
type port Iuh_CODEC_PT message {
|
||||||
|
out Iuh_Send;
|
||||||
|
in Iuh_RecvFrom,
|
||||||
|
ASP_ConnId_ReadyToRelease,
|
||||||
|
ASP_Event;
|
||||||
|
} with { extension "user IPL4asp_PT
|
||||||
|
out(Iuh_Send -> ASP_Send:function(Iuh_to_IPL4_Send))
|
||||||
|
in(ASP_RecvFrom -> Iuh_RecvFrom: function(IPL4_to_Iuh_RecvFrom);
|
||||||
|
ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple;
|
||||||
|
ASP_Event -> ASP_Event: simple)"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
module Iuh_CodecPort_CtrlFunct {
|
||||||
|
|
||||||
|
import from Iuh_CodecPort all;
|
||||||
|
import from IPL4asp_Types all;
|
||||||
|
|
||||||
|
external function f_IPL4_listen(
|
||||||
|
inout Iuh_CODEC_PT portRef,
|
||||||
|
in HostName locName,
|
||||||
|
in PortNumber locPort,
|
||||||
|
in ProtoTuple proto,
|
||||||
|
in OptionList options := {}
|
||||||
|
) return Result;
|
||||||
|
|
||||||
|
external function f_IPL4_connect(
|
||||||
|
inout Iuh_CODEC_PT portRef,
|
||||||
|
in HostName remName,
|
||||||
|
in PortNumber remPort,
|
||||||
|
in HostName locName,
|
||||||
|
in PortNumber locPort,
|
||||||
|
in ConnectionId connId,
|
||||||
|
in ProtoTuple proto,
|
||||||
|
in OptionList options := {}
|
||||||
|
) return Result;
|
||||||
|
|
||||||
|
external function f_IPL4_close(
|
||||||
|
inout Iuh_CODEC_PT portRef,
|
||||||
|
in ConnectionId id,
|
||||||
|
in ProtoTuple proto := { unspecified := {} }
|
||||||
|
) return Result;
|
||||||
|
|
||||||
|
external function f_IPL4_setUserData(
|
||||||
|
inout Iuh_CODEC_PT portRef,
|
||||||
|
in ConnectionId id,
|
||||||
|
in UserData userData
|
||||||
|
) return Result;
|
||||||
|
|
||||||
|
external function f_IPL4_getUserData(
|
||||||
|
inout Iuh_CODEC_PT portRef,
|
||||||
|
in ConnectionId id,
|
||||||
|
out UserData userData
|
||||||
|
) return Result;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "IPL4asp_PortType.hh"
|
||||||
|
#include "Iuh_CodecPort.hh"
|
||||||
|
#include "IPL4asp_PT.hh"
|
||||||
|
|
||||||
|
namespace Iuh__CodecPort__CtrlFunct {
|
||||||
|
|
||||||
|
IPL4asp__Types::Result f__IPL4__listen(
|
||||||
|
Iuh__CodecPort::Iuh__CODEC__PT& portRef,
|
||||||
|
const IPL4asp__Types::HostName& locName,
|
||||||
|
const IPL4asp__Types::PortNumber& locPort,
|
||||||
|
const IPL4asp__Types::ProtoTuple& proto,
|
||||||
|
const IPL4asp__Types::OptionList& options)
|
||||||
|
{
|
||||||
|
return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPL4asp__Types::Result f__IPL4__connect(
|
||||||
|
Iuh__CodecPort::Iuh__CODEC__PT& portRef,
|
||||||
|
const IPL4asp__Types::HostName& remName,
|
||||||
|
const IPL4asp__Types::PortNumber& remPort,
|
||||||
|
const IPL4asp__Types::HostName& locName,
|
||||||
|
const IPL4asp__Types::PortNumber& locPort,
|
||||||
|
const IPL4asp__Types::ConnectionId& connId,
|
||||||
|
const IPL4asp__Types::ProtoTuple& proto,
|
||||||
|
const IPL4asp__Types::OptionList& options)
|
||||||
|
{
|
||||||
|
return f__IPL4__PROVIDER__connect(portRef, remName, remPort,
|
||||||
|
locName, locPort, connId, proto, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPL4asp__Types::Result f__IPL4__close(
|
||||||
|
Iuh__CodecPort::Iuh__CODEC__PT& portRef,
|
||||||
|
const IPL4asp__Types::ConnectionId& connId,
|
||||||
|
const IPL4asp__Types::ProtoTuple& proto)
|
||||||
|
{
|
||||||
|
return f__IPL4__PROVIDER__close(portRef, connId, proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPL4asp__Types::Result f__IPL4__setUserData(
|
||||||
|
Iuh__CodecPort::Iuh__CODEC__PT& portRef,
|
||||||
|
const IPL4asp__Types::ConnectionId& connId,
|
||||||
|
const IPL4asp__Types::UserData& userData)
|
||||||
|
{
|
||||||
|
return f__IPL4__PROVIDER__setUserData(portRef, connId, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPL4asp__Types::Result f__IPL4__getUserData(
|
||||||
|
Iuh__CodecPort::Iuh__CODEC__PT& portRef,
|
||||||
|
const IPL4asp__Types::ConnectionId& connId,
|
||||||
|
IPL4asp__Types::UserData& userData)
|
||||||
|
{
|
||||||
|
return f__IPL4__PROVIDER__getUserData(portRef, connId, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
module Iuh_Emulation {
|
||||||
|
|
||||||
|
/* Iuh Emulation, runs on top of Iuh_CodecPort. It multiplexes/demultiplexes
|
||||||
|
* HNBAP and RUA.
|
||||||
|
*
|
||||||
|
* The Iuh_Emulation.main() function processes Iuh primitives from the Iuh
|
||||||
|
* socket via the Iuh_CodecPort, and dispatches them to HNBAP/RUA ports.
|
||||||
|
*
|
||||||
|
* (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@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 Iuh_CodecPort all;
|
||||||
|
import from Iuh_CodecPort_CtrlFunct all;
|
||||||
|
import from HNBAP_Types all;
|
||||||
|
import from HNBAP_Constants all;
|
||||||
|
import from HNBAP_PDU_Contents all;
|
||||||
|
import from HNBAP_PDU_Descriptions all;
|
||||||
|
import from HNBAP_IEs all;
|
||||||
|
import from HNBAP_Templates all;
|
||||||
|
import from RUA_Types all;
|
||||||
|
import from RUA_Constants all;
|
||||||
|
import from RUA_PDU_Contents all;
|
||||||
|
import from RUA_PDU_Descriptions all;
|
||||||
|
import from RUA_IEs all;
|
||||||
|
import from RUA_Templates all;
|
||||||
|
import from Iuh_Types all;
|
||||||
|
|
||||||
|
import from General_Types all;
|
||||||
|
import from Misc_Helpers all;
|
||||||
|
import from Osmocom_Types all;
|
||||||
|
import from IPL4asp_Types all;
|
||||||
|
import from DNS_Helpers all;
|
||||||
|
|
||||||
|
type enumerated IUHEM_EventUpDown {
|
||||||
|
IUHEM_EVENT_DOWN,
|
||||||
|
IUHEM_EVENT_UP
|
||||||
|
}
|
||||||
|
|
||||||
|
/* an event indicating us whether or not a connection is physically up or down. */
|
||||||
|
type union IUHEM_Event {
|
||||||
|
IUHEM_EventUpDown up_down
|
||||||
|
}
|
||||||
|
|
||||||
|
type port HNBAP_PT message {
|
||||||
|
inout HNBAP_PDU, IUHEM_Event;
|
||||||
|
} with { extension "internal" };
|
||||||
|
type port RUA_PT message {
|
||||||
|
inout RUA_PDU, IUHEM_Event;
|
||||||
|
} with { extension "internal" };
|
||||||
|
|
||||||
|
type component Iuh_Emulation_CT {
|
||||||
|
/* Port facing to the SCTP SUT */
|
||||||
|
port Iuh_CODEC_PT Iuh;
|
||||||
|
/* Port facing to user upper side stack: */
|
||||||
|
port HNBAP_PT HNBAP;
|
||||||
|
port RUA_PT RUA;
|
||||||
|
|
||||||
|
var Iuh_conn_parameters g_pars;
|
||||||
|
var charstring g_Iuh_id;
|
||||||
|
var integer g_self_conn_id := -1;
|
||||||
|
var IPL4asp_Types.ConnectionId g_last_conn_id := -1; /* server only */
|
||||||
|
}
|
||||||
|
|
||||||
|
type record Iuh_conn_parameters {
|
||||||
|
HostName remote_ip,
|
||||||
|
PortNumber remote_sctp_port,
|
||||||
|
HostName local_ip,
|
||||||
|
PortNumber local_sctp_port
|
||||||
|
}
|
||||||
|
|
||||||
|
function tr_Iuh_RecvFrom_R(template Iuh_PDU msg)
|
||||||
|
runs on Iuh_Emulation_CT return template Iuh_RecvFrom {
|
||||||
|
var template Iuh_RecvFrom mrf := {
|
||||||
|
connId := ?,
|
||||||
|
remName := ?,
|
||||||
|
remPort := ?,
|
||||||
|
locName := ?,
|
||||||
|
locPort := ?,
|
||||||
|
msg := msg
|
||||||
|
}
|
||||||
|
return mrf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := omit) := {
|
||||||
|
sinfo_stream := omit,
|
||||||
|
sinfo_ppid := ppid,
|
||||||
|
remSocks := omit,
|
||||||
|
assocId := omit
|
||||||
|
};
|
||||||
|
|
||||||
|
private template PortEvent tr_SctpAssocChange := {
|
||||||
|
sctpEvent := {
|
||||||
|
sctpAssocChange := ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private template PortEvent tr_SctpPeerAddrChange := {
|
||||||
|
sctpEvent := {
|
||||||
|
sctpPeerAddrChange := ?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function emu_is_server() runs on Iuh_Emulation_CT return boolean {
|
||||||
|
return g_pars.remote_sctp_port == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resolve TCP/IP connection identifier depending on server/client mode */
|
||||||
|
private function f_iuh_conn_id() runs on Iuh_Emulation_CT
|
||||||
|
return IPL4asp_Types.ConnectionId {
|
||||||
|
var IPL4asp_Types.ConnectionId conn_id;
|
||||||
|
|
||||||
|
if (not emu_is_server()) {
|
||||||
|
conn_id := g_self_conn_id;
|
||||||
|
} else {
|
||||||
|
conn_id := g_last_conn_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn_id == -1) { /* Just to be sure */
|
||||||
|
f_shutdown(__FILE__, __LINE__, fail, "Connection is not established");
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function main(Iuh_conn_parameters p, charstring id) runs on Iuh_Emulation_CT {
|
||||||
|
var Result res;
|
||||||
|
g_pars := p;
|
||||||
|
g_Iuh_id := id;
|
||||||
|
|
||||||
|
map(self:Iuh, system:Iuh_CODEC_PT);
|
||||||
|
if (emu_is_server()) {
|
||||||
|
res := Iuh_CodecPort_CtrlFunct.f_IPL4_listen(Iuh, p.local_ip, p.local_sctp_port, { sctp := valueof(ts_SCTP) });
|
||||||
|
} else {
|
||||||
|
res := Iuh_CodecPort_CtrlFunct.f_IPL4_connect(Iuh, p.remote_ip, p.remote_sctp_port,
|
||||||
|
p.local_ip, p.local_sctp_port, -1, { sctp := valueof(ts_SCTP) });
|
||||||
|
}
|
||||||
|
if (not ispresent(res.connId)) {
|
||||||
|
f_shutdown(__FILE__, __LINE__, fail, "Could not connect Iuh socket, check your configuration");
|
||||||
|
}
|
||||||
|
g_self_conn_id := res.connId;
|
||||||
|
|
||||||
|
/* notify user about SCTP establishment */
|
||||||
|
if (p.remote_sctp_port != -1) {
|
||||||
|
HNBAP.send(IUHEM_Event:{up_down:=IUHEM_EVENT_UP});
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var Iuh_RecvFrom mrf;
|
||||||
|
var HNBAP_PDU hnbap_msg;
|
||||||
|
var RUA_PDU rua_msg;
|
||||||
|
var ASP_Event asp_evt;
|
||||||
|
|
||||||
|
alt {
|
||||||
|
/* HNBAP from client: pass on transparently */
|
||||||
|
[] HNBAP.receive(HNBAP_PDU:?) -> value hnbap_msg {
|
||||||
|
/* Pass message through */
|
||||||
|
Iuh.send(t_Iuh_Send_HNBAP(f_iuh_conn_id(), hnbap_msg));
|
||||||
|
}
|
||||||
|
/* RUA from client: pass on transparently */
|
||||||
|
[] RUA.receive(RUA_PDU:?) -> value rua_msg {
|
||||||
|
/* Pass message through */
|
||||||
|
Iuh.send(t_Iuh_Send_RUA(f_iuh_conn_id(), rua_msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iuh received from peer (HNBGW or HnodeB) */
|
||||||
|
[] Iuh.receive(tr_Iuh_RecvFrom_R(?)) -> value mrf {
|
||||||
|
if (not match(mrf.connId, f_iuh_conn_id())) {
|
||||||
|
f_shutdown(__FILE__, __LINE__, fail, log2str("Received message from unexpected conn_id!", mrf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match(mrf, t_Iuh_RecvFrom_HNBAP(?))) {
|
||||||
|
HNBAP.send(mrf.msg.hnbap);
|
||||||
|
} else if (match(mrf, t_Iuh_RecvFrom_RUA(?))) {
|
||||||
|
RUA.send(mrf.msg.rua);
|
||||||
|
} else {
|
||||||
|
/* TODO: special handling, as it contains multiple HNB connection ids */
|
||||||
|
f_shutdown(__FILE__, __LINE__, fail, log2str("UNEXPECTED MESSAGE RECEIVED!", mrf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[] Iuh.receive(tr_SctpAssocChange) { }
|
||||||
|
[] Iuh.receive(tr_SctpPeerAddrChange) { }
|
||||||
|
|
||||||
|
/* server only */
|
||||||
|
[] Iuh.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
|
||||||
|
if (not emu_is_server()) {
|
||||||
|
f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected event receiver in client mode", asp_evt));
|
||||||
|
}
|
||||||
|
g_last_conn_id := asp_evt.connOpened.connId;
|
||||||
|
log("Established a new Iuh connection (conn_id=", g_last_conn_id, ")");
|
||||||
|
|
||||||
|
HNBAP.send(IUHEM_Event:{up_down:=IUHEM_EVENT_UP}); /* TODO: send g_last_conn_id */
|
||||||
|
}
|
||||||
|
|
||||||
|
[] Iuh.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
|
||||||
|
log("Iuh: Closed");
|
||||||
|
g_self_conn_id := -1;
|
||||||
|
HNBAP.send(IUHEM_Event:{up_down:=IUHEM_EVENT_DOWN}); /* TODO: send asp_evt.connClosed.connId */
|
||||||
|
if (not emu_is_server()) {
|
||||||
|
self.stop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* Osmocom Iuh Interface Types
|
||||||
|
* (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Iuh Codec Port Types
|
||||||
|
*
|
||||||
|
* (C) 2019 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
module Iuh_Types {
|
||||||
|
|
||||||
|
import from HNBAP_PDU_Descriptions all;
|
||||||
|
import from HNBAP_Types all;
|
||||||
|
import from RUA_PDU_Descriptions all;
|
||||||
|
import from RUA_Types all;
|
||||||
|
|
||||||
|
type union Iuh_PDU {
|
||||||
|
HNBAP_PDU hnbap,
|
||||||
|
RUA_PDU rua,
|
||||||
|
octetstring payload
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,135 @@
|
||||||
|
/* HNBAP Templates in TTCN-3
|
||||||
|
* (C) 2021 Pau Espin Pedrol <pespin@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
|
||||||
|
*/
|
||||||
|
|
||||||
|
module HNBAP_Templates {
|
||||||
|
|
||||||
|
import from General_Types all;
|
||||||
|
import from Osmocom_Types all;
|
||||||
|
|
||||||
|
import from HNBAP_IEs all;
|
||||||
|
import from HNBAP_CommonDataTypes all;
|
||||||
|
import from HNBAP_Constants all;
|
||||||
|
import from HNBAP_Containers all;
|
||||||
|
import from HNBAP_PDU_Contents all;
|
||||||
|
import from HNBAP_PDU_Descriptions all;
|
||||||
|
|
||||||
|
/*********************************************************************************
|
||||||
|
* 3GPP TS 25.469
|
||||||
|
*********************************************************************************/
|
||||||
|
|
||||||
|
template (value) Cause ts_HnbapCause(template (value) CauseRadioNetwork c) := {
|
||||||
|
radioNetwork := c
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 9.1.3 HNB REGISTER REQUEST */
|
||||||
|
template (present) HNBAP_PDU
|
||||||
|
tr_HNBAP_HNBRegisterRequest(template (present) octetstring hNB_Identity_Info := ?,
|
||||||
|
template (present) OCT3 plmnid := ?,
|
||||||
|
template (present) BIT28 cell_identity := ?,
|
||||||
|
template (present) OCT2 lac := ?,
|
||||||
|
template (present) OCT1 rac := ?,
|
||||||
|
template (present) OCT2 sac := ?) := {
|
||||||
|
initiatingMessage := {
|
||||||
|
procedureCode := id_HNBRegister,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := {
|
||||||
|
hNBRegisterRequest := {
|
||||||
|
protocolIEs := {
|
||||||
|
{
|
||||||
|
id := HNBAP_Constants.id_HNB_Identity,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := {
|
||||||
|
hNB_Identity := {
|
||||||
|
hNB_Identity_Info := hNB_Identity_Info,
|
||||||
|
iE_Extensions := omit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id := 8,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := {
|
||||||
|
hNB_Location_Information := {
|
||||||
|
macroCoverageInfo := omit,
|
||||||
|
geographicalCoordinates := omit,
|
||||||
|
iE_Extensions := omit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id := 9,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := { pLMNidentity := plmnid }
|
||||||
|
}, {
|
||||||
|
id := 11,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := { cellIdentity := cell_identity }
|
||||||
|
}, {
|
||||||
|
id := 6,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := { lAC := lac }
|
||||||
|
}, {
|
||||||
|
id := 7,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := { rAC := rac }
|
||||||
|
}, {
|
||||||
|
id := 10,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := { sAC := sac }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
protocolExtensions := omit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 9.1.4 HNB REGISTER ACCEPT */
|
||||||
|
template (value) HNBAP_PDU
|
||||||
|
ts_HNBAP_HNBRegisterAccept(template (value) uint16_t rnc_id) := {
|
||||||
|
successfulOutcome := {
|
||||||
|
procedureCode := id_HNBRegister,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := {
|
||||||
|
hNBRegisterAccept := {
|
||||||
|
protocolIEs := {
|
||||||
|
{
|
||||||
|
id := HNBAP_Constants.id_RNC_ID,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := { RNC_ID := rnc_id }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
protocolExtensions := omit /* TODO: Mux Port Number (optional) 9.2.29 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 9.1.5 HNB REGISTER REJECT */
|
||||||
|
template (value) HNBAP_PDU
|
||||||
|
ts_HNBAP_HNBRegisterReject(template (value) Cause cause) := {
|
||||||
|
unsuccessfulOutcome := {
|
||||||
|
procedureCode := id_HNBRegister,
|
||||||
|
criticality := reject,
|
||||||
|
value_ := {
|
||||||
|
HNBRegisterReject := {
|
||||||
|
protocolIEs := {
|
||||||
|
{
|
||||||
|
id := HNBAP_Constants.id_Cause,
|
||||||
|
criticality := ignore,
|
||||||
|
value_ := { Cause := cause }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
protocolExtensions := omit /* TODO: CriticalityDiagnostics, BackoffTimer */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* RUA Templates in TTCN-3
|
||||||
|
* (C) 2021 Pau Espin Pedrol <pespin@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
|
||||||
|
*/
|
||||||
|
|
||||||
|
module RUA_Templates {
|
||||||
|
|
||||||
|
import from RUA_IEs all;
|
||||||
|
import from RUA_CommonDataTypes all;
|
||||||
|
import from RUA_Constants all;
|
||||||
|
import from RUA_Containers all;
|
||||||
|
import from RUA_PDU_Contents all;
|
||||||
|
import from RUA_PDU_Descriptions all;
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Add RUA Templates here */
|
||||||
|
}
|
Loading…
Reference in New Issue