osmo-ttcn3-hacks/cbc/BSC_ConnectionHandler.ttcn

207 lines
7.2 KiB
Plaintext

/* BSC (CBSP) Connection Handler of CBC test suite in TTCN-3
* (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All rights reserved.
*
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* 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 BSC_ConnectionHandler {
import from Osmocom_Types all;
import from BSSAP_Types all;
import from BSSMAP_Templates all;
import from CBSP_Types all;
import from CBSP_Templates all;
import from CBSP_Adapter all;
import from CBSP_CodecPort all;
import from CBS_Message all;
type function void_fn() runs on BSC_ConnHdlr;
/* Coordinate with test_CT: */
type port BSC_ConnHdlr_Coord_PT message {
inout charstring;
} with { extension "internal" };
/* this component represents a single subscriber connection */
type component BSC_ConnHdlr extends CBSP_Adapter_CT {
var BSC_ConnHdlrPars g_pars;
port BSC_ConnHdlr_Coord_PT COORD;
}
type record BSC_ConnHdlrPars {
charstring bsc_host,
integer bsc_cbsp_port,
charstring cbc_host,
integer cbc_cbsp_port,
boolean tcp_is_client,
void_fn start_fn,
CBS_Message exp_cbs_msg optional,
BSSMAP_FIELD_CellIdentificationList cell_list_success optional,
CBSP_FailureListItems tx_fail_list optional
};
function f_BSC_ConnHdlr_main(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
g_pars := pars;
if (g_pars.tcp_is_client) {
CBSP_Adapter.f_connect(g_pars.cbc_host, g_pars.cbc_cbsp_port,
g_pars.bsc_host, g_pars.bsc_cbsp_port);
} else {
CBSP_Adapter.f_bind(g_pars.bsc_host, g_pars.bsc_cbsp_port);
CBSP_Adapter.f_wait_client_connect();
}
var BSSMAP_FIELD_CellIdentificationList cell_list := {
cIl_allInBSS := ''O
};
activate(as_cbsp_keepalive_ack(0));
f_cbsp_send(ts_CBSP_RESTART(cell_list, CBSP_BC_MSGT_CBS, CBSP_RI_DATA_LOST));
f_cbsp_send(ts_CBSP_RESTART(cell_list, CBSP_BC_MSGT_EMERG, CBSP_RI_DATA_LOST));
as_cbsp_reset(0);
COORD.send(COORD_MSG_CONNECTED);
g_pars.start_fn.apply();
}
altstep as_cbsp_reset(integer idx) runs on CBSP_Adapter_CT {
var CBSP_RecvFrom rf;
[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_RESET)) -> value rf {
var CBSP_IE ie;
f_cbsp_find_ie(rf.msg, CBSP_IEI_CELL_LIST, ie);
CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx],
ts_CBSP_RESET_COMPL(ie.body.cell_list.cell_id)));
}
}
/* receive + acknowledge KEEP-ALIVE */
altstep as_cbsp_keepalive_ack(integer idx) runs on CBSP_Adapter_CT {
[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_KEEP_ALIVE)) {
CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], ts_CBSP_KEEP_ALIVE_COMPL));
}
}
/* receive + ignore RESTART */
altstep as_cbsp_restart(integer idx) runs on CBSP_Adapter_CT {
[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_RESTART));
}
function f_cbsp_tx_write_compl(CBS_Message msg, integer idx := 0,
template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit,
template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit)
runs on BSC_ConnHdlr {
var template (value) CBSP_PDU tx;
var template (value) BSSMAP_FIELD_CellIdentificationList tx_list;
if (istemplatekind(tx_cell_list, "omit")) {
/* use the "expected list" when confirming the write-replace */
tx_list := msg.cell_list;
} else {
/* use an user-provided different list of cells */
tx_list := valueof(tx_cell_list);
}
if (istemplatekind(tx_compl_list, "omit")) {
if (msg_id_is_etws(msg.msg_id)) {
tx := ts_CBSP_WRITE_EMERG_COMPL(msg.msg_id, msg.ser_nr, tx_list);
} else {
tx := ts_CBSP_WRITE_CBS_COMPL(msg.msg_id, msg.ser_nr, tx_list, msg.channel_ind);
}
} else {
if (msg_id_is_etws(msg.msg_id)) {
tx := ts_CBSP_REPLACE_EMERG_COMPL(msg.msg_id, msg.ser_nr, msg.old_ser_nr,
tx_list);
} else {
tx := ts_CBSP_REPLACE_CBS_COMPL(msg.msg_id, msg.ser_nr, msg.old_ser_nr,
valueof(tx_compl_list), tx_list,
msg.channel_ind);
}
}
CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx));
}
function f_cbsp_tx_write_fail(CBS_Message msg, integer idx := 0,
template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit,
template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit,
template (omit) CBSP_FailureListItems tx_fail_list := omit)
runs on BSC_ConnHdlr {
var template (value) CBSP_PDU tx;
tx := ts_CBSP_WRITE_CBS_FAIL(msg.msg_id, msg.ser_nr, valueof(tx_fail_list),
tx_compl_list, tx_cell_list, msg.channel_ind);
CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx));
}
/* handle a CBSP-WRITE-REPLACE and respond to it with COMPLETE or FAILURE depending on arguments */
function f_cbsp_handle_write(CBS_Message msg, integer idx := 0,
template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit,
template (omit) CBSP_FailureListItems tx_fail_list := omit,
template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit)
runs on BSC_ConnHdlr {
var template CBSP_IEs content_ies := {};
var template (present) CBSP_PDU rx_templ;
var CBSP_RecvFrom rf;
if (msg_id_is_etws(msg.msg_id)) {
rx_templ := tr_CBSP_WRITE_EMERG(msg.msg_id, msg.ser_nr, msg.cell_list, 1,
hex2int('180'H) + (msg.msg_id - 4352),
msg.num_bcast_req, 0)
} else {
for (var integer i := 0; i < lengthof(msg.content); i := i+1) {
//content_ies[i] := tr_CbspMsgContent(msg.content[i].payload, msg.content[i].user_len);
content_ies[i] := tr_CbspMsgContent(?, ?);
}
rx_templ := tr_CBSP_WRITE_CBS(msg.msg_id, msg.ser_nr, msg.cell_list, msg.channel_ind,
msg.category, msg.rep_period, msg.num_bcast_req, msg.dcs,
content_ies);
}
alt {
[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf {
var template (value) CBSP_PDU tx;
if (istemplatekind(tx_fail_list, "omit")) {
f_cbsp_tx_write_compl(msg, idx, tx_cell_list, tx_compl_list);
} else {
f_cbsp_tx_write_fail(msg, idx, tx_cell_list, tx_compl_list, tx_fail_list);
}
}
[] as_cbsp_keepalive_ack(idx) { repeat; }
[] CBSP[idx].receive {
setverdict(fail, "Received unexpected CBSP in index ", idx);
}
}
}
/* handle a CBSP-KILL and respond to it with COMPLETE or FAILURE depending on arguments */
function f_cbsp_handle_kill(integer idx, uint16_t msg_id, uint16_t ser_nr,
template BSSMAP_FIELD_CellIdentificationList exp_list,
template (omit) BSSMAP_FIELD_CellIdentificationList tx_list,
template (omit) CBSP_FailureListItems tx_fail_list := omit,
template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit,
template (omit) uint8_t channel_ind := omit)
runs on BSC_ConnHdlr {
var template (present) CBSP_PDU rx_templ;
var CBSP_RecvFrom rf;
rx_templ := tr_CBSP_KILL(msg_id, ser_nr, exp_list, channel_ind);
alt {
[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf {
var template (value) CBSP_PDU tx;
if (istemplatekind(tx_fail_list, "omit")) {
tx := ts_CBSP_KILL_COMPL(msg_id, ser_nr, tx_compl_list, tx_list, channel_ind);
} else {
tx := ts_CBSP_KILL_FAIL(msg_id, ser_nr, valueof(tx_fail_list), tx_compl_list,
tx_list, channel_ind);
}
CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx));
}
[] as_cbsp_keepalive_ack(idx) { repeat; }
[] CBSP[idx].receive {
setverdict(fail, "Received unexpected CBSP in index ", idx);
}
}
}
}