summaryrefslogtreecommitdiffstats
path: root/library/NS_RAW.ttcn
blob: 848f488135a8689e1bd4317a803b9dbcad23cfed (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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
module NS_RAW {

/* "RAW" NS utilities: Wrapper around several NS_CodecPort */

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from GSM_RR_Types all;

import from NS_Types all;
import from BSSGP_Types all;
import from Osmocom_Gb_Types all;

import from IPL4asp_Types all;
import from NS_CodecPort all;
import from NS_CodecPort_CtrlFunct all;
import from Native_Functions all;

import from NS_Emulation all;
import from BSSGP_Emulation all;

type component RAW_NS_CT {
	/* UDP port towards the bottom (IUT) */
	port NS_CODEC_PT NSCP[4];
	var ConnectionId g_ns_conn_id[4] := {-1, -1, -1, -1};
	var NSConfiguration g_nsconfig[4];
	timer g_T_guard;
}

private altstep as_Tguard() runs on RAW_NS_CT {
	[] g_T_guard.timeout {
		setverdict(fail, "Timeout of T_guard");
		mtc.stop;
		}
}

function f_init_ns_codec(NSConfiguration nsconfig, integer idx := 0, float guard_secs := 60.0)
runs on RAW_NS_CT {
	var Result res;

	if (not g_T_guard.running) {
		g_T_guard.start(guard_secs);
		activate(as_Tguard());
	}

	if (not isbound(g_nsconfig) or not isbound(g_nsconfig[idx])) {
		/* copy most parts from nsconfig */
		g_nsconfig[idx] := nsconfig;
/* FIXME */
		/* adjust those parts different for each NS-VC */
		g_nsconfig[idx].nsvci := nsconfig.nsvci + idx;
		g_nsconfig[idx].local_udp_port := nsconfig.local_udp_port + idx;
	}

	map(self:NSCP[idx], system:NSCP);
	/* Connect the UDP socket */
	log("connecting NSCP[", idx, "] to ", g_nsconfig[idx]);
	res := f_IPL4_connect(NSCP[idx], g_nsconfig[idx].remote_ip, g_nsconfig[idx].remote_udp_port,
				g_nsconfig[idx].local_ip, g_nsconfig[idx].local_udp_port, 0, { udp := {}});
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect NS UDP socket, check your configuration ", g_nsconfig[idx]);
		mtc.stop;
	}
	g_ns_conn_id[idx] := res.connId;

}

function f_ns_exp(template PDU_NS exp_rx, integer idx := 0) runs on RAW_NS_CT return PDU_NS {
	var NS_RecvFrom nrf;
	log("f_ns_exp() expecting ", exp_rx);
	alt {
	[] NSCP[idx].receive(t_NS_RecvFrom(exp_rx)) -> value nrf { }
	[] NSCP[idx].receive {
		setverdict(fail, "Received unexpected NS: ", nrf);
		mtc.stop;
		}
	}
	return nrf.msg;
}

/* perform outbound NS-ALIVE procedure */
function f_outgoing_ns_alive(integer idx := 0) runs on RAW_NS_CT {
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], t_NS_ALIVE));
	alt {
	[] NSCP[idx].receive(t_NS_RecvFrom(t_NS_ALIVE_ACK));
	[] NSCP[idx].receive { repeat; }
	}
}

/* perform outbound NS-ALIVE procedure */
function f_outgoing_ns_alive_no_ack(integer idx := 0, float tout := 10.0) runs on RAW_NS_CT {
	timer T := tout;
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], t_NS_ALIVE));
	T.start;
	alt {
	[] NSCP[idx].receive(t_NS_RecvFrom(t_NS_ALIVE_ACK)) {
		setverdict(fail, "Received unexpected NS-ALIVE ACK");
		}
	[] NSCP[idx].receive { repeat; }
	[] T.timeout {
		setverdict(pass);
		}
	}
}

/* ensure no matching message is received within 'tout' */
function f_ensure_no_ns(template PDU_NS ns := ?, integer idx := 0, float tout := 3.0)
runs on RAW_NS_CT {
	timer T := tout;
	T.start;
	alt {
	[] NSCP[idx].receive(t_NS_RecvFrom(ns)) {
		setverdict(fail, "NS-ALIVE from unconfigured (possibly initial) endpoint");
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
}

/* perform outbound NS-BLOCK procedure */
function f_outgoing_ns_block(NsCause cause, integer idx := 0) runs on RAW_NS_CT {
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_NS_BLOCK(cause, g_nsconfig[idx].nsvci)));
	alt {
	[] NSCP[idx].receive(t_NS_RecvFrom(tr_NS_BLOCK_ACK(g_nsconfig[idx].nsvci)));
	[] NSCP[idx].receive { repeat; }
	}
}

/* receive NS-ALIVE and ACK it */
altstep as_rx_alive_tx_ack(boolean oneshot := false, integer idx := 0) runs on RAW_NS_CT {
	[] NSCP[idx].receive(t_NS_RecvFrom(t_NS_ALIVE)) {
		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], t_NS_ALIVE_ACK));
		if (not oneshot) { repeat; }
		}
}

