blob: 1833a893daf820cdf3ccbd330ea5be877d2b18d0 [file] [log] [blame]
Harald Welted86cdc62017-11-22 00:45:07 +01001module IPA_Emulation {
2
Harald Weltebdb63702017-12-09 01:15:44 +01003/* This module implements the IPA multiplex protocol on top of TCP, using the IPL4asp
4 * test-port as provider. It implements both client and server roles, as well was the CCM
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005 * handshake for establishing the identity of the client to the server.
Harald Welte35bb7162018-01-03 21:07:52 +01006 *
7 * It already knows certain well-known sub-protocols such as A-bis RSL, MGCP and SCCP and
8 * GSUP. IT hence transcodes messages so the user can work with abstract data types rather
9 * than binary messages. It handles multiple packets inside one TCP segment.
10 *
Harald Welte34b5a952019-05-27 11:54:11 +020011 * (C) 2017-2019 by Harald Welte <laforge@gnumonks.org>
12 * contributions by sysmocom - s.f.m.c. GmbH
Harald Welte35bb7162018-01-03 21:07:52 +010013 * All rights reserved.
14 *
15 * Released under the terms of GNU General Public License, Version 2 or
16 * (at your option) any later version.
Harald Welte34b5a952019-05-27 11:54:11 +020017 *
18 * SPDX-License-Identifier: GPL-2.0-or-later
Harald Welte35bb7162018-01-03 21:07:52 +010019 */
Harald Weltebdb63702017-12-09 01:15:44 +010020
Harald Welted86cdc62017-11-22 00:45:07 +010021import from IPA_Types all;
22import from IPA_CodecPort all;
23import from IPA_CodecPort_CtrlFunct all;
24import from IPL4asp_Types all;
Harald Welte12188832017-11-29 11:47:13 +010025import from IPL4asp_PortType all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010026import from Socket_API_Definitions all;
Harald Welted86cdc62017-11-22 00:45:07 +010027
Harald Weltedf277252018-02-20 15:49:30 +010028#ifdef IPA_EMULATION_SCCP
29import from MTP3asp_Types all;
30import from MTP3asp_PortType all;
31#endif
32
33#ifdef IPA_EMULATION_RSL
34import from RSL_Types all;
35#endif
36
Harald Weltec6826662019-02-06 22:26:46 +010037#ifdef IPA_EMULATION_OML
38import from AbisOML_Types all;
39#endif
40
Harald Weltedf277252018-02-20 15:49:30 +010041#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +010042import from MGCP_Types all;
Harald Weltedf277252018-02-20 15:49:30 +010043#endif
44
45#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +010046import from GSUP_Types all;
Harald Weltedf277252018-02-20 15:49:30 +010047#endif
Harald Weltec82eef42017-11-24 20:40:12 +010048
Harald Welte7460a722018-10-10 12:28:27 +020049#ifdef IPA_EMULATION_RSPRO
50import from RSPRO all;
51import from RSPRO_Types all;
52#endif
53
Harald Welte3286eb32019-08-18 19:36:10 +020054#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +010055import from Osmocom_CTRL_Types all;
Harald Welte3286eb32019-08-18 19:36:10 +020056#endif
Harald Weltea76c4bb2017-12-09 02:06:07 +010057
Harald Welted86cdc62017-11-22 00:45:07 +010058modulepar {
Harald Welte92632e12017-11-25 02:31:20 +010059 /* Use Osmocom extended IPA mux header */
60 boolean mp_ipa_mgcp_uses_osmo_ext := true;
Harald Welted86cdc62017-11-22 00:45:07 +010061}
Harald Welted86cdc62017-11-22 00:45:07 +010062
Harald Welteb3414b22017-11-23 18:22:10 +010063type enumerated IpaMode {
64 IPA_MODE_CLIENT,
65 IPA_MODE_SERVER
66}
67
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +020068type enumerated IpaInitBehavior {
69 IPA_INIT_SEND_IPA_ID_GET,
70 IPA_INIT_SEND_IPA_ID_ACK
71}
72
Harald Weltec76f29f2017-11-22 12:46:46 +010073type record ASP_IPA_Unitdata {
74 IpaStreamId streamId,
Harald Weltec82eef42017-11-24 20:40:12 +010075 IpaExtStreamId streamIdExt optional,
Harald Weltec76f29f2017-11-22 12:46:46 +010076 octetstring payload
77}
78
Vadim Yanitskiy8701b272020-05-18 20:17:25 +070079type enumerated ASP_IPA_EventType {
Harald Welte0d846a72017-12-07 17:58:28 +010080 ASP_IPA_EVENT_DOWN,
81 ASP_IPA_EVENT_UP,
82 ASP_IPA_EVENT_ID_ACK
83}
84
Harald Weltebdb63702017-12-09 01:15:44 +010085/* an event indicating us whether or not a connection is physically up or down,
86 * and whether we have received an ID_ACK */
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +070087type record ASP_IPA_Event {
88 ASP_IPA_EventType ev_type,
89 integer conn_id
Harald Welte0d846a72017-12-07 17:58:28 +010090}
91
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +070092template (value) ASP_IPA_Event ts_ASP_IPA_EV(ASP_IPA_EventType ev_type, integer conn_id) := {
93 ev_type := ev_type,
94 conn_id := conn_id
Vadim Yanitskiy61564be2020-05-18 20:44:14 +070095}
96
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +070097template ASP_IPA_Event tr_ASP_IPA_EV(template ASP_IPA_EventType ev_type,
98 template integer conn_id := ?) := {
99 ev_type := ev_type,
100 conn_id := conn_id
Harald Welte0d846a72017-12-07 17:58:28 +0100101}
102
Harald Welte1dd8f372017-11-25 02:25:27 +0100103template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
104 template IpaExtStreamId esid := omit) := {
105 streamId := sid,
106 streamIdExt := esid,
107 payload := pl
108}
109
Harald Weltedf277252018-02-20 15:49:30 +0100110#ifdef IPA_EMULATION_RSL
Harald Weltebdb63702017-12-09 01:15:44 +0100111/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +0100112type record ASP_RSL_Unitdata {
113 IpaStreamId streamId,
114 RSL_Message rsl
115};
116
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700117template (value) ASP_RSL_Unitdata ts_ASP_RSL_UD(template (value) RSL_Message rsl,
118 IpaStreamId sid := IPAC_PROTO_RSL_TRX0) := {
Harald Welte0d846a72017-12-07 17:58:28 +0100119 streamId := sid,
Vadim Yanitskiy6b4856d2020-05-25 21:23:46 +0700120 rsl := rsl
Harald Welte0d846a72017-12-07 17:58:28 +0100121}
122
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700123template ASP_RSL_Unitdata tr_ASP_RSL_UD(template (present) RSL_Message rsl,
124 template IpaStreamId sid := IPAC_PROTO_RSL_TRX0) := {
Harald Welte7ae019e2017-12-09 00:54:15 +0100125 streamId := sid,
126 rsl := rsl
127}
128
Harald Welte0d846a72017-12-07 17:58:28 +0100129template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
130 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
Harald Weltedf277252018-02-20 15:49:30 +0100131#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100132
Harald Weltec6826662019-02-06 22:26:46 +0100133
Harald Weltebdb63702017-12-09 01:15:44 +0100134/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +0100135type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +0100136 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +0100137} with { extension "internal" }
138
Harald Weltedf277252018-02-20 15:49:30 +0100139#ifdef IPA_EMULATION_MGCP
Harald Weltebdb63702017-12-09 01:15:44 +0100140/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +0100141type port IPA_MGCP_PT message {
142 inout MgcpCommand, MgcpResponse;
143} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100144#endif
Harald Weltec82eef42017-11-24 20:40:12 +0100145
Harald Weltedf277252018-02-20 15:49:30 +0100146#ifdef IPA_EMULATION_RSL
Harald Weltebdb63702017-12-09 01:15:44 +0100147/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +0100148type port IPA_RSL_PT message {
149 inout ASP_RSL_Unitdata, ASP_IPA_Event;
150} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100151#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100152
Harald Weltec6826662019-02-06 22:26:46 +0100153#ifdef IPA_EMULATION_OML
154/* Client port for A-bis OML inside IPA */
155type port IPA_OML_PT message {
156 inout OML_PDU, octetstring, ASP_IPA_Event;
157} with { extension "internal" }
158#endif
159
Harald Welte3286eb32019-08-18 19:36:10 +0200160#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100161/* Client port for CTRL inside IPA */
162type port IPA_CTRL_PT message {
163 inout CtrlMessage, ASP_IPA_Event;
164} with { extension "internal" }
Harald Welte3286eb32019-08-18 19:36:10 +0200165#endif
Harald Weltea76c4bb2017-12-09 02:06:07 +0100166
Harald Weltedf277252018-02-20 15:49:30 +0100167#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100168/* Client port for CTRL inside IPA */
169type port IPA_GSUP_PT message {
170 inout GSUP_PDU, ASP_IPA_Event;
171} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100172#endif
Harald Weltedf327232017-12-28 22:51:51 +0100173
Harald Welte7460a722018-10-10 12:28:27 +0200174#ifdef IPA_EMULATION_RSPRO
175type port IPA_RSPRO_PT message {
176 inout RsproPDU, ASP_IPA_Event;
177} with { extension "internal" }
178#endif
179
180
181
Harald Weltedf327232017-12-28 22:51:51 +0100182
Harald Welted86cdc62017-11-22 00:45:07 +0100183type component IPA_Emulation_CT {
184 /* down-facing port to IPA codec port */
185 port IPA_CODEC_PT IPA_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100186#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100187 /* up-facing port to SCCP */
188 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100189#endif
190#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100191 /* up-facing port for MGCP */
192 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100193#endif
194#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100195 /* up-facing port for RSL */
196 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100197#endif
Harald Weltec6826662019-02-06 22:26:46 +0100198#ifdef IPA_EMULATION_OML
199 /* up-facing port for OML */
200 port IPA_OML_PT IPA_OML_PORT;
201#endif
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200202#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100203 /* up-facing port for CTRL */
204 port IPA_CTRL_PT IPA_CTRL_PORT;
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200205#endif
Harald Weltedf277252018-02-20 15:49:30 +0100206#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100207 /* up-facing port for GSUP */
208 port IPA_GSUP_PT IPA_GSUP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100209#endif
Harald Welte7460a722018-10-10 12:28:27 +0200210#ifdef IPA_EMULATION_RSPRO
211 /* up-facing port for RSPRO */
212 port IPA_RSPRO_PT IPA_RSPRO_PORT;
213#endif
Harald Weltedf327232017-12-28 22:51:51 +0100214
Harald Weltec76f29f2017-11-22 12:46:46 +0100215 /* up-facing port for other streams */
216 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100217
218 var boolean g_initialized := false;
Harald Weltec82eef42017-11-24 20:40:12 +0100219 /* Are we a BSC/MGW (truel) or MSC (false) */
220 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100221
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700222 /* Connection identifier of the client / server itself */
223 var IPL4asp_Types.ConnectionId g_self_conn_id := -1;
224 /* Connection identifier of the last connected client (server only) */
225 var IPL4asp_Types.ConnectionId g_last_conn_id := -1;
226
Harald Welteb3414b22017-11-23 18:22:10 +0100227 var IpaMode g_mode;
Harald Welte2d86aff2018-04-17 11:23:04 +0200228 var boolean g_ccm_enabled;
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200229 var IpaInitBehavior g_init_behavior;
Harald Weltee09921f2017-12-07 17:49:00 +0100230 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100231}
232
Harald Weltee21096d2017-12-04 20:45:12 +0100233type record IPA_CCM_Parameters {
234 charstring ser_nr optional,
235 charstring name optional,
236 charstring location1 optional,
237 charstring location2 optional,
238 charstring equip_version optional,
239 charstring sw_version optional,
240 charstring ip_addr optional,
241 charstring mac_addr optional,
242 charstring unit_id optional,
243 charstring osmo_rand optional
244}
245
Harald Weltee09921f2017-12-07 17:49:00 +0100246const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
247 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100248 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100249 location1 := "",
250 location2 := "",
251 equip_version := "",
252 sw_version := "",
253 ip_addr := "",
254 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100255 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100256 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100257};
258
Harald Weltebdb63702017-12-09 01:15:44 +0100259/* Function to use to connect as client to a remote IPA Server */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100260function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
261 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100262 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100263 var IPL4asp_Types.Result res;
Harald Welted86cdc62017-11-22 00:45:07 +0100264 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
265 local_host, local_port, 0, { tcp:={} });
Harald Welte9220f632018-05-23 20:27:02 +0200266 if (not ispresent(res.connId)) {
Stefan Sperling6a90be42018-08-31 15:05:39 +0200267 setverdict(fail, "Could not connect IPA socket from ", local_host, " port ", local_port,
268 " to ", remote_host, " port ", remote_port, "; check your configuration");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200269 mtc.stop;
Harald Welte9220f632018-05-23 20:27:02 +0200270 }
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700271 g_self_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100272 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100273 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100274}
275
Harald Weltebdb63702017-12-09 01:15:44 +0100276/* Function to use to bind to a local port as IPA server, accepting remote clients */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100277function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100278 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100279 var IPL4asp_Types.Result res;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +0200280 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
Harald Welteb3414b22017-11-23 18:22:10 +0100281 local_host, local_port, { tcp:={} });
Harald Welte9220f632018-05-23 20:27:02 +0200282 if (not ispresent(res.connId)) {
Maxb7aae8b2019-03-11 15:22:02 +0100283 setverdict(fail, "Could not listen IPA socket ", local_host, ":", local_port, ", check your configuration");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200284 mtc.stop;
Harald Welte9220f632018-05-23 20:27:02 +0200285 }
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700286 g_self_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100287 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100288 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100289}
290
Harald Weltedf277252018-02-20 15:49:30 +0100291#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100292template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
293 sio := { '10'B, '00'B, '0011'B },
294 opc := opc,
295 dpc := 0,
296 sls := 0,
297 data := data
298}
Harald Weltedf277252018-02-20 15:49:30 +0100299#endif
Harald Welted86cdc62017-11-22 00:45:07 +0100300
301
302private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
303 len := 0, /* overwritten by codec */
304 tag := tag,
Harald Welte95686e02018-08-02 15:05:43 +0200305 data := char2oct(payload) & '00'O
Harald Welted86cdc62017-11-22 00:45:07 +0100306}
307
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700308private function f_send_IPA_EVT(template (value) ASP_IPA_Event evt) runs on IPA_Emulation_CT {
Harald Welte2e32e432018-05-24 20:00:00 +0200309 if (IPA_SP_PORT.checkstate("Connected")) {
310 IPA_SP_PORT.send(evt);
311 }
Harald Weltedf277252018-02-20 15:49:30 +0100312#ifdef IPA_EMULATION_RSL
Harald Welte5819b552017-12-09 02:55:46 +0100313 if (IPA_RSL_PORT.checkstate("Connected")) {
314 IPA_RSL_PORT.send(evt);
315 }
Harald Weltedf277252018-02-20 15:49:30 +0100316#endif
Harald Weltec6826662019-02-06 22:26:46 +0100317#ifdef IPA_EMULATION_OML
318 if (IPA_OML_PORT.checkstate("Connected")) {
319 IPA_OML_PORT.send(evt);
320 }
321#endif
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200322#ifdef IPA_EMULATION_CTRL
Harald Welte5819b552017-12-09 02:55:46 +0100323 if (IPA_CTRL_PORT.checkstate("Connected")) {
324 IPA_CTRL_PORT.send(evt);
325 }
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200326#endif
Harald Weltedf277252018-02-20 15:49:30 +0100327#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100328 if (IPA_GSUP_PORT.checkstate("Connected")) {
329 IPA_GSUP_PORT.send(evt);
330 }
Harald Weltedf277252018-02-20 15:49:30 +0100331#endif
Harald Welte7460a722018-10-10 12:28:27 +0200332#ifdef IPA_EMULATION_RSPRO
333 if (IPA_RSPRO_PORT.checkstate("Connected")) {
334 IPA_RSPRO_PORT.send(evt);
335 }
336#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100337 /* FIXME: to other ports */
338}
339
Harald Welted86cdc62017-11-22 00:45:07 +0100340/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100341private function f_ccm_make_id_resp(PDU_IPA_CCM get) runs on IPA_Emulation_CT return PDU_IPA_CCM {
Harald Welted86cdc62017-11-22 00:45:07 +0100342 var integer i;
343 var PDU_IPA_CCM resp := {
344 msg_type := IPAC_MSGT_ID_RESP,
345 u := {
346 resp := {}
347 }
348 }
349
350 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
351 var IpaCcmIdTag tag := get.u.get[i].tag;
352 var charstring foo;
353 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100354 case (IPAC_IDTAG_SERNR) {
355 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100356 }
357 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100358 foo := g_ccm_pars.name;
359 }
360 case (IPAC_IDTAG_LOCATION1) {
361 foo := g_ccm_pars.location1;
362 }
363 case (IPAC_IDTAG_LOCATION2) {
364 foo := g_ccm_pars.location2;
365 }
366 case (IPAC_IDTAG_EQUIPVERS) {
367 foo := g_ccm_pars.equip_version;
368 }
369 case (IPAC_IDTAG_SWVERSION) {
370 foo := g_ccm_pars.sw_version;
371 }
372 case (IPAC_IDTAG_IPADDR) {
373 foo := g_ccm_pars.ip_addr;
374 }
375 case (IPAC_IDTAG_MACADDR) {
376 foo := g_ccm_pars.mac_addr;
377 }
Vadim Yanitskiy44f0c482020-05-24 20:49:29 +0700378 case (IPAC_IDTAG_UNITID) {
Harald Weltee21096d2017-12-04 20:45:12 +0100379 foo := g_ccm_pars.unit_id;
380 }
381 case (IPAC_IDTAG_OSMO_RAND) {
382 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100383 }
384 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100385 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100386 }
387 }
388 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
389 }
390
391 return resp;
392}
393
394/* transmit IPA CCM message */
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700395private function f_ccm_tx(PDU_IPA_CCM ccm, IPL4asp_Types.ConnectionId conn_id)
396runs on IPA_Emulation_CT {
397 var IPA_Send ipa_tx := valueof(t_IPA_Send(conn_id, IPAC_PROTO_CCM, enc_PDU_IPA_CCM(ccm)));
Harald Welted86cdc62017-11-22 00:45:07 +0100398 log("CCM Tx:", ccm);
399 IPA_PORT.send(ipa_tx);
400}
401
402template PDU_IPA_CCM ts_IPA_PONG := {
403 msg_type := IPAC_MSGT_PONG,
404 u := omit
405}
406
407template PDU_IPA_CCM ts_IPA_ACK := {
408 msg_type := IPAC_MSGT_ID_ACK,
409 u := omit
410}
411
Harald Welteb3414b22017-11-23 18:22:10 +0100412template PDU_IPA_CCM ts_IPA_ID_GET := {
413 msg_type := IPAC_MSGT_ID_GET,
414 u := {
415 get := {
416 { 1, IPAC_IDTAG_UNITNAME }
417 }
418 }
419}
420
Harald Welted86cdc62017-11-22 00:45:07 +0100421/* receive IPA CCM message */
Harald Welte2d86aff2018-04-17 11:23:04 +0200422private function f_ccm_rx_client(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100423 select (ccm.msg_type) {
424 case (IPAC_MSGT_PING) {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700425 f_ccm_tx(valueof(ts_IPA_PONG), g_self_conn_id);
Harald Welted86cdc62017-11-22 00:45:07 +0100426 }
427 case (IPAC_MSGT_ID_ACK) {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700428 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK, g_self_conn_id));
Harald Welted86cdc62017-11-22 00:45:07 +0100429 }
430 case (IPAC_MSGT_ID_GET) {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700431 f_ccm_tx(f_ccm_make_id_resp(ccm), g_self_conn_id);
Harald Welted86cdc62017-11-22 00:45:07 +0100432 }
Harald Welte2d86aff2018-04-17 11:23:04 +0200433 case else {
434 log("Unknown/unsupported IPA CCM message type", ccm);
435 }
436 }
437}
438
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700439private function f_ccm_rx_server(PDU_IPA_CCM ccm, IPL4asp_Types.ConnectionId conn_id)
440runs on IPA_Emulation_CT {
Harald Welte2d86aff2018-04-17 11:23:04 +0200441 select (ccm.msg_type) {
442 case (IPAC_MSGT_PING) {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700443 f_ccm_tx(valueof(ts_IPA_PONG), conn_id);
Harald Welte2d86aff2018-04-17 11:23:04 +0200444 }
445 case (IPAC_MSGT_ID_ACK) {
446 /* the IPA server should at some point receive an ID_ACK from the client,
447 * in case of RSL/OML from nanoBTS, this is actually the first message after
448 * the TCP connection is established. Other implementations may differ.
449 * We currently ignore it completely - but actually we should make sure that
450 * one ID_ACK is received by the server at some point */
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700451 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK, conn_id));
Harald Welte2d86aff2018-04-17 11:23:04 +0200452 }
Harald Welte3bc387f2018-02-21 12:18:46 +0100453 case (IPAC_MSGT_ID_RESP) {
454 log("IPA ID RESP: ", ccm.u.resp);
Harald Welte2d86aff2018-04-17 11:23:04 +0200455 /* acknowledge any identity that the client may have sent */
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700456 f_ccm_tx(valueof(ts_IPA_ACK), conn_id);
Harald Welte3bc387f2018-02-21 12:18:46 +0100457 }
Harald Welted86cdc62017-11-22 00:45:07 +0100458 case else {
459 log("Unknown/unsupported IPA CCM message type", ccm);
460 }
461 }
462}
463
Harald Weltec76f29f2017-11-22 12:46:46 +0100464private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
465 var ASP_IPA_Unitdata ret := {
466 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100467 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100468 payload := ipa_rx.msg
469 }
470 return ret;
471}
472
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100473private function f_from_asp(IPL4asp_Types.ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100474 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
475 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100476 return ret;
477}
Harald Welted86cdc62017-11-22 00:45:07 +0100478
Harald Weltedf277252018-02-20 15:49:30 +0100479#ifdef IPA_EMULATION_RSL
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100480private function f_from_rsl(IPL4asp_Types.ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
Harald Welte0d846a72017-12-07 17:58:28 +0100481 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
482 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
483 return ret;
484}
Harald Weltedf277252018-02-20 15:49:30 +0100485#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100486
Harald Weltec6826662019-02-06 22:26:46 +0100487#ifdef IPA_EMULATION_OML
488private function f_from_oml(IPL4asp_Types.ConnectionId connId, OML_PDU oml_tx) return IPA_Send {
489 var octetstring payload := enc_OML_PDU(oml_tx);
490 var IPA_Send ret := valueof(t_IPA_Send(connId, IPAC_PROTO_OML, payload));
491 return ret;
492}
493#endif
494
Harald Weltebdb63702017-12-09 01:15:44 +0100495/* main function to use for a client-side IPA implementation */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100496function main_client(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
497 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Welte2d86aff2018-04-17 11:23:04 +0200498 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars,
499 boolean ccm_enabled := true) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100500 g_mode := IPA_MODE_CLIENT;
Harald Welte2d86aff2018-04-17 11:23:04 +0200501 g_ccm_enabled := ccm_enabled;
Harald Weltee09921f2017-12-07 17:49:00 +0100502 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welte2d86aff2018-04-17 11:23:04 +0200503 if (g_ccm_enabled) {
504 /* we're a client: Send ID_ACK immediately after connect */
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700505 f_ccm_tx(valueof(ts_IPA_ACK), g_self_conn_id);
Harald Welte2d86aff2018-04-17 11:23:04 +0200506 }
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700507 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_UP, g_self_conn_id));
Harald Welteb3414b22017-11-23 18:22:10 +0100508 ScanEvents();
509}
510
Harald Weltebdb63702017-12-09 01:15:44 +0100511/* main function to use for a server-side IPA implementation */
Harald Welte2d86aff2018-04-17 11:23:04 +0200512function main_server(charstring local_host, IPL4asp_Types.PortNumber local_port,
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200513 boolean ccm_enabled := true,
514 IpaInitBehavior init_behavior := IPA_INIT_SEND_IPA_ID_GET)
515runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100516 g_mode := IPA_MODE_SERVER;
Harald Welte2d86aff2018-04-17 11:23:04 +0200517 g_ccm_enabled := ccm_enabled;
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200518 g_init_behavior := init_behavior;
Harald Welteb3414b22017-11-23 18:22:10 +0100519 f_bind(local_host, local_port);
520 ScanEvents();
521}
522
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200523#ifdef IPA_EMULATION_CTRL
Harald Weltedf277252018-02-20 15:49:30 +0100524private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
525 var charstring msg_ch := oct2char(msg);
526 IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
527}
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200528#endif
Harald Weltedf277252018-02-20 15:49:30 +0100529
530#ifdef IPA_EMULATION_GSUP
531private function f_gsup_to_user(octetstring msg) runs on IPA_Emulation_CT {
532 var GSUP_PDU gsup := dec_GSUP_PDU(msg);
533 f_gsup_postprocess_decoded(gsup);
534 IPA_GSUP_PORT.send(gsup);
535}
536#endif
537
Harald Welte7460a722018-10-10 12:28:27 +0200538#ifdef IPA_EMULATION_RSPRO
539private function f_rspro_to_user(octetstring msg) runs on IPA_Emulation_CT {
540 var RsproPDU rspro := dec_RsproPDU(msg);
541 IPA_RSPRO_PORT.send(rspro);
542}
543#endif
544
Harald Weltedf277252018-02-20 15:49:30 +0100545#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100546private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
547 var charstring msg_ch := oct2char(msg);
548 if (g_is_bsc_mgw) {
549 log("============");
550 log(msg_ch);
551 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
552 } else {
553 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
554 }
555}
556
Harald Welte92632e12017-11-25 02:31:20 +0100557private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
558 if (mp_ipa_mgcp_uses_osmo_ext) {
559 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
560 } else {
561 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
562 }
563}
Harald Weltedf277252018-02-20 15:49:30 +0100564#endif
Harald Welte92632e12017-11-25 02:31:20 +0100565
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700566/* Resolve TCP/IP connection identifier depending on g_mode */
567private function f_ipa_conn_id() runs on IPA_Emulation_CT
568return IPL4asp_Types.ConnectionId {
569 var IPL4asp_Types.ConnectionId conn_id;
570
571 select (g_mode) {
572 case (IPA_MODE_CLIENT) { conn_id := g_self_conn_id; }
573 case (IPA_MODE_SERVER) { conn_id := g_last_conn_id; }
574 case else {
575 setverdict(fail, "Unknown mode");
576 mtc.stop;
577 }
578 }
579
580 if (conn_id == -1) { /* Just to be sure */
581 setverdict(fail, "Connection is not established");
582 mtc.stop;
583 }
584
585 return conn_id;
586}
587
Harald Weltebdb63702017-12-09 01:15:44 +0100588/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100589private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100590 var IPA_RecvFrom ipa_rx;
Harald Welteb3414b22017-11-23 18:22:10 +0100591 var ASP_Event asp_evt;
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100592 var Socket_API_Definitions.PortEvent port_evt;
Harald Weltedf277252018-02-20 15:49:30 +0100593 var octetstring payload;
Harald Weltedf277252018-02-20 15:49:30 +0100594 var ASP_IPA_Unitdata ipa_ud;
Harald Welte3286eb32019-08-18 19:36:10 +0200595#ifdef IPA_EMULATION_CTRL
596 var CtrlMessage ctrl_msg;
597#endif
Harald Weltedf277252018-02-20 15:49:30 +0100598#ifdef IPA_EMULATION_SCCP
599 var ASP_MTP3_TRANSFERreq mtp_req;
600#endif
601#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100602 var MgcpCommand mgcp_cmd;
603 var MgcpResponse mgcp_rsp;
Harald Weltedf277252018-02-20 15:49:30 +0100604#endif
605#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100606 var GSUP_PDU gsup_msg;
Harald Weltedf277252018-02-20 15:49:30 +0100607#endif
608#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100609 var ASP_RSL_Unitdata rsl;
Harald Weltedf277252018-02-20 15:49:30 +0100610#endif
Harald Weltec6826662019-02-06 22:26:46 +0100611#ifdef IPA_EMULATION_OML
612 var OML_PDU oml;
613#endif
Harald Welte7460a722018-10-10 12:28:27 +0200614#ifdef IPA_EMULATION_RSPRO
615 var RsproPDU rspro;
616#endif
Harald Welted86cdc62017-11-22 00:45:07 +0100617
Harald Welte3e6ad892017-12-12 14:39:46 +0100618 /* Set function for dissecting the binary */
619 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700620 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_self_conn_id, vl_f, {0, 2, 3, 1, 0});
Harald Welte3e6ad892017-12-12 14:39:46 +0100621
Harald Welted86cdc62017-11-22 00:45:07 +0100622 while (true) {
623 alt {
624 /* Received IPA -> up into SCCP stack */
Harald Welte2d86aff2018-04-17 11:23:04 +0200625 [g_ccm_enabled] IPA_PORT.receive(IPA_RecvFrom:{?,IPAC_PROTO_CCM,omit,?}) -> value ipa_rx {
626 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
627 log("CCM Rx:", ccm);
628 select (g_mode) {
629 case (IPA_MODE_CLIENT) {
630 f_ccm_rx_client(ccm);
631 }
632 case (IPA_MODE_SERVER) {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700633 f_ccm_rx_server(ccm, ipa_rx.connId);
Harald Welte2d86aff2018-04-17 11:23:04 +0200634 }
635 case else {
636 setverdict(fail, "Unknown mode");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200637 mtc.stop;
Harald Welte2d86aff2018-04-17 11:23:04 +0200638 }
Harald Weltedf277252018-02-20 15:49:30 +0100639 }
Harald Welte2d86aff2018-04-17 11:23:04 +0200640 }
641 [] IPA_PORT.receive(IPA_RecvFrom:?) -> value ipa_rx {
642 select (ipa_rx.streamId) {
Harald Weltedf277252018-02-20 15:49:30 +0100643#ifdef IPA_EMULATION_SCCP
644 case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100645 var ASP_MTP3_TRANSFERind mtp;
646 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
647 MTP3_SP_PORT.send(mtp);
Harald Weltedf277252018-02-20 15:49:30 +0100648 }
649#endif
650#ifdef IPA_EMULATION_MGCP
651 case (IPAC_PROTO_MGCP_OLD) {
Harald Weltec82eef42017-11-24 20:40:12 +0100652 f_mgcp_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100653 }
654#endif
655#ifdef IPA_EMULATION_RSL
656 case (t_IpaSidRSL) {
Harald Welte0d846a72017-12-07 17:58:28 +0100657 rsl := {
658 streamId := ipa_rx.streamId,
659 rsl := dec_RSL_Message(ipa_rx.msg)
660 };
661 IPA_RSL_PORT.send(rsl);
Harald Weltedf277252018-02-20 15:49:30 +0100662 }
663#endif
Harald Weltec6826662019-02-06 22:26:46 +0100664#ifdef IPA_EMULATION_OML
665 case (IPAC_PROTO_OML) {
666 oml := dec_OML_PDU(ipa_rx.msg)
667 IPA_OML_PORT.send(oml);
668 }
669#endif
Harald Weltedf277252018-02-20 15:49:30 +0100670 case (IPAC_PROTO_OSMO) {
Harald Weltec82eef42017-11-24 20:40:12 +0100671 select (ipa_rx.streamIdExt) {
Harald Weltedf277252018-02-20 15:49:30 +0100672#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100673 case (IPAC_PROTO_EXT_MGCP) {
674 f_mgcp_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100675 }
676#endif
Harald Welte3286eb32019-08-18 19:36:10 +0200677#ifdef IPA_EMULATION_CTRL
Harald Weltedf277252018-02-20 15:49:30 +0100678 case (IPAC_PROTO_EXT_CTRL) {
Harald Weltea76c4bb2017-12-09 02:06:07 +0100679 f_ctrl_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100680 }
Harald Welte3286eb32019-08-18 19:36:10 +0200681#endif
Harald Weltedf277252018-02-20 15:49:30 +0100682#ifdef IPA_EMULATION_GSUP
683 case (IPAC_PROTO_EXT_GSUP) {
Harald Weltedf327232017-12-28 22:51:51 +0100684 f_gsup_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100685 }
686#endif
Harald Welte7460a722018-10-10 12:28:27 +0200687#ifdef IPA_EMULATION_RSPRO
688 case (IPAC_PROTO_EXT_RSPRO) {
689 f_rspro_to_user(ipa_rx.msg);
690 }
691#endif
Harald Weltedf277252018-02-20 15:49:30 +0100692 case else {
Harald Weltec82eef42017-11-24 20:40:12 +0100693 IPA_SP_PORT.send(f_to_asp(ipa_rx));
694 }
Harald Welted86cdc62017-11-22 00:45:07 +0100695 }
Harald Weltedf277252018-02-20 15:49:30 +0100696 }
697 case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100698 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100699 }
700 }
701 }
702
Harald Welteb3414b22017-11-23 18:22:10 +0100703 /* server only */
704 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700705 g_last_conn_id := asp_evt.connOpened.connId;
706 log("Established a new IPA connection (conn_id=", g_last_conn_id, ")");
707
708 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_UP, g_last_conn_id));
Harald Welte2d86aff2018-04-17 11:23:04 +0200709 if (g_mode == IPA_MODE_SERVER and g_ccm_enabled) {
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200710 select (g_init_behavior) {
711 case (IPA_INIT_SEND_IPA_ID_GET) {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700712 f_ccm_tx(valueof(ts_IPA_ID_GET), g_last_conn_id);
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200713 }
714 case (IPA_INIT_SEND_IPA_ID_ACK) {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700715 f_ccm_tx(valueof(ts_IPA_ACK), g_last_conn_id);
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200716 }
717 }
Harald Welteb3414b22017-11-23 18:22:10 +0100718 }
719 }
720
721 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
722 log("IPA: Closed");
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700723 g_self_conn_id := -1;
724 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_DOWN, asp_evt.connClosed.connId));
Harald Welteb3414b22017-11-23 18:22:10 +0100725 self.stop;
726 }
727
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100728 [] IPA_PORT.receive(Socket_API_Definitions.PortEvent:{result:={errorCode:=ERROR_SOCKET, connId:=?, os_error_code:=?, os_error_text:=?}}) -> value port_evt {
729 log("PortEvent: ERROR_SOCKET: ", port_evt);
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700730 g_self_conn_id := -1;
731 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_DOWN, port_evt.result.connId));
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100732 self.stop;
733 }
734
Harald Weltedf277252018-02-20 15:49:30 +0100735#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100736 /* Received SCCP -> down into IPA */
737 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700738 var IPA_Send ipa_tx := valueof(t_IPA_Send(f_ipa_conn_id(), IPAC_PROTO_SCCP,
Harald Weltec82eef42017-11-24 20:40:12 +0100739 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100740 IPA_PORT.send(ipa_tx);
741 }
Harald Weltedf277252018-02-20 15:49:30 +0100742#endif
Harald Weltec76f29f2017-11-22 12:46:46 +0100743
Harald Weltedf277252018-02-20 15:49:30 +0100744#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100745 /* Received MGCP -> down into IPA */
746 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100747 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
748 ipa_ud := f_mgcp_to_ud(payload);
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700749 IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
Harald Weltec82eef42017-11-24 20:40:12 +0100750 }
751 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100752 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100753 ipa_ud := f_mgcp_to_ud(payload);
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700754 IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
Harald Weltec82eef42017-11-24 20:40:12 +0100755 }
Harald Weltedf277252018-02-20 15:49:30 +0100756#endif
Harald Weltec82eef42017-11-24 20:40:12 +0100757
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200758#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100759 [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
760 payload := char2oct(enc_CtrlMessage(ctrl_msg));
761 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700762 IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
Harald Weltea76c4bb2017-12-09 02:06:07 +0100763 }
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200764#endif
Harald Weltea76c4bb2017-12-09 02:06:07 +0100765
Harald Weltedf277252018-02-20 15:49:30 +0100766#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100767 [] IPA_GSUP_PORT.receive(GSUP_PDU:?) -> value gsup_msg {
Harald Welte2f562b12018-01-24 20:52:38 +0100768 f_gsup_preprocess_encoded(gsup_msg);
Harald Weltedf327232017-12-28 22:51:51 +0100769 payload := enc_GSUP_PDU(gsup_msg);
770 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_GSUP));
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700771 IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
Harald Weltedf327232017-12-28 22:51:51 +0100772 }
Harald Weltedf277252018-02-20 15:49:30 +0100773#endif
Harald Weltedf327232017-12-28 22:51:51 +0100774
Harald Welte7460a722018-10-10 12:28:27 +0200775#ifdef IPA_EMULATION_RSPRO
776 [] IPA_RSPRO_PORT.receive(RsproPDU:?) -> value rspro {
777 payload := enc_RsproPDU(rspro);
778 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_RSPRO));
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700779 IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
Harald Welte7460a722018-10-10 12:28:27 +0200780 }
781#endif
782
Harald Weltedf277252018-02-20 15:49:30 +0100783#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100784 /* Received RSL -> down into IPA */
785 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700786 IPA_PORT.send(f_from_rsl(f_ipa_conn_id(), rsl));
Harald Welte0d846a72017-12-07 17:58:28 +0100787 }
Harald Weltedf277252018-02-20 15:49:30 +0100788#endif
Harald Weltec6826662019-02-06 22:26:46 +0100789#ifdef IPA_EMULATION_OML
790 /* Received OML -> down into IPA */
791 [] IPA_OML_PORT.receive(OML_PDU:?) -> value oml {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700792 IPA_PORT.send(f_from_oml(f_ipa_conn_id(), oml));
Harald Weltec6826662019-02-06 22:26:46 +0100793 }
794 [] IPA_OML_PORT.receive(octetstring:?) -> value payload {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700795 IPA_PORT.send(t_IPA_Send(f_ipa_conn_id(), IPAC_PROTO_OML, payload));
Harald Weltec6826662019-02-06 22:26:46 +0100796 }
797#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100798 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100799 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
Vadim Yanitskiy6643e8d2020-05-18 21:50:12 +0700800 IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
Harald Weltec76f29f2017-11-22 12:46:46 +0100801 }
802
803
Harald Welted86cdc62017-11-22 00:45:07 +0100804 }
805 }
806}
807
Harald Welte2e32e432018-05-24 20:00:00 +0200808/***********************************************************************
809 * IPA Event waiter component. Wait for ASP_IPA_EVENT_ID_ACK
810 ***********************************************************************/
811
812type component IPA_EventWaiter_CT {
813 port IPA_SP_PT IPA_SP_PORT;
814}
815
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700816function waiter_main(template ASP_IPA_Event wait_for := tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK))
Harald Welte2e32e432018-05-24 20:00:00 +0200817runs on IPA_EventWaiter_CT {
818
819 alt {
820 [] IPA_SP_PORT.receive(wait_for) {
821 setverdict(pass);
822 }
823 [] IPA_SP_PORT.receive { repeat; }
824 }
825}
826
827
Harald Welted86cdc62017-11-22 00:45:07 +0100828}