blob: 1bfc8dc4dd36d3a7d312c46b90fadc25d6929962 [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 */
Harald Welte0d846a72017-12-07 17:58:28 +010087type union ASP_IPA_Event {
Vadim Yanitskiy8701b272020-05-18 20:17:25 +070088 ASP_IPA_EventType up_down
Harald Welte0d846a72017-12-07 17:58:28 +010089}
90
Vadim Yanitskiy61564be2020-05-18 20:44:14 +070091template (value) ASP_IPA_Event ts_ASP_IPA_EV(ASP_IPA_EventType ud) := {
92 up_down := ud
93}
94
95template ASP_IPA_Event tr_ASP_IPA_EV(template ASP_IPA_EventType ud) := {
Harald Welte0d846a72017-12-07 17:58:28 +010096 up_down := ud
97}
98
Harald Welte1dd8f372017-11-25 02:25:27 +010099template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
100 template IpaExtStreamId esid := omit) := {
101 streamId := sid,
102 streamIdExt := esid,
103 payload := pl
104}
105
Harald Weltedf277252018-02-20 15:49:30 +0100106#ifdef IPA_EMULATION_RSL
Harald Weltebdb63702017-12-09 01:15:44 +0100107/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +0100108type record ASP_RSL_Unitdata {
109 IpaStreamId streamId,
110 RSL_Message rsl
111};
112
Vadim Yanitskiy6b4856d2020-05-25 21:23:46 +0700113template (value) ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template (value) RSL_Message rsl) := {
Harald Welte0d846a72017-12-07 17:58:28 +0100114 streamId := sid,
Vadim Yanitskiy6b4856d2020-05-25 21:23:46 +0700115 rsl := rsl
Harald Welte0d846a72017-12-07 17:58:28 +0100116}
117
Vadim Yanitskiy6b4856d2020-05-25 21:23:46 +0700118template ASP_RSL_Unitdata tr_ASP_RSL_UD(template IpaStreamId sid, template RSL_Message rsl) := {
Harald Welte7ae019e2017-12-09 00:54:15 +0100119 streamId := sid,
120 rsl := rsl
121}
122
Harald Welte0d846a72017-12-07 17:58:28 +0100123template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
124 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
Harald Weltedf277252018-02-20 15:49:30 +0100125#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100126
Harald Weltec6826662019-02-06 22:26:46 +0100127
Harald Weltebdb63702017-12-09 01:15:44 +0100128/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +0100129type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +0100130 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +0100131} with { extension "internal" }
132
Harald Weltedf277252018-02-20 15:49:30 +0100133#ifdef IPA_EMULATION_MGCP
Harald Weltebdb63702017-12-09 01:15:44 +0100134/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +0100135type port IPA_MGCP_PT message {
136 inout MgcpCommand, MgcpResponse;
137} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100138#endif
Harald Weltec82eef42017-11-24 20:40:12 +0100139
Harald Weltedf277252018-02-20 15:49:30 +0100140#ifdef IPA_EMULATION_RSL
Harald Weltebdb63702017-12-09 01:15:44 +0100141/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +0100142type port IPA_RSL_PT message {
143 inout ASP_RSL_Unitdata, ASP_IPA_Event;
144} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100145#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100146
Harald Weltec6826662019-02-06 22:26:46 +0100147#ifdef IPA_EMULATION_OML
148/* Client port for A-bis OML inside IPA */
149type port IPA_OML_PT message {
150 inout OML_PDU, octetstring, ASP_IPA_Event;
151} with { extension "internal" }
152#endif
153
Harald Welte3286eb32019-08-18 19:36:10 +0200154#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100155/* Client port for CTRL inside IPA */
156type port IPA_CTRL_PT message {
157 inout CtrlMessage, ASP_IPA_Event;
158} with { extension "internal" }
Harald Welte3286eb32019-08-18 19:36:10 +0200159#endif
Harald Weltea76c4bb2017-12-09 02:06:07 +0100160
Harald Weltedf277252018-02-20 15:49:30 +0100161#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100162/* Client port for CTRL inside IPA */
163type port IPA_GSUP_PT message {
164 inout GSUP_PDU, ASP_IPA_Event;
165} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100166#endif
Harald Weltedf327232017-12-28 22:51:51 +0100167
Harald Welte7460a722018-10-10 12:28:27 +0200168#ifdef IPA_EMULATION_RSPRO
169type port IPA_RSPRO_PT message {
170 inout RsproPDU, ASP_IPA_Event;
171} with { extension "internal" }
172#endif
173
174
175
Harald Weltedf327232017-12-28 22:51:51 +0100176
Harald Welted86cdc62017-11-22 00:45:07 +0100177type component IPA_Emulation_CT {
178 /* down-facing port to IPA codec port */
179 port IPA_CODEC_PT IPA_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100180#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100181 /* up-facing port to SCCP */
182 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100183#endif
184#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100185 /* up-facing port for MGCP */
186 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100187#endif
188#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100189 /* up-facing port for RSL */
190 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100191#endif
Harald Weltec6826662019-02-06 22:26:46 +0100192#ifdef IPA_EMULATION_OML
193 /* up-facing port for OML */
194 port IPA_OML_PT IPA_OML_PORT;
195#endif
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200196#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100197 /* up-facing port for CTRL */
198 port IPA_CTRL_PT IPA_CTRL_PORT;
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200199#endif
Harald Weltedf277252018-02-20 15:49:30 +0100200#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100201 /* up-facing port for GSUP */
202 port IPA_GSUP_PT IPA_GSUP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100203#endif
Harald Welte7460a722018-10-10 12:28:27 +0200204#ifdef IPA_EMULATION_RSPRO
205 /* up-facing port for RSPRO */
206 port IPA_RSPRO_PT IPA_RSPRO_PORT;
207#endif
Harald Weltedf327232017-12-28 22:51:51 +0100208
Harald Weltec76f29f2017-11-22 12:46:46 +0100209 /* up-facing port for other streams */
210 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100211
212 var boolean g_initialized := false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100213 var IPL4asp_Types.ConnectionId g_ipa_conn_id := -1;
Harald Weltec82eef42017-11-24 20:40:12 +0100214 /* Are we a BSC/MGW (truel) or MSC (false) */
215 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100216
217 var IpaMode g_mode;
Harald Welte2d86aff2018-04-17 11:23:04 +0200218 var boolean g_ccm_enabled;
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200219 var IpaInitBehavior g_init_behavior;
Harald Weltee09921f2017-12-07 17:49:00 +0100220 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100221}
222
Harald Weltee21096d2017-12-04 20:45:12 +0100223type record IPA_CCM_Parameters {
224 charstring ser_nr optional,
225 charstring name optional,
226 charstring location1 optional,
227 charstring location2 optional,
228 charstring equip_version optional,
229 charstring sw_version optional,
230 charstring ip_addr optional,
231 charstring mac_addr optional,
232 charstring unit_id optional,
233 charstring osmo_rand optional
234}
235
Harald Weltee09921f2017-12-07 17:49:00 +0100236const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
237 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100238 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100239 location1 := "",
240 location2 := "",
241 equip_version := "",
242 sw_version := "",
243 ip_addr := "",
244 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100245 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100246 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100247};
248
Harald Weltebdb63702017-12-09 01:15:44 +0100249/* Function to use to connect as client to a remote IPA Server */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100250function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
251 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100252 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100253 var IPL4asp_Types.Result res;
Harald Welted86cdc62017-11-22 00:45:07 +0100254 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
255 local_host, local_port, 0, { tcp:={} });
Harald Welte9220f632018-05-23 20:27:02 +0200256 if (not ispresent(res.connId)) {
Stefan Sperling6a90be42018-08-31 15:05:39 +0200257 setverdict(fail, "Could not connect IPA socket from ", local_host, " port ", local_port,
258 " to ", remote_host, " port ", remote_port, "; check your configuration");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200259 mtc.stop;
Harald Welte9220f632018-05-23 20:27:02 +0200260 }
Harald Welted86cdc62017-11-22 00:45:07 +0100261 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100262 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100263 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100264}
265
Harald Weltebdb63702017-12-09 01:15:44 +0100266/* Function to use to bind to a local port as IPA server, accepting remote clients */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100267function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100268 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100269 var IPL4asp_Types.Result res;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +0200270 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
Harald Welteb3414b22017-11-23 18:22:10 +0100271 local_host, local_port, { tcp:={} });
Harald Welte9220f632018-05-23 20:27:02 +0200272 if (not ispresent(res.connId)) {
Maxb7aae8b2019-03-11 15:22:02 +0100273 setverdict(fail, "Could not listen IPA socket ", local_host, ":", local_port, ", check your configuration");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200274 mtc.stop;
Harald Welte9220f632018-05-23 20:27:02 +0200275 }
Harald Welteb3414b22017-11-23 18:22:10 +0100276 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100277 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100278 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100279}
280
Harald Weltedf277252018-02-20 15:49:30 +0100281#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100282template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
283 sio := { '10'B, '00'B, '0011'B },
284 opc := opc,
285 dpc := 0,
286 sls := 0,
287 data := data
288}
Harald Weltedf277252018-02-20 15:49:30 +0100289#endif
Harald Welted86cdc62017-11-22 00:45:07 +0100290
291
292private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
293 len := 0, /* overwritten by codec */
294 tag := tag,
Harald Welte95686e02018-08-02 15:05:43 +0200295 data := char2oct(payload) & '00'O
Harald Welted86cdc62017-11-22 00:45:07 +0100296}
297
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700298private function f_send_IPA_EVT(template (value) ASP_IPA_Event evt) runs on IPA_Emulation_CT {
Harald Welte2e32e432018-05-24 20:00:00 +0200299 if (IPA_SP_PORT.checkstate("Connected")) {
300 IPA_SP_PORT.send(evt);
301 }
Harald Weltedf277252018-02-20 15:49:30 +0100302#ifdef IPA_EMULATION_RSL
Harald Welte5819b552017-12-09 02:55:46 +0100303 if (IPA_RSL_PORT.checkstate("Connected")) {
304 IPA_RSL_PORT.send(evt);
305 }
Harald Weltedf277252018-02-20 15:49:30 +0100306#endif
Harald Weltec6826662019-02-06 22:26:46 +0100307#ifdef IPA_EMULATION_OML
308 if (IPA_OML_PORT.checkstate("Connected")) {
309 IPA_OML_PORT.send(evt);
310 }
311#endif
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200312#ifdef IPA_EMULATION_CTRL
Harald Welte5819b552017-12-09 02:55:46 +0100313 if (IPA_CTRL_PORT.checkstate("Connected")) {
314 IPA_CTRL_PORT.send(evt);
315 }
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200316#endif
Harald Weltedf277252018-02-20 15:49:30 +0100317#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100318 if (IPA_GSUP_PORT.checkstate("Connected")) {
319 IPA_GSUP_PORT.send(evt);
320 }
Harald Weltedf277252018-02-20 15:49:30 +0100321#endif
Harald Welte7460a722018-10-10 12:28:27 +0200322#ifdef IPA_EMULATION_RSPRO
323 if (IPA_RSPRO_PORT.checkstate("Connected")) {
324 IPA_RSPRO_PORT.send(evt);
325 }
326#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100327 /* FIXME: to other ports */
328}
329
Harald Welted86cdc62017-11-22 00:45:07 +0100330/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100331private 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 +0100332 var integer i;
333 var PDU_IPA_CCM resp := {
334 msg_type := IPAC_MSGT_ID_RESP,
335 u := {
336 resp := {}
337 }
338 }
339
340 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
341 var IpaCcmIdTag tag := get.u.get[i].tag;
342 var charstring foo;
343 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100344 case (IPAC_IDTAG_SERNR) {
345 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100346 }
347 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100348 foo := g_ccm_pars.name;
349 }
350 case (IPAC_IDTAG_LOCATION1) {
351 foo := g_ccm_pars.location1;
352 }
353 case (IPAC_IDTAG_LOCATION2) {
354 foo := g_ccm_pars.location2;
355 }
356 case (IPAC_IDTAG_EQUIPVERS) {
357 foo := g_ccm_pars.equip_version;
358 }
359 case (IPAC_IDTAG_SWVERSION) {
360 foo := g_ccm_pars.sw_version;
361 }
362 case (IPAC_IDTAG_IPADDR) {
363 foo := g_ccm_pars.ip_addr;
364 }
365 case (IPAC_IDTAG_MACADDR) {
366 foo := g_ccm_pars.mac_addr;
367 }
Vadim Yanitskiy44f0c482020-05-24 20:49:29 +0700368 case (IPAC_IDTAG_UNITID) {
Harald Weltee21096d2017-12-04 20:45:12 +0100369 foo := g_ccm_pars.unit_id;
370 }
371 case (IPAC_IDTAG_OSMO_RAND) {
372 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100373 }
374 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100375 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100376 }
377 }
378 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
379 }
380
381 return resp;
382}
383
384/* transmit IPA CCM message */
385private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Weltec82eef42017-11-24 20:40:12 +0100386 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_CCM, enc_PDU_IPA_CCM(ccm)));
Harald Welted86cdc62017-11-22 00:45:07 +0100387 log("CCM Tx:", ccm);
388 IPA_PORT.send(ipa_tx);
389}
390
391template PDU_IPA_CCM ts_IPA_PONG := {
392 msg_type := IPAC_MSGT_PONG,
393 u := omit
394}
395
396template PDU_IPA_CCM ts_IPA_ACK := {
397 msg_type := IPAC_MSGT_ID_ACK,
398 u := omit
399}
400
Harald Welteb3414b22017-11-23 18:22:10 +0100401template PDU_IPA_CCM ts_IPA_ID_GET := {
402 msg_type := IPAC_MSGT_ID_GET,
403 u := {
404 get := {
405 { 1, IPAC_IDTAG_UNITNAME }
406 }
407 }
408}
409
Harald Welted86cdc62017-11-22 00:45:07 +0100410/* receive IPA CCM message */
Harald Welte2d86aff2018-04-17 11:23:04 +0200411private function f_ccm_rx_client(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100412 select (ccm.msg_type) {
413 case (IPAC_MSGT_PING) {
414 f_ccm_tx(valueof(ts_IPA_PONG));
415 }
416 case (IPAC_MSGT_ID_ACK) {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700417 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK));
Harald Welted86cdc62017-11-22 00:45:07 +0100418 }
419 case (IPAC_MSGT_ID_GET) {
420 f_ccm_tx(f_ccm_make_id_resp(ccm));
421 }
Harald Welte2d86aff2018-04-17 11:23:04 +0200422 case else {
423 log("Unknown/unsupported IPA CCM message type", ccm);
424 }
425 }
426}
427
428private function f_ccm_rx_server(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
429 select (ccm.msg_type) {
430 case (IPAC_MSGT_PING) {
431 f_ccm_tx(valueof(ts_IPA_PONG));
432 }
433 case (IPAC_MSGT_ID_ACK) {
434 /* the IPA server should at some point receive an ID_ACK from the client,
435 * in case of RSL/OML from nanoBTS, this is actually the first message after
436 * the TCP connection is established. Other implementations may differ.
437 * We currently ignore it completely - but actually we should make sure that
438 * one ID_ACK is received by the server at some point */
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700439 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK));
Harald Welte2d86aff2018-04-17 11:23:04 +0200440 }
Harald Welte3bc387f2018-02-21 12:18:46 +0100441 case (IPAC_MSGT_ID_RESP) {
442 log("IPA ID RESP: ", ccm.u.resp);
Harald Welte2d86aff2018-04-17 11:23:04 +0200443 /* acknowledge any identity that the client may have sent */
444 f_ccm_tx(valueof(ts_IPA_ACK));
Harald Welte3bc387f2018-02-21 12:18:46 +0100445 }
Harald Welted86cdc62017-11-22 00:45:07 +0100446 case else {
447 log("Unknown/unsupported IPA CCM message type", ccm);
448 }
449 }
450}
451
Harald Weltec76f29f2017-11-22 12:46:46 +0100452private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
453 var ASP_IPA_Unitdata ret := {
454 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100455 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100456 payload := ipa_rx.msg
457 }
458 return ret;
459}
460
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100461private function f_from_asp(IPL4asp_Types.ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100462 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
463 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100464 return ret;
465}
Harald Welted86cdc62017-11-22 00:45:07 +0100466
Harald Weltedf277252018-02-20 15:49:30 +0100467#ifdef IPA_EMULATION_RSL
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100468private function f_from_rsl(IPL4asp_Types.ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
Harald Welte0d846a72017-12-07 17:58:28 +0100469 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
470 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
471 return ret;
472}
Harald Weltedf277252018-02-20 15:49:30 +0100473#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100474
Harald Weltec6826662019-02-06 22:26:46 +0100475#ifdef IPA_EMULATION_OML
476private function f_from_oml(IPL4asp_Types.ConnectionId connId, OML_PDU oml_tx) return IPA_Send {
477 var octetstring payload := enc_OML_PDU(oml_tx);
478 var IPA_Send ret := valueof(t_IPA_Send(connId, IPAC_PROTO_OML, payload));
479 return ret;
480}
481#endif
482
Harald Weltebdb63702017-12-09 01:15:44 +0100483/* main function to use for a client-side IPA implementation */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100484function main_client(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
485 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Welte2d86aff2018-04-17 11:23:04 +0200486 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars,
487 boolean ccm_enabled := true) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100488 g_mode := IPA_MODE_CLIENT;
Harald Welte2d86aff2018-04-17 11:23:04 +0200489 g_ccm_enabled := ccm_enabled;
Harald Weltee09921f2017-12-07 17:49:00 +0100490 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welte2d86aff2018-04-17 11:23:04 +0200491 if (g_ccm_enabled) {
492 /* we're a client: Send ID_ACK immediately after connect */
493 f_ccm_tx(valueof(ts_IPA_ACK));
494 }
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700495 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100496 ScanEvents();
497}
498
Harald Weltebdb63702017-12-09 01:15:44 +0100499/* main function to use for a server-side IPA implementation */
Harald Welte2d86aff2018-04-17 11:23:04 +0200500function main_server(charstring local_host, IPL4asp_Types.PortNumber local_port,
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200501 boolean ccm_enabled := true,
502 IpaInitBehavior init_behavior := IPA_INIT_SEND_IPA_ID_GET)
503runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100504 g_mode := IPA_MODE_SERVER;
Harald Welte2d86aff2018-04-17 11:23:04 +0200505 g_ccm_enabled := ccm_enabled;
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200506 g_init_behavior := init_behavior;
Harald Welteb3414b22017-11-23 18:22:10 +0100507 f_bind(local_host, local_port);
508 ScanEvents();
509}
510
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200511#ifdef IPA_EMULATION_CTRL
Harald Weltedf277252018-02-20 15:49:30 +0100512private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
513 var charstring msg_ch := oct2char(msg);
514 IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
515}
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200516#endif
Harald Weltedf277252018-02-20 15:49:30 +0100517
518#ifdef IPA_EMULATION_GSUP
519private function f_gsup_to_user(octetstring msg) runs on IPA_Emulation_CT {
520 var GSUP_PDU gsup := dec_GSUP_PDU(msg);
521 f_gsup_postprocess_decoded(gsup);
522 IPA_GSUP_PORT.send(gsup);
523}
524#endif
525
Harald Welte7460a722018-10-10 12:28:27 +0200526#ifdef IPA_EMULATION_RSPRO
527private function f_rspro_to_user(octetstring msg) runs on IPA_Emulation_CT {
528 var RsproPDU rspro := dec_RsproPDU(msg);
529 IPA_RSPRO_PORT.send(rspro);
530}
531#endif
532
Harald Weltedf277252018-02-20 15:49:30 +0100533#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100534private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
535 var charstring msg_ch := oct2char(msg);
536 if (g_is_bsc_mgw) {
537 log("============");
538 log(msg_ch);
539 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
540 } else {
541 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
542 }
543}
544
Harald Welte92632e12017-11-25 02:31:20 +0100545private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
546 if (mp_ipa_mgcp_uses_osmo_ext) {
547 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
548 } else {
549 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
550 }
551}
Harald Weltedf277252018-02-20 15:49:30 +0100552#endif
Harald Welte92632e12017-11-25 02:31:20 +0100553
Harald Weltebdb63702017-12-09 01:15:44 +0100554/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100555private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100556 var IPA_RecvFrom ipa_rx;
Harald Welteb3414b22017-11-23 18:22:10 +0100557 var ASP_Event asp_evt;
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100558 var Socket_API_Definitions.PortEvent port_evt;
Harald Weltedf277252018-02-20 15:49:30 +0100559 var octetstring payload;
Harald Weltedf277252018-02-20 15:49:30 +0100560 var ASP_IPA_Unitdata ipa_ud;
Harald Welte3286eb32019-08-18 19:36:10 +0200561#ifdef IPA_EMULATION_CTRL
562 var CtrlMessage ctrl_msg;
563#endif
Harald Weltedf277252018-02-20 15:49:30 +0100564#ifdef IPA_EMULATION_SCCP
565 var ASP_MTP3_TRANSFERreq mtp_req;
566#endif
567#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100568 var MgcpCommand mgcp_cmd;
569 var MgcpResponse mgcp_rsp;
Harald Weltedf277252018-02-20 15:49:30 +0100570#endif
571#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100572 var GSUP_PDU gsup_msg;
Harald Weltedf277252018-02-20 15:49:30 +0100573#endif
574#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100575 var ASP_RSL_Unitdata rsl;
Harald Weltedf277252018-02-20 15:49:30 +0100576#endif
Harald Weltec6826662019-02-06 22:26:46 +0100577#ifdef IPA_EMULATION_OML
578 var OML_PDU oml;
579#endif
Harald Welte7460a722018-10-10 12:28:27 +0200580#ifdef IPA_EMULATION_RSPRO
581 var RsproPDU rspro;
582#endif
Harald Welted86cdc62017-11-22 00:45:07 +0100583
Harald Welte3e6ad892017-12-12 14:39:46 +0100584 /* Set function for dissecting the binary */
585 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
586 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});
587
Harald Welted86cdc62017-11-22 00:45:07 +0100588 while (true) {
589 alt {
590 /* Received IPA -> up into SCCP stack */
Harald Welte2d86aff2018-04-17 11:23:04 +0200591 [g_ccm_enabled] IPA_PORT.receive(IPA_RecvFrom:{?,IPAC_PROTO_CCM,omit,?}) -> value ipa_rx {
592 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
593 log("CCM Rx:", ccm);
594 select (g_mode) {
595 case (IPA_MODE_CLIENT) {
596 f_ccm_rx_client(ccm);
597 }
598 case (IPA_MODE_SERVER) {
599 f_ccm_rx_server(ccm);
600 }
601 case else {
602 setverdict(fail, "Unknown mode");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200603 mtc.stop;
Harald Welte2d86aff2018-04-17 11:23:04 +0200604 }
Harald Weltedf277252018-02-20 15:49:30 +0100605 }
Harald Welte2d86aff2018-04-17 11:23:04 +0200606 }
607 [] IPA_PORT.receive(IPA_RecvFrom:?) -> value ipa_rx {
608 select (ipa_rx.streamId) {
Harald Weltedf277252018-02-20 15:49:30 +0100609#ifdef IPA_EMULATION_SCCP
610 case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100611 var ASP_MTP3_TRANSFERind mtp;
612 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
613 MTP3_SP_PORT.send(mtp);
Harald Weltedf277252018-02-20 15:49:30 +0100614 }
615#endif
616#ifdef IPA_EMULATION_MGCP
617 case (IPAC_PROTO_MGCP_OLD) {
Harald Weltec82eef42017-11-24 20:40:12 +0100618 f_mgcp_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100619 }
620#endif
621#ifdef IPA_EMULATION_RSL
622 case (t_IpaSidRSL) {
Harald Welte0d846a72017-12-07 17:58:28 +0100623 rsl := {
624 streamId := ipa_rx.streamId,
625 rsl := dec_RSL_Message(ipa_rx.msg)
626 };
627 IPA_RSL_PORT.send(rsl);
Harald Weltedf277252018-02-20 15:49:30 +0100628 }
629#endif
Harald Weltec6826662019-02-06 22:26:46 +0100630#ifdef IPA_EMULATION_OML
631 case (IPAC_PROTO_OML) {
632 oml := dec_OML_PDU(ipa_rx.msg)
633 IPA_OML_PORT.send(oml);
634 }
635#endif
Harald Weltedf277252018-02-20 15:49:30 +0100636 case (IPAC_PROTO_OSMO) {
Harald Weltec82eef42017-11-24 20:40:12 +0100637 select (ipa_rx.streamIdExt) {
Harald Weltedf277252018-02-20 15:49:30 +0100638#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100639 case (IPAC_PROTO_EXT_MGCP) {
640 f_mgcp_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100641 }
642#endif
Harald Welte3286eb32019-08-18 19:36:10 +0200643#ifdef IPA_EMULATION_CTRL
Harald Weltedf277252018-02-20 15:49:30 +0100644 case (IPAC_PROTO_EXT_CTRL) {
Harald Weltea76c4bb2017-12-09 02:06:07 +0100645 f_ctrl_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100646 }
Harald Welte3286eb32019-08-18 19:36:10 +0200647#endif
Harald Weltedf277252018-02-20 15:49:30 +0100648#ifdef IPA_EMULATION_GSUP
649 case (IPAC_PROTO_EXT_GSUP) {
Harald Weltedf327232017-12-28 22:51:51 +0100650 f_gsup_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100651 }
652#endif
Harald Welte7460a722018-10-10 12:28:27 +0200653#ifdef IPA_EMULATION_RSPRO
654 case (IPAC_PROTO_EXT_RSPRO) {
655 f_rspro_to_user(ipa_rx.msg);
656 }
657#endif
Harald Weltedf277252018-02-20 15:49:30 +0100658 case else {
Harald Weltec82eef42017-11-24 20:40:12 +0100659 IPA_SP_PORT.send(f_to_asp(ipa_rx));
660 }
Harald Welted86cdc62017-11-22 00:45:07 +0100661 }
Harald Weltedf277252018-02-20 15:49:30 +0100662 }
663 case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100664 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100665 }
666 }
667 }
668
Harald Welteb3414b22017-11-23 18:22:10 +0100669 /* server only */
670 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
671 log("IPA: Connected");
672 g_ipa_conn_id := asp_evt.connOpened.connId;
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700673 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_UP));
Harald Welte2d86aff2018-04-17 11:23:04 +0200674 if (g_mode == IPA_MODE_SERVER and g_ccm_enabled) {
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200675 select (g_init_behavior) {
676 case (IPA_INIT_SEND_IPA_ID_GET) {
677 f_ccm_tx(valueof(ts_IPA_ID_GET));
678 }
679 case (IPA_INIT_SEND_IPA_ID_ACK) {
680 f_ccm_tx(valueof(ts_IPA_ACK));
681 }
682 }
Harald Welteb3414b22017-11-23 18:22:10 +0100683 }
684 }
685
686 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
687 log("IPA: Closed");
688 g_ipa_conn_id := -1;
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700689 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_DOWN));
Harald Welteb3414b22017-11-23 18:22:10 +0100690 self.stop;
691 }
692
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100693 [] IPA_PORT.receive(Socket_API_Definitions.PortEvent:{result:={errorCode:=ERROR_SOCKET, connId:=?, os_error_code:=?, os_error_text:=?}}) -> value port_evt {
694 log("PortEvent: ERROR_SOCKET: ", port_evt);
695 g_ipa_conn_id := -1;
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700696 f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_DOWN));
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100697 self.stop;
698 }
699
Harald Weltedf277252018-02-20 15:49:30 +0100700#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100701 /* Received SCCP -> down into IPA */
702 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Harald Weltec82eef42017-11-24 20:40:12 +0100703 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
704 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100705 IPA_PORT.send(ipa_tx);
706 }
Harald Weltedf277252018-02-20 15:49:30 +0100707#endif
Harald Weltec76f29f2017-11-22 12:46:46 +0100708
Harald Weltedf277252018-02-20 15:49:30 +0100709#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100710 /* Received MGCP -> down into IPA */
711 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100712 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
713 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100714 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
715 }
716 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100717 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100718 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100719 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
720 }
Harald Weltedf277252018-02-20 15:49:30 +0100721#endif
Harald Weltec82eef42017-11-24 20:40:12 +0100722
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200723#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100724 [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
725 payload := char2oct(enc_CtrlMessage(ctrl_msg));
726 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
727 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
728 }
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200729#endif
Harald Weltea76c4bb2017-12-09 02:06:07 +0100730
Harald Weltedf277252018-02-20 15:49:30 +0100731#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100732 [] IPA_GSUP_PORT.receive(GSUP_PDU:?) -> value gsup_msg {
Harald Welte2f562b12018-01-24 20:52:38 +0100733 f_gsup_preprocess_encoded(gsup_msg);
Harald Weltedf327232017-12-28 22:51:51 +0100734 payload := enc_GSUP_PDU(gsup_msg);
735 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_GSUP));
736 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
737 }
Harald Weltedf277252018-02-20 15:49:30 +0100738#endif
Harald Weltedf327232017-12-28 22:51:51 +0100739
Harald Welte7460a722018-10-10 12:28:27 +0200740#ifdef IPA_EMULATION_RSPRO
741 [] IPA_RSPRO_PORT.receive(RsproPDU:?) -> value rspro {
742 payload := enc_RsproPDU(rspro);
743 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_RSPRO));
744 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
745 }
746#endif
747
Harald Weltedf277252018-02-20 15:49:30 +0100748#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100749 /* Received RSL -> down into IPA */
750 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
751 IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
752 }
Harald Weltedf277252018-02-20 15:49:30 +0100753#endif
Harald Weltec6826662019-02-06 22:26:46 +0100754#ifdef IPA_EMULATION_OML
755 /* Received OML -> down into IPA */
756 [] IPA_OML_PORT.receive(OML_PDU:?) -> value oml {
757 IPA_PORT.send(f_from_oml(g_ipa_conn_id, oml));
758 }
759 [] IPA_OML_PORT.receive(octetstring:?) -> value payload {
760 IPA_PORT.send(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_OML, payload));
761 }
762#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100763 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100764 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
765 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
766 }
767
768
Harald Welted86cdc62017-11-22 00:45:07 +0100769 }
770 }
771}
772
Harald Welte2e32e432018-05-24 20:00:00 +0200773/***********************************************************************
774 * IPA Event waiter component. Wait for ASP_IPA_EVENT_ID_ACK
775 ***********************************************************************/
776
777type component IPA_EventWaiter_CT {
778 port IPA_SP_PT IPA_SP_PORT;
779}
780
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700781function waiter_main(template ASP_IPA_Event wait_for := tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK))
Harald Welte2e32e432018-05-24 20:00:00 +0200782runs on IPA_EventWaiter_CT {
783
784 alt {
785 [] IPA_SP_PORT.receive(wait_for) {
786 setverdict(pass);
787 }
788 [] IPA_SP_PORT.receive { repeat; }
789 }
790}
791
792
Harald Welted86cdc62017-11-22 00:45:07 +0100793}