/* Transmit BSSGP RESET for given BVCI and expect ACK */
function f_tx_bvc_reset_rx_ack(BssgpBvci bvci, BssgpCellId cell_id, integer idx := 0, boolean exp_ack := true)
runs on RAW_NS_CT {
	var PDU_BSSGP bssgp_tx := valueof(ts_BVC_RESET(BSSGP_CAUSE_NET_SV_CAP_MOD_GT_ZERO_KBPS, bvci,
							cell_id));
	timer T := 5.0;
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_NS_UNITDATA(t_SduCtrlB, 0, enc_PDU_BSSGP(bssgp_tx))));
	T.start;
	alt {
	[exp_ack] NSCP[idx].receive(t_NS_RecvFrom(tr_NS_UNITDATA(t_SduCtrlB, 0,
						  decmatch tr_BVC_RESET_ACK(bvci, ?)))) {
		setverdict(pass);
		}
	[exp_ack] T.timeout {
		setverdict(fail, "No response to BVC-RESET");
		}
	[not exp_ack] T.timeout {
		setverdict(pass);
		}
	[] NSCP[idx].receive { repeat; }
	}
}

/* Receive a BSSGP RESET for given BVCI and ACK it */
altstep as_rx_bvc_reset_tx_ack(BssgpBvci bvci, BssgpCellId cell_id, boolean oneshot := false,
				integer idx := 0)
runs on RAW_NS_CT {
	var NS_RecvFrom ns_rf;
	/* FIXME: nail down received cell_id in match */
	[] NSCP[idx].receive(t_NS_RecvFrom(tr_NS_UNITDATA(t_SduCtrlB, 0,
						  decmatch tr_BVC_RESET(?, bvci, ?))))
								-> value ns_rf {
		var PDU_BSSGP bssgp_rx := dec_PDU_BSSGP(ns_rf.msg.pDU_NS_Unitdata.nS_SDU);
		var PDU_BSSGP bssgp_tx := valueof(ts_BVC_RESET_ACK(bvci, cell_id));
		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_NS_UNITDATA(t_SduCtrlB, 0, enc_PDU_BSSGP(bssgp_tx))));
		if (not oneshot) { repeat; }
		}
}


/* Receive a BSSGP UNBLOCK for given BVCI and ACK it */
altstep as_rx_bvc_unblock_tx_ack(BssgpBvci bvci, boolean oneshot := false, integer idx := 0) runs on RAW_NS_CT {
	var NS_RecvFrom ns_rf;
	[] NSCP[idx].receive(t_NS_RecvFrom(tr_NS_UNITDATA(t_SduCtrlB, 0,
						  decmatch t_BVC_UNBLOCK(bvci))))
								-> value ns_rf {
		var PDU_BSSGP bssgp_rx := dec_PDU_BSSGP(ns_rf.msg.pDU_NS_Unitdata.nS_SDU);
		var PDU_BSSGP bssgp_tx := valueof(t_BVC_UNBLOCK_ACK(bvci));
		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_NS_UNITDATA(t_SduCtrlB, 0, enc_PDU_BSSGP(bssgp_tx))));
		if (not oneshot) { repeat; }
		}
}

/* Receive a BSSGP FLOW-CONTROL-BVC and ACK it */
altstep as_rx_bvc_fc_tx_ack(BssgpBvci bvci, boolean oneshot := false, integer idx := 0) runs on RAW_NS_CT {
	var NS_RecvFrom ns_rf;
	[] NSCP[idx].receive(t_NS_RecvFrom(tr_NS_UNITDATA(t_SduCtrlB, bvci,
						  decmatch tr_BVC_FC_BVC)))
								-> value ns_rf {
		var PDU_BSSGP bssgp_rx := dec_PDU_BSSGP(ns_rf.msg.pDU_NS_Unitdata.nS_SDU);
		var OCT1 tag := bssgp_rx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value;
		var PDU_BSSGP bssgp_tx := valueof(t_BVC_FC_BVC_ACK(tag));
		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_NS_UNITDATA(t_SduCtrlB, bvci, enc_PDU_BSSGP(bssgp_tx))));
		if (not oneshot) { repeat; }
		}
}


/* Receive a NS-RESET and ACK it */
altstep as_rx_ns_reset_ack(boolean oneshot := false, integer idx := 0) runs on RAW_NS_CT {
	var NS_RecvFrom ns_rf;
	[] NSCP[idx].receive(t_NS_RecvFrom(tr_NS_RESET(NS_CAUSE_OM_INTERVENTION, g_nsconfig[idx].nsvci,
						  g_nsconfig[idx].nsei))) -> value ns_rf {
		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_NS_RESET_ACK(g_nsconfig[idx].nsvci,
									    g_nsconfig[idx].nsei)));
		if (not oneshot) { repeat; }
		}
}
/* Receive a NS-UNBLOCK and ACK it */
altstep as_rx_ns_unblock_ack(boolean oneshot := false, integer idx := 0) runs on RAW_NS_CT {
	var NS_RecvFrom ns_rf;
	[] NSCP[idx].receive(t_NS_RecvFrom(t_NS_UNBLOCK)) -> value ns_rf {
		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], t_NS_UNBLOCK_ACK));
		if (not oneshot) { repeat; }
		}
}



}