blob: 75871c513e3ea1abaa9f82b2c4f907ec944b299e [file] [log] [blame]
Harald Weltea49e36e2018-01-21 19:29:33 +01001module BSC_ConnectionHandler {
2
3import from General_Types all;
4import from Osmocom_Types all;
Harald Welteb71901a2018-01-26 19:16:05 +01005import from Native_Functions all;
Harald Weltea49e36e2018-01-21 19:29:33 +01006import from GSM_Types all;
Harald Welteb71901a2018-01-26 19:16:05 +01007import from IPL4asp_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +01008import from SCCPasp_Types all;
9import from BSSAP_Types all;
10import from BSSMAP_Emulation all;
11import from BSSMAP_Templates all;
12
13import from GSUP_Types all;
14import from GSUP_Emulation all;
15
16import from MNCC_Types all;
17import from MNCC_Emulation all;
18
Harald Welte4aa970c2018-01-26 10:38:09 +010019import from MGCP_Types all;
20import from MGCP_Emulation all;
Harald Welteb71901a2018-01-26 19:16:05 +010021import from MGCP_Templates all;
22import from SDP_Types all;
Harald Welte4aa970c2018-01-26 10:38:09 +010023
Harald Weltea49e36e2018-01-21 19:29:33 +010024import from MobileL3_Types all;
25import from MobileL3_CommonIE_Types all;
26import from MobileL3_MM_Types all;
Harald Welteb71901a2018-01-26 19:16:05 +010027import from MobileL3_CC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010028import from L3_Templates all;
29
30/* this component represents a single subscriber connection */
Harald Welte4aa970c2018-01-26 10:38:09 +010031type component BSC_ConnHdlr extends BSSAP_ConnHdlr, MNCC_ConnHdlr, GSUP_ConnHdlr, MGCP_ConnHdlr {
Harald Weltea49e36e2018-01-21 19:29:33 +010032 var BSC_ConnHdlrPars g_pars;
33}
34
Harald Welte148a7082018-01-26 18:56:43 +010035type record AuthVector {
36 OCT16 rand,
37 OCT4 sres,
38 OCT8 kc
39 /* FIXME: 3G elements */
40}
41
Harald Weltea49e36e2018-01-21 19:29:33 +010042type record BSC_ConnHdlrPars {
43 SCCP_PAR_Address sccp_addr_own,
44 SCCP_PAR_Address sccp_addr_peer,
45 BSSMAP_IE_CellIdentifier cell_id,
Harald Welte256571e2018-01-24 18:47:19 +010046 hexstring imei,
Harald Weltea49e36e2018-01-21 19:29:33 +010047 hexstring imsi,
Harald Welte82600572018-01-21 20:54:08 +010048 hexstring msisdn,
Harald Welte256571e2018-01-24 18:47:19 +010049 OCT4 tmsi optional,
Harald Welte82600572018-01-21 20:54:08 +010050 BSSMAP_IE_ClassmarkInformationType2 cm2,
Harald Welte16114282018-01-24 22:41:21 +010051 BSSMAP_IE_ClassmarkInformationType3 cm3 optional,
Harald Welte148a7082018-01-26 18:56:43 +010052 AuthVector vec optional
Harald Weltea49e36e2018-01-21 19:29:33 +010053};
54
55
56/* Callback function from general BSSMAP_Emulation whenever a connectionless
57 * BSSMAP message arrives. Canreturn a PDU_BSSAPthat should be sent in return */
58private function BscUnitdataCallback(PDU_BSSAP bssap)
59runs on BSSMAP_Emulation_CT return template PDU_BSSAP {
60 var template PDU_BSSAP resp := omit;
61
62 log("BSSMAP_BscUnitdataCallback");
63 /* answer all RESET with RESET ACK */
64 if (match(bssap, tr_BSSMAP_Reset)){
65 log("BSSMAP_BscUnitdataCallback: Responding to RESET with RESET-ACK");
66 resp := ts_BSSMAP_ResetAck;
67 }
68
69 /* FIXME: Handle paging, etc. */
70 return resp;
71}
72
73const BssmapOps BSC_BssmapOps := {
74 /* Create call-back for inbound connections from MSC (hand-over) */
75 create_cb := refers(BSSMAP_Emulation.ExpectedCreateCallback),
76 unitdata_cb := refers(BscUnitdataCallback),
77 decode_dtap := true,
78 role_ms := true
79}
80
81
82private function MnccUnitdataCallback(MNCC_PDU mncc)
83runs on MNCC_Emulation_CT return template MNCC_PDU {
84 log("Ignoring MNCC", mncc);
85 return omit;
86}
87
88const MnccOps BCC_MnccOps := {
89 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
90 unitdata_cb := refers(MnccUnitdataCallback)
91}
92
93
94
95template BSSAP_Conn_Req ts_BSSAP_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, PDU_BSSAP bssap) := {
96 addr_peer := peer,
97 addr_own := own,
98 bssap := bssap
99};
100
Harald Weltea49e36e2018-01-21 19:29:33 +0100101/* Encode 'l3' and ask BSSMAP_Emulation to create new connection with COMPL L3 INFO */
102function f_bssap_compl_l3(PDU_ML3_MS_NW l3)
103runs on BSC_ConnHdlr {
104 log("Sending COMPL L3: ", l3);
105 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3);
106 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
107 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, l3_enc))));
Harald Welte71b69332018-01-21 20:43:53 +0100108 alt {
109 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
110 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
111 setverdict(fail, "DISC.ind from SCCP");
112 self.stop;
113 }
114 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100115}
116
117/* helper function to fully establish a dedicated channel */
Harald Welte148a7082018-01-26 18:56:43 +0100118function f_establish_fully(MobileIdentityLV mi, boolean expect_auth, boolean expect_ciph)
Harald Weltea49e36e2018-01-21 19:29:33 +0100119runs on BSC_ConnHdlr {
Harald Welte6ed6bf92018-01-24 21:09:15 +0100120 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100121 var PDU_DTAP_MT dtap_mt;
122
123 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
124 f_bssap_compl_l3(l3_info);
125
Harald Welte148a7082018-01-26 18:56:43 +0100126 f_mm_common(expect_auth, expect_ciph);
127 if (expect_ciph) {
128 /* implicit CM SERVICE ACCEPT? */
129 } else {
130 /* explicit CM SERVICE ACCEPT */
131 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
Harald Weltea49e36e2018-01-21 19:29:33 +0100132 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100133}
134
135/* build a PDU_ML3_MS_NW containing a Location Update by IMSI */
136function f_build_lu_imsi(hexstring imsi) return PDU_ML3_MS_NW
137{
138 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(imsi));
139 return f_build_lu(mi);
140}
Harald Welteba7b6d92018-01-23 21:32:34 +0100141function f_build_lu_imei(hexstring imei) return PDU_ML3_MS_NW
142{
143 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(imei));
144 return f_build_lu(mi);
145}
146function f_build_lu_tmsi(OCT4 tmsi) return PDU_ML3_MS_NW
147{
148 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV(tmsi));
149 return f_build_lu(mi);
150}
Harald Weltea49e36e2018-01-21 19:29:33 +0100151private function f_build_lu(MobileIdentityLV mi) return PDU_ML3_MS_NW
152{
153 var LocationAreaIdentification_V old_lai := { '62F220'O, '9999'O };
154 var PDU_ML3_MS_NW l3_info := valueof(ts_ML3_MO_LU_Req(valueof(ts_ML3_IE_LuType_Attach),
155 old_lai, mi, valueof(ts_CM1)));
156 return l3_info;
157}
158
Harald Weltecf66d5a2018-01-23 19:24:28 +0100159private function f_rnd_oct(integer len) return octetstring {
160 var integer i;
161 var octetstring res;
162 for (i := 0; i < len; i := i + 1) {
163 res[i] := int2oct(float2int(rnd()*256.0), 1);
164 }
165 return res;
166}
167
168function f_gen_auth_vec_2g() return AuthVector {
169 var AuthVector vec;
170 vec.rand := f_rnd_oct(16);
171 vec.sres := f_rnd_oct(4);
172 vec.kc := f_rnd_oct(8);
173 return vec;
174}
175
Harald Welte148a7082018-01-26 18:56:43 +0100176
177function f_mm_common(boolean expect_auth, boolean expect_ciph) runs on BSC_ConnHdlr
178{
179 if (expect_auth) {
180 g_pars.vec := f_gen_auth_vec_2g();
181 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
182 g_pars.vec.sres,
183 g_pars.vec.kc));
184 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
185 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
186
187 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(g_pars.vec.rand)));
188 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G(g_pars.vec.sres)));
189 }
190
191 if (expect_ciph) {
192 BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc));
193 BSSAP.send(ts_BSSMAP_CipherModeCompl('02'O));
194 }
195}
196
Harald Welte16114282018-01-24 22:41:21 +0100197function f_perform_lu(boolean expect_auth, boolean expect_tmsi, boolean send_early_cm,
198 boolean expect_ciph := false)
Harald Weltea49e36e2018-01-21 19:29:33 +0100199runs on BSC_ConnHdlr {
200 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
201 var PDU_DTAP_MT dtap_mt;
202
203 /* tell GSUP dispatcher to send this IMSI to us */
204 f_create_gsup_expect(hex2str(g_pars.imsi));
205
206 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
207 f_bssap_compl_l3(l3_lu);
208
Harald Welte8a121b32018-01-22 03:00:41 +0100209 if (send_early_cm) {
210 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
211 }
Harald Welte5c2622c2018-01-21 20:45:20 +0100212
Harald Welte148a7082018-01-26 18:56:43 +0100213 f_mm_common(expect_auth, expect_ciph);
Harald Welte16114282018-01-24 22:41:21 +0100214
Harald Weltea49e36e2018-01-21 19:29:33 +0100215 /* Expect MSC to perform LU with HLR */
216 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
217 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
218 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
219 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
220
221 alt {
222 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {
223 var PDU_ML3_LocationUpdateAccept lu_acc := dtap_mt.dtap.msgs.mm.locationUpdateAccept;
224 if (expect_tmsi) {
225 if (not ispresent(lu_acc.mobileIdentityTLV) or
226 not ischosen(lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi)) {
227 setverdict(fail, "Expected TMSI but no TMSI was allocated");
228 self.stop;
229 } else {
Harald Welte256571e2018-01-24 18:47:19 +0100230 g_pars.tmsi := lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets;
Harald Weltea49e36e2018-01-21 19:29:33 +0100231 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
232 }
233 } else {
234 if (ispresent(lu_acc.mobileIdentityTLV) and
235 ischosen(lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi)) {
236 setverdict(fail, "Expected no TMSI but TMSI was allocated");
237 self.stop;
238 }
239 }
240 }
241 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
242 setverdict(fail, "Expected LU ACK, but received LU REJ");
243 self.stop;
244 }
245 }
246 /* FIXME: there could be pending SMS or other common procedures by the MSC, let's ignore them */
247 BSSAP.receive(tr_BSSMAP_ClearCommand);
248 BSSAP.send(ts_BSSMAP_ClearComplete);
249 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
250 setverdict(pass);
251}
252
253function f_foo() runs on BSC_ConnHdlr{
254 /* SCCP CC handled by BSSMAP_Emulation_CT.main() */
255 /* Expect auth, if enabled */
256
257 /* TODO: ISD */
258 /* Expect encr, if enabled */
259 /* Expect encr, if enabled */
260 /* Expect ASS CMD, if chan_type != requested */
261 /* Send ASS CMPL in successful case */
262
263 /* Expect AoIP port/ip information for RTP stream */
264 /* Expect MSC-originated MGCP to our simulated MGW */
265 /* Verify Counters via CTRL */
266 /* re-configure MSC behaviour via VTY */
267}
268
Harald Welteb71901a2018-01-26 19:16:05 +0100269/* parameters related to a (MO?) voice call */
270type record CallParameters {
271 boolean expect_auth, /* do we expect AUTHENTICATE from network */
272 boolean expect_ciph, /* do we expect CIPHER MODE from network */
273
274 /* CC related parameters */
275 hexstring called_party, /* whom are we calling */
276 integer transaction_id optional, /* which TS 04.08 CC transaction ID to use */
277 BearerCapability_TLV bearer_cap, /* which bearer capabilities to claim */
278
279 /* MNCC related parameters */
280 uint32_t mncc_callref optional, /* call reference on the MNCC side */
281 MNCC_bearer_cap mncc_bearer_cap optional, /* MNCC-side bearer capabilities */
282
283 /* RTP related parameters */
284 HostName bss_rtp_ip optional, /* BSS Side RTP IP */
285 PortNumber bss_rtp_port optional, /* BSS Side RTP Port */
286 HostName mss_rtp_ip optional, /* MSS Side RTP IP */
287 PortNumber mss_rtp_port optional, /* MSS Side RTP Port */
Harald Welte4017d552018-01-26 21:40:05 +0100288 HostName mgw_rtp_ip_bss, /* BSS-facing MGW RTP IP */
289 PortNumber mgw_rtp_port_bss, /* BSS-facing MGW RTP Port */
290 HostName mgw_rtp_ip_mss, /* MSS-facing MGW RTP IP */
291 PortNumber mgw_rtp_port_mss, /* MSS-facing MGW RTP Port */
Harald Welteb71901a2018-01-26 19:16:05 +0100292 uint7_t rtp_payload_type, /* dynamic RTP payload type */
293 charstring rtp_sdp_format, /* AMR/8000 or the like */
294
295 MgcpCallId mgcp_call_id optional, /* MGCP Call ID; CallAgent allocated */
296 MgcpEndpoint mgcp_ep optional /* MGCP Endpoint, CallAgent or MGW allocated */,
297 MgcpConnectionId mgcp_connection_id_bss, /* MGCP Connection ID BSS Side */
298 MgcpConnectionId mgcp_connection_id_mss /* MGCP Connection ID MSS Side */
299}
300
301template (value) CallParameters t_CallParams(hexstring called, integer tid) := {
302 expect_auth := false,
303 expect_ciph := false,
304 called_party := called,
305 transaction_id := tid,
306 bearer_cap := valueof(ts_Bcap_voice),
307 mncc_callref := omit,
308 mncc_bearer_cap := valueof(ts_MNCC_bcap_voice),
Harald Welte4017d552018-01-26 21:40:05 +0100309 bss_rtp_ip := "9.8.7.6",
310 bss_rtp_port := 9000,
Harald Welteb71901a2018-01-26 19:16:05 +0100311 mss_rtp_ip := omit,
312 mss_rtp_port := omit,
Harald Welte4017d552018-01-26 21:40:05 +0100313 mgw_rtp_ip_bss := "1.1.1.1",
314 mgw_rtp_port_bss := 10000,
315 mgw_rtp_ip_mss := "1.1.1.1",
316 mgw_rtp_port_mss := 11000,
Harald Welteb71901a2018-01-26 19:16:05 +0100317 rtp_payload_type := 98,
318 rtp_sdp_format := "AMR/8000",
319 mgcp_call_id := omit,
320 mgcp_ep := omit,
321 mgcp_connection_id_bss := '0'H,//
322 mgcp_connection_id_mss := '0'H //
323};
324
325
326function f_mo_call(inout CallParameters cpars)
327runs on BSC_ConnHdlr {
328
329 var MobileIdentityLV mi;
330 var MNCC_PDU mncc;
331 var MgcpCommand mgcp_cmd;
332
333 /* If we have a TMSI, use TMSI instead of IMSI */
334 if (ispresent(g_pars.tmsi)) {
335 mi := valueof(ts_MI_TMSI_LV(g_pars.tmsi));
336 } else {
337 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
338 }
339 f_establish_fully(mi, cpars.expect_auth, cpars.expect_ciph);
340
341 /* Create MNCC and MGCP expect */
342 f_create_mncc_expect(hex2str(cpars.called_party));
343 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
344
345 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
346 interleave {
347 [] MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc {
348 cpars.mncc_callref := mncc.u.signal.callref;
349 /* Call Proceeding */
350 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
351 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
352 };
Harald Welte4017d552018-01-26 21:40:05 +0100353 /* First MGCP CRCX (for BSS/RAN side) */
Harald Welteb71901a2018-01-26 19:16:05 +0100354 [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
355 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
356 /* TODO: dynamic EP allocation case */
357 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte4017d552018-01-26 21:40:05 +0100358 var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_bss, cpars.mgw_rtp_ip_bss,
Harald Welteb71901a2018-01-26 19:16:05 +0100359 hex2str(cpars.mgcp_call_id), "42",
Harald Welte4017d552018-01-26 21:40:05 +0100360 cpars.mgw_rtp_port_bss,
Harald Welteb71901a2018-01-26 19:16:05 +0100361 { int2str(cpars.rtp_payload_type) },
362 { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
363 cpars.rtp_sdp_format)),
364 valueof(ts_SDP_ptime(20)) }));
365 MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, sdp));
366 }
367 }
Harald Welte4017d552018-01-26 21:40:05 +0100368 /* Second MGCP CRCX (this time for MSS/CN side) */
369 MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
370 var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
371 hex2str(cpars.mgcp_call_id), "42",
372 cpars.mgw_rtp_port_mss,
373 { int2str(cpars.rtp_payload_type) },
374 { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
375 cpars.rtp_sdp_format)),
376 valueof(ts_SDP_ptime(20)) }));
377 MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
378 }
Harald Welteb71901a2018-01-26 19:16:05 +0100379
380 /* Alerting */
381 MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
Harald Welteb71901a2018-01-26 19:16:05 +0100382
Harald Welte4017d552018-01-26 21:40:05 +0100383 var BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
384 valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_rtp_ip_bss),cpars.mgw_rtp_port_bss));
385 interleave {
386 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id))) {}
387 /* expect AoIP IP/Port to match what we returned in CRCX_ACK above */
388 [] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) {
Harald Welteb71901a2018-01-26 19:16:05 +0100389 var BSSMAP_IE_AoIP_TransportLayerAddress tla;
390 tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
391 BSSAP.send(ts_BSSMAP_AssignmentComplete(omit, tla));
392 }
393 }
394
Harald Welte4017d552018-01-26 21:40:05 +0100395 /* Answer. MNCC_SETUP_RSP -> CONNECT to MS; CONNECT_ACK from MS */
396 MNCC.send(ts_MNCC_SETUP_rsp(cpars.mncc_callref));
397 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CONNECT(cpars.transaction_id)));
398 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT_ACK(cpars.transaction_id)));
Harald Welteb71901a2018-01-26 19:16:05 +0100399
400 f_sleep(3.0);
401
402 /* Hangup by "B" side */
403 MNCC.send(ts_MNCC_DISC_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
404 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
405
406 /* Release of call */
407 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(42))));
408 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
409 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
410
411 /* clearing of radio channel */
412 interleave {
413 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
414 BSSAP.send(ts_BSSMAP_ClearComplete);
415 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
416 }
417 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
418 /* TODO: For one or all connections on EP? */
419 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
420 f_create_mgcp_delete_ep(cpars.mgcp_ep);
421 }
422 }
423 setverdict(pass);
424}
Harald Weltea49e36e2018-01-21 19:29:33 +0100425
426
427
428
429}
430
431