aboutsummaryrefslogtreecommitdiffstats
path: root/cbc/BSC_ConnectionHandler.ttcn
blob: 5f4fa59c9dc4dd66cbb94b24a32714d42de58720 (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
/* 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);
		}
	}
}

}