aboutsummaryrefslogtreecommitdiffstats
path: root/cbc/MME_ConnectionHandler.ttcn
blob: 4ab30c644b70d704bd19751b9cd4412fb8ab24f5 (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
/* MME (SBc-AP) 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 MME_ConnectionHandler {

import from SBC_AP_IEs all;
import from SBC_AP_Constants all;
import from SBC_AP_PDU_Contents all;
import from SBC_AP_PDU_Descriptions all;
import from SBC_AP_Types all;
import from SBC_AP_Templates all;
import from SBC_AP_CodecPort all;
import from SBC_AP_Adapter all;

import from CBS_Message all;

type function void_fn() runs on MME_ConnHdlr;

/* Coordinate with test_CT: */
type port MME_ConnHdlr_Coord_PT message {
	inout charstring;
} with { extension "internal" };

/* this component represents a single subscriber connection */
type component MME_ConnHdlr extends SBC_AP_Adapter_CT {
	var MME_ConnHdlrPars g_pars;
	port MME_ConnHdlr_Coord_PT COORD;
}

type record MME_ConnHdlrPars {
	charstring mme_host,
	integer mme_sbcap_port,
	charstring cbc_host,
	integer cbc_sbcap_port,
	boolean sctp_is_client,
	void_fn start_fn,
	CBS_Message exp_cbs_msg optional,
	SBC_AP_Cause write_replace_warning_req_cause,
	SBC_AP_Cause write_replace_warning_ind_cause optional,
	List_of_TAIs write_repl_unknown_TAIs optional,
	CellId_Broadcast_List bcast_cell_id_list optional
};

function f_MME_ConnHdlr_main(charstring id, MME_ConnHdlrPars pars) runs on MME_ConnHdlr {
	g_pars := pars;
	if (g_pars.sctp_is_client) {
		SBC_AP_Adapter.f_connect(g_pars.cbc_host, g_pars.cbc_sbcap_port,
					 g_pars.mme_host, g_pars.mme_sbcap_port);
	} else {
		SBC_AP_Adapter.f_bind(g_pars.mme_host, g_pars.mme_sbcap_port);
		SBC_AP_Adapter.f_wait_client_connect();
	}
	COORD.send(COORD_MSG_CONNECTED);
	g_pars.start_fn.apply();
}

function f_sbcap_tx_write_replace_warn_resp(CBS_Message msg, integer idx := 0)
runs on MME_ConnHdlr {
	var template (value) SBC_AP_PDU tx;
	if (ispresent(g_pars.write_repl_unknown_TAIs)) {
		tx := ts_SBCAP_WRITE_WARNING_RESP_UNKNOWN_TAI(
						int2bit(msg.msg_id, 16),
						int2bit(msg.ser_nr, 16),
						g_pars.write_replace_warning_req_cause,
						g_pars.write_repl_unknown_TAIs);
	} else {
		tx := ts_SBCAP_WRITE_WARNING_RESP(int2bit(msg.msg_id, 16),
						  int2bit(msg.ser_nr, 16),
						  g_pars.write_replace_warning_req_cause);
	}
	f_SBC_AP_send(tx, idx);
}

function f_sbcap_tx_write_replace_warn_ind(integer idx := 0, CBS_Message msg,
					   SBC_AP_Cause cause,
					   template (value) CellId_Broadcast_List bcast_cell_id_li)
runs on MME_ConnHdlr {
	var template (value) SBC_AP_PDU tx;
	tx := ts_SBCAP_WRITE_WARNING_IND(int2bit(msg.msg_id, 16),
					 int2bit(msg.ser_nr, 16),
					 cause, bcast_cell_id_li);
	f_SBC_AP_send(tx, idx);
}

function f_sbcap_tx_stop_warn_resp(integer idx := 0, CBS_Message msg)
runs on MME_ConnHdlr {
	var template (value) SBC_AP_PDU tx;
	tx := ts_SBCAP_STOP_WARNING_RESP(int2bit(msg.msg_id, 16),
					  int2bit(msg.ser_nr, 16));
	f_SBC_AP_send(tx, idx);
}

/* handle a SBc-AP Write-Replace Request and respond to it with Response or FAILURE depending on arguments */
function f_sbcap_handle_write_replace_warn_req(CBS_Message msg, integer idx := 0)
runs on MME_ConnHdlr {
	var template (present) SBC_AP_PDU rx_templ;
	var SBC_AP_RecvFrom rf;
	if (msg_id_is_etws(msg.msg_id)) {
		rx_templ := tr_SBCAP_WRITE_WARNING_REQ_ETWS(
				int2bit(msg.msg_id, 16), int2bit(msg.ser_nr, 16),
				msg.rep_period, msg.num_bcast_req, hex2oct('018'H & int2hex(msg.msg_id - 4352, 1)));
	} else {
		rx_templ := tr_SBCAP_WRITE_WARNING_REQ_CBS(
				int2bit(msg.msg_id, 16), int2bit(msg.ser_nr, 16),
				msg.rep_period, msg.num_bcast_req);
	}
	alt {
	[] SBC_AP[idx].receive(tr_SBC_AP_Recv(g_SBC_AP_conn_id[idx], rx_templ)) -> value rf {
		log ("received expected req:", rf);
		f_sbcap_tx_write_replace_warn_resp(msg, idx);
		}
	[] SBC_AP[idx].receive {
		setverdict(fail, "Received unexpected SBc-AP in index ", idx);
		}
	}
}

/* handle a SBc-AP Stop-Warning-Request and respond to it with Response or FAILURE depending on arguments */
function f_sbcap_handle_stop_warn_req(integer idx := 0, CBS_Message msg)
runs on MME_ConnHdlr {
	var template (present) SBC_AP_PDU rx_templ;
	var SBC_AP_RecvFrom rf;

	rx_templ := tr_SBCAP_STOP_WARNING(int2bit(msg.msg_id, 16),
					  int2bit(msg.ser_nr, 16));
	alt {
	[] SBC_AP[idx].receive(tr_SBC_AP_Recv(g_SBC_AP_conn_id[idx], rx_templ)) -> value rf {
		log ("received expected req:", rf);
		f_sbcap_tx_stop_warn_resp(idx, msg);
		}
	[] SBC_AP[idx].receive {
		setverdict(fail, "Received unexpected SBc-AP in index ", idx);
		}
	}
}

}