blob: 7b80c2d23b9f0a772a097d648289bfa55db5e333 [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
Harald Welte0d846a72017-12-07 17:58:28 +010079type enumerated ASP_IPA_EventUpDown {
80 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 {
88 ASP_IPA_EventUpDown up_down
89}
90
91template ASP_IPA_Event t_ASP_IPA_EVT_UD(ASP_IPA_EventUpDown ud) := {
92 up_down := ud
93}
94
Harald Welte1dd8f372017-11-25 02:25:27 +010095template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
96 template IpaExtStreamId esid := omit) := {
97 streamId := sid,
98 streamIdExt := esid,
99 payload := pl
100}
101
Harald Weltedf277252018-02-20 15:49:30 +0100102#ifdef IPA_EMULATION_RSL
Harald Weltebdb63702017-12-09 01:15:44 +0100103/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +0100104type record ASP_RSL_Unitdata {
105 IpaStreamId streamId,
106 RSL_Message rsl
107};
108
Harald Welte7ae019e2017-12-09 00:54:15 +0100109template ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
Harald Welte0d846a72017-12-07 17:58:28 +0100110 streamId := sid,
111 rsl := valueof(rsl)
112}
113
Harald Welte7ae019e2017-12-09 00:54:15 +0100114template ASP_RSL_Unitdata tr_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
115 streamId := sid,
116 rsl := rsl
117}
118
Harald Welte0d846a72017-12-07 17:58:28 +0100119template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
120 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
Harald Weltedf277252018-02-20 15:49:30 +0100121#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100122
Harald Weltec6826662019-02-06 22:26:46 +0100123
Harald Weltebdb63702017-12-09 01:15:44 +0100124/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +0100125type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +0100126 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +0100127} with { extension "internal" }
128
Harald Weltedf277252018-02-20 15:49:30 +0100129#ifdef IPA_EMULATION_MGCP
Harald Weltebdb63702017-12-09 01:15:44 +0100130/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +0100131type port IPA_MGCP_PT message {
132 inout MgcpCommand, MgcpResponse;
133} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100134#endif
Harald Weltec82eef42017-11-24 20:40:12 +0100135
Harald Weltedf277252018-02-20 15:49:30 +0100136#ifdef IPA_EMULATION_RSL
Harald Weltebdb63702017-12-09 01:15:44 +0100137/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +0100138type port IPA_RSL_PT message {
139 inout ASP_RSL_Unitdata, ASP_IPA_Event;
140} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100141#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100142
Harald Weltec6826662019-02-06 22:26:46 +0100143#ifdef IPA_EMULATION_OML
144/* Client port for A-bis OML inside IPA */
145type port IPA_OML_PT message {
146 inout OML_PDU, octetstring, ASP_IPA_Event;
147} with { extension "internal" }
148#endif
149
Harald Welte3286eb32019-08-18 19:36:10 +0200150#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100151/* Client port for CTRL inside IPA */
152type port IPA_CTRL_PT message {
153 inout CtrlMessage, ASP_IPA_Event;
154} with { extension "internal" }
Harald Welte3286eb32019-08-18 19:36:10 +0200155#endif
Harald Weltea76c4bb2017-12-09 02:06:07 +0100156
Harald Weltedf277252018-02-20 15:49:30 +0100157#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100158/* Client port for CTRL inside IPA */
159type port IPA_GSUP_PT message {
160 inout GSUP_PDU, ASP_IPA_Event;
161} with { extension "internal" }
Harald Weltedf277252018-02-20 15:49:30 +0100162#endif
Harald Weltedf327232017-12-28 22:51:51 +0100163
Harald Welte7460a722018-10-10 12:28:27 +0200164#ifdef IPA_EMULATION_RSPRO
165type port IPA_RSPRO_PT message {
166 inout RsproPDU, ASP_IPA_Event;
167} with { extension "internal" }
168#endif
169
170
171
Harald Weltedf327232017-12-28 22:51:51 +0100172
Harald Welted86cdc62017-11-22 00:45:07 +0100173type component IPA_Emulation_CT {
174 /* down-facing port to IPA codec port */
175 port IPA_CODEC_PT IPA_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100176#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100177 /* up-facing port to SCCP */
178 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100179#endif
180#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100181 /* up-facing port for MGCP */
182 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100183#endif
184#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100185 /* up-facing port for RSL */
186 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100187#endif
Harald Weltec6826662019-02-06 22:26:46 +0100188#ifdef IPA_EMULATION_OML
189 /* up-facing port for OML */
190 port IPA_OML_PT IPA_OML_PORT;
191#endif
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200192#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100193 /* up-facing port for CTRL */
194 port IPA_CTRL_PT IPA_CTRL_PORT;
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200195#endif
Harald Weltedf277252018-02-20 15:49:30 +0100196#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100197 /* up-facing port for GSUP */
198 port IPA_GSUP_PT IPA_GSUP_PORT;
Harald Weltedf277252018-02-20 15:49:30 +0100199#endif
Harald Welte7460a722018-10-10 12:28:27 +0200200#ifdef IPA_EMULATION_RSPRO
201 /* up-facing port for RSPRO */
202 port IPA_RSPRO_PT IPA_RSPRO_PORT;
203#endif
Harald Weltedf327232017-12-28 22:51:51 +0100204
Harald Weltec76f29f2017-11-22 12:46:46 +0100205 /* up-facing port for other streams */
206 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100207
208 var boolean g_initialized := false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100209 var IPL4asp_Types.ConnectionId g_ipa_conn_id := -1;
Harald Weltec82eef42017-11-24 20:40:12 +0100210 /* Are we a BSC/MGW (truel) or MSC (false) */
211 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100212
213 var IpaMode g_mode;
Harald Welte2d86aff2018-04-17 11:23:04 +0200214 var boolean g_ccm_enabled;
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200215 var IpaInitBehavior g_init_behavior;
Harald Weltee09921f2017-12-07 17:49:00 +0100216 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100217}
218
Harald Weltee21096d2017-12-04 20:45:12 +0100219type record IPA_CCM_Parameters {
220 charstring ser_nr optional,
221 charstring name optional,
222 charstring location1 optional,
223 charstring location2 optional,
224 charstring equip_version optional,
225 charstring sw_version optional,
226 charstring ip_addr optional,
227 charstring mac_addr optional,
228 charstring unit_id optional,
229 charstring osmo_rand optional
230}
231
Harald Weltee09921f2017-12-07 17:49:00 +0100232const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
233 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100234 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100235 location1 := "",
236 location2 := "",
237 equip_version := "",
238 sw_version := "",
239 ip_addr := "",
240 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100241 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100242 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100243};
244
Harald Weltebdb63702017-12-09 01:15:44 +0100245/* Function to use to connect as client to a remote IPA Server */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100246function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
247 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100248 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100249 var IPL4asp_Types.Result res;
Harald Welted86cdc62017-11-22 00:45:07 +0100250 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
251 local_host, local_port, 0, { tcp:={} });
Harald Welte9220f632018-05-23 20:27:02 +0200252 if (not ispresent(res.connId)) {
Stefan Sperling6a90be42018-08-31 15:05:39 +0200253 setverdict(fail, "Could not connect IPA socket from ", local_host, " port ", local_port,
254 " to ", remote_host, " port ", remote_port, "; check your configuration");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200255 mtc.stop;
Harald Welte9220f632018-05-23 20:27:02 +0200256 }
Harald Welted86cdc62017-11-22 00:45:07 +0100257 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100258 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100259 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100260}
261
Harald Weltebdb63702017-12-09 01:15:44 +0100262/* Function to use to bind to a local port as IPA server, accepting remote clients */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100263function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100264 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100265 var IPL4asp_Types.Result res;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +0200266 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
Harald Welteb3414b22017-11-23 18:22:10 +0100267 local_host, local_port, { tcp:={} });
Harald Welte9220f632018-05-23 20:27:02 +0200268 if (not ispresent(res.connId)) {
Maxb7aae8b2019-03-11 15:22:02 +0100269 setverdict(fail, "Could not listen IPA socket ", local_host, ":", local_port, ", check your configuration");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200270 mtc.stop;
Harald Welte9220f632018-05-23 20:27:02 +0200271 }
Harald Welteb3414b22017-11-23 18:22:10 +0100272 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100273 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100274 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100275}
276
Harald Weltedf277252018-02-20 15:49:30 +0100277#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100278template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
279 sio := { '10'B, '00'B, '0011'B },
280 opc := opc,
281 dpc := 0,
282 sls := 0,
283 data := data
284}
Harald Weltedf277252018-02-20 15:49:30 +0100285#endif
Harald Welted86cdc62017-11-22 00:45:07 +0100286
287
288private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
289 len := 0, /* overwritten by codec */
290 tag := tag,
Harald Welte95686e02018-08-02 15:05:43 +0200291 data := char2oct(payload) & '00'O
Harald Welted86cdc62017-11-22 00:45:07 +0100292}
293
Harald Welte0d846a72017-12-07 17:58:28 +0100294private function f_send_IPA_EVT(template ASP_IPA_Event evt) runs on IPA_Emulation_CT {
Harald Welte2e32e432018-05-24 20:00:00 +0200295 if (IPA_SP_PORT.checkstate("Connected")) {
296 IPA_SP_PORT.send(evt);
297 }
Harald Weltedf277252018-02-20 15:49:30 +0100298#ifdef IPA_EMULATION_RSL
Harald Welte5819b552017-12-09 02:55:46 +0100299 if (IPA_RSL_PORT.checkstate("Connected")) {
300 IPA_RSL_PORT.send(evt);
301 }
Harald Weltedf277252018-02-20 15:49:30 +0100302#endif
Harald Weltec6826662019-02-06 22:26:46 +0100303#ifdef IPA_EMULATION_OML
304 if (IPA_OML_PORT.checkstate("Connected")) {
305 IPA_OML_PORT.send(evt);
306 }
307#endif
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200308#ifdef IPA_EMULATION_CTRL
Harald Welte5819b552017-12-09 02:55:46 +0100309 if (IPA_CTRL_PORT.checkstate("Connected")) {
310 IPA_CTRL_PORT.send(evt);
311 }
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200312#endif
Harald Weltedf277252018-02-20 15:49:30 +0100313#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100314 if (IPA_GSUP_PORT.checkstate("Connected")) {
315 IPA_GSUP_PORT.send(evt);
316 }
Harald Weltedf277252018-02-20 15:49:30 +0100317#endif
Harald Welte7460a722018-10-10 12:28:27 +0200318#ifdef IPA_EMULATION_RSPRO
319 if (IPA_RSPRO_PORT.checkstate("Connected")) {
320 IPA_RSPRO_PORT.send(evt);
321 }
322#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100323 /* FIXME: to other ports */
324}
325
Harald Welted86cdc62017-11-22 00:45:07 +0100326/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100327private 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 +0100328 var integer i;
329 var PDU_IPA_CCM resp := {
330 msg_type := IPAC_MSGT_ID_RESP,
331 u := {
332 resp := {}
333 }
334 }
335
336 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
337 var IpaCcmIdTag tag := get.u.get[i].tag;
338 var charstring foo;
339 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100340 case (IPAC_IDTAG_SERNR) {
341 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100342 }
343 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100344 foo := g_ccm_pars.name;
345 }
346 case (IPAC_IDTAG_LOCATION1) {
347 foo := g_ccm_pars.location1;
348 }
349 case (IPAC_IDTAG_LOCATION2) {
350 foo := g_ccm_pars.location2;
351 }
352 case (IPAC_IDTAG_EQUIPVERS) {
353 foo := g_ccm_pars.equip_version;
354 }
355 case (IPAC_IDTAG_SWVERSION) {
356 foo := g_ccm_pars.sw_version;
357 }
358 case (IPAC_IDTAG_IPADDR) {
359 foo := g_ccm_pars.ip_addr;
360 }
361 case (IPAC_IDTAG_MACADDR) {
362 foo := g_ccm_pars.mac_addr;
363 }
364 case (IPAC_IDTAG_UNIT) {
365 foo := g_ccm_pars.unit_id;
366 }
367 case (IPAC_IDTAG_OSMO_RAND) {
368 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100369 }
370 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100371 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100372 }
373 }
374 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
375 }
376
377 return resp;
378}
379
380/* transmit IPA CCM message */
381private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Weltec82eef42017-11-24 20:40:12 +0100382 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 +0100383 log("CCM Tx:", ccm);
384 IPA_PORT.send(ipa_tx);
385}
386
387template PDU_IPA_CCM ts_IPA_PONG := {
388 msg_type := IPAC_MSGT_PONG,
389 u := omit
390}
391
392template PDU_IPA_CCM ts_IPA_ACK := {
393 msg_type := IPAC_MSGT_ID_ACK,
394 u := omit
395}
396
Harald Welteb3414b22017-11-23 18:22:10 +0100397template PDU_IPA_CCM ts_IPA_ID_GET := {
398 msg_type := IPAC_MSGT_ID_GET,
399 u := {
400 get := {
401 { 1, IPAC_IDTAG_UNITNAME }
402 }
403 }
404}
405
Harald Welted86cdc62017-11-22 00:45:07 +0100406/* receive IPA CCM message */
Harald Welte2d86aff2018-04-17 11:23:04 +0200407private function f_ccm_rx_client(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100408 select (ccm.msg_type) {
409 case (IPAC_MSGT_PING) {
410 f_ccm_tx(valueof(ts_IPA_PONG));
411 }
412 case (IPAC_MSGT_ID_ACK) {
Harald Welte2d86aff2018-04-17 11:23:04 +0200413 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_ID_ACK));
Harald Welted86cdc62017-11-22 00:45:07 +0100414 }
415 case (IPAC_MSGT_ID_GET) {
416 f_ccm_tx(f_ccm_make_id_resp(ccm));
417 }
Harald Welte2d86aff2018-04-17 11:23:04 +0200418 case else {
419 log("Unknown/unsupported IPA CCM message type", ccm);
420 }
421 }
422}
423
424private function f_ccm_rx_server(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
425 select (ccm.msg_type) {
426 case (IPAC_MSGT_PING) {
427 f_ccm_tx(valueof(ts_IPA_PONG));
428 }
429 case (IPAC_MSGT_ID_ACK) {
430 /* the IPA server should at some point receive an ID_ACK from the client,
431 * in case of RSL/OML from nanoBTS, this is actually the first message after
432 * the TCP connection is established. Other implementations may differ.
433 * We currently ignore it completely - but actually we should make sure that
434 * one ID_ACK is received by the server at some point */
Harald Welte2e32e432018-05-24 20:00:00 +0200435 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_ID_ACK));
Harald Welte2d86aff2018-04-17 11:23:04 +0200436 }
Harald Welte3bc387f2018-02-21 12:18:46 +0100437 case (IPAC_MSGT_ID_RESP) {
438 log("IPA ID RESP: ", ccm.u.resp);
Harald Welte2d86aff2018-04-17 11:23:04 +0200439 /* acknowledge any identity that the client may have sent */
440 f_ccm_tx(valueof(ts_IPA_ACK));
Harald Welte3bc387f2018-02-21 12:18:46 +0100441 }
Harald Welted86cdc62017-11-22 00:45:07 +0100442 case else {
443 log("Unknown/unsupported IPA CCM message type", ccm);
444 }
445 }
446}
447
Harald Weltec76f29f2017-11-22 12:46:46 +0100448private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
449 var ASP_IPA_Unitdata ret := {
450 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100451 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100452 payload := ipa_rx.msg
453 }
454 return ret;
455}
456
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100457private function f_from_asp(IPL4asp_Types.ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100458 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
459 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100460 return ret;
461}
Harald Welted86cdc62017-11-22 00:45:07 +0100462
Harald Weltedf277252018-02-20 15:49:30 +0100463#ifdef IPA_EMULATION_RSL
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100464private function f_from_rsl(IPL4asp_Types.ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
Harald Welte0d846a72017-12-07 17:58:28 +0100465 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
466 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
467 return ret;
468}
Harald Weltedf277252018-02-20 15:49:30 +0100469#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100470
Harald Weltec6826662019-02-06 22:26:46 +0100471#ifdef IPA_EMULATION_OML
472private function f_from_oml(IPL4asp_Types.ConnectionId connId, OML_PDU oml_tx) return IPA_Send {
473 var octetstring payload := enc_OML_PDU(oml_tx);
474 var IPA_Send ret := valueof(t_IPA_Send(connId, IPAC_PROTO_OML, payload));
475 return ret;
476}
477#endif
478
Harald Weltebdb63702017-12-09 01:15:44 +0100479/* main function to use for a client-side IPA implementation */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100480function main_client(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
481 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Welte2d86aff2018-04-17 11:23:04 +0200482 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars,
483 boolean ccm_enabled := true) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100484 g_mode := IPA_MODE_CLIENT;
Harald Welte2d86aff2018-04-17 11:23:04 +0200485 g_ccm_enabled := ccm_enabled;
Harald Weltee09921f2017-12-07 17:49:00 +0100486 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welte2d86aff2018-04-17 11:23:04 +0200487 if (g_ccm_enabled) {
488 /* we're a client: Send ID_ACK immediately after connect */
489 f_ccm_tx(valueof(ts_IPA_ACK));
490 }
Harald Welte03c0e562017-12-09 02:55:12 +0100491 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100492 ScanEvents();
493}
494
Harald Weltebdb63702017-12-09 01:15:44 +0100495/* main function to use for a server-side IPA implementation */
Harald Welte2d86aff2018-04-17 11:23:04 +0200496function main_server(charstring local_host, IPL4asp_Types.PortNumber local_port,
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200497 boolean ccm_enabled := true,
498 IpaInitBehavior init_behavior := IPA_INIT_SEND_IPA_ID_GET)
499runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100500 g_mode := IPA_MODE_SERVER;
Harald Welte2d86aff2018-04-17 11:23:04 +0200501 g_ccm_enabled := ccm_enabled;
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200502 g_init_behavior := init_behavior;
Harald Welteb3414b22017-11-23 18:22:10 +0100503 f_bind(local_host, local_port);
504 ScanEvents();
505}
506
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200507#ifdef IPA_EMULATION_CTRL
Harald Weltedf277252018-02-20 15:49:30 +0100508private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
509 var charstring msg_ch := oct2char(msg);
510 IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
511}
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200512#endif
Harald Weltedf277252018-02-20 15:49:30 +0100513
514#ifdef IPA_EMULATION_GSUP
515private function f_gsup_to_user(octetstring msg) runs on IPA_Emulation_CT {
516 var GSUP_PDU gsup := dec_GSUP_PDU(msg);
517 f_gsup_postprocess_decoded(gsup);
518 IPA_GSUP_PORT.send(gsup);
519}
520#endif
521
Harald Welte7460a722018-10-10 12:28:27 +0200522#ifdef IPA_EMULATION_RSPRO
523private function f_rspro_to_user(octetstring msg) runs on IPA_Emulation_CT {
524 var RsproPDU rspro := dec_RsproPDU(msg);
525 IPA_RSPRO_PORT.send(rspro);
526}
527#endif
528
Harald Weltedf277252018-02-20 15:49:30 +0100529#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100530private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
531 var charstring msg_ch := oct2char(msg);
532 if (g_is_bsc_mgw) {
533 log("============");
534 log(msg_ch);
535 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
536 } else {
537 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
538 }
539}
540
Harald Welte92632e12017-11-25 02:31:20 +0100541private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
542 if (mp_ipa_mgcp_uses_osmo_ext) {
543 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
544 } else {
545 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
546 }
547}
Harald Weltedf277252018-02-20 15:49:30 +0100548#endif
Harald Welte92632e12017-11-25 02:31:20 +0100549
Harald Weltebdb63702017-12-09 01:15:44 +0100550/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100551private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100552 var IPA_RecvFrom ipa_rx;
Harald Welteb3414b22017-11-23 18:22:10 +0100553 var ASP_Event asp_evt;
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100554 var Socket_API_Definitions.PortEvent port_evt;
Harald Weltedf277252018-02-20 15:49:30 +0100555 var octetstring payload;
Harald Weltedf277252018-02-20 15:49:30 +0100556 var ASP_IPA_Unitdata ipa_ud;
Harald Welte3286eb32019-08-18 19:36:10 +0200557#ifdef IPA_EMULATION_CTRL
558 var CtrlMessage ctrl_msg;
559#endif
Harald Weltedf277252018-02-20 15:49:30 +0100560#ifdef IPA_EMULATION_SCCP
561 var ASP_MTP3_TRANSFERreq mtp_req;
562#endif
563#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100564 var MgcpCommand mgcp_cmd;
565 var MgcpResponse mgcp_rsp;
Harald Weltedf277252018-02-20 15:49:30 +0100566#endif
567#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100568 var GSUP_PDU gsup_msg;
Harald Weltedf277252018-02-20 15:49:30 +0100569#endif
570#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100571 var ASP_RSL_Unitdata rsl;
Harald Weltedf277252018-02-20 15:49:30 +0100572#endif
Harald Weltec6826662019-02-06 22:26:46 +0100573#ifdef IPA_EMULATION_OML
574 var OML_PDU oml;
575#endif
Harald Welte7460a722018-10-10 12:28:27 +0200576#ifdef IPA_EMULATION_RSPRO
577 var RsproPDU rspro;
578#endif
Harald Welted86cdc62017-11-22 00:45:07 +0100579
Harald Welte3e6ad892017-12-12 14:39:46 +0100580 /* Set function for dissecting the binary */
581 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
582 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});
583
Harald Welted86cdc62017-11-22 00:45:07 +0100584 while (true) {
585 alt {
586 /* Received IPA -> up into SCCP stack */
Harald Welte2d86aff2018-04-17 11:23:04 +0200587 [g_ccm_enabled] IPA_PORT.receive(IPA_RecvFrom:{?,IPAC_PROTO_CCM,omit,?}) -> value ipa_rx {
588 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
589 log("CCM Rx:", ccm);
590 select (g_mode) {
591 case (IPA_MODE_CLIENT) {
592 f_ccm_rx_client(ccm);
593 }
594 case (IPA_MODE_SERVER) {
595 f_ccm_rx_server(ccm);
596 }
597 case else {
598 setverdict(fail, "Unknown mode");
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200599 mtc.stop;
Harald Welte2d86aff2018-04-17 11:23:04 +0200600 }
Harald Weltedf277252018-02-20 15:49:30 +0100601 }
Harald Welte2d86aff2018-04-17 11:23:04 +0200602 }
603 [] IPA_PORT.receive(IPA_RecvFrom:?) -> value ipa_rx {
604 select (ipa_rx.streamId) {
Harald Weltedf277252018-02-20 15:49:30 +0100605#ifdef IPA_EMULATION_SCCP
606 case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100607 var ASP_MTP3_TRANSFERind mtp;
608 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
609 MTP3_SP_PORT.send(mtp);
Harald Weltedf277252018-02-20 15:49:30 +0100610 }
611#endif
612#ifdef IPA_EMULATION_MGCP
613 case (IPAC_PROTO_MGCP_OLD) {
Harald Weltec82eef42017-11-24 20:40:12 +0100614 f_mgcp_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100615 }
616#endif
617#ifdef IPA_EMULATION_RSL
618 case (t_IpaSidRSL) {
Harald Welte0d846a72017-12-07 17:58:28 +0100619 rsl := {
620 streamId := ipa_rx.streamId,
621 rsl := dec_RSL_Message(ipa_rx.msg)
622 };
623 IPA_RSL_PORT.send(rsl);
Harald Weltedf277252018-02-20 15:49:30 +0100624 }
625#endif
Harald Weltec6826662019-02-06 22:26:46 +0100626#ifdef IPA_EMULATION_OML
627 case (IPAC_PROTO_OML) {
628 oml := dec_OML_PDU(ipa_rx.msg)
629 IPA_OML_PORT.send(oml);
630 }
631#endif
Harald Weltedf277252018-02-20 15:49:30 +0100632 case (IPAC_PROTO_OSMO) {
Harald Weltec82eef42017-11-24 20:40:12 +0100633 select (ipa_rx.streamIdExt) {
Harald Weltedf277252018-02-20 15:49:30 +0100634#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100635 case (IPAC_PROTO_EXT_MGCP) {
636 f_mgcp_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100637 }
638#endif
Harald Welte3286eb32019-08-18 19:36:10 +0200639#ifdef IPA_EMULATION_CTRL
Harald Weltedf277252018-02-20 15:49:30 +0100640 case (IPAC_PROTO_EXT_CTRL) {
Harald Weltea76c4bb2017-12-09 02:06:07 +0100641 f_ctrl_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100642 }
Harald Welte3286eb32019-08-18 19:36:10 +0200643#endif
Harald Weltedf277252018-02-20 15:49:30 +0100644#ifdef IPA_EMULATION_GSUP
645 case (IPAC_PROTO_EXT_GSUP) {
Harald Weltedf327232017-12-28 22:51:51 +0100646 f_gsup_to_user(ipa_rx.msg);
Harald Weltedf277252018-02-20 15:49:30 +0100647 }
648#endif
Harald Welte7460a722018-10-10 12:28:27 +0200649#ifdef IPA_EMULATION_RSPRO
650 case (IPAC_PROTO_EXT_RSPRO) {
651 f_rspro_to_user(ipa_rx.msg);
652 }
653#endif
Harald Weltedf277252018-02-20 15:49:30 +0100654 case else {
Harald Weltec82eef42017-11-24 20:40:12 +0100655 IPA_SP_PORT.send(f_to_asp(ipa_rx));
656 }
Harald Welted86cdc62017-11-22 00:45:07 +0100657 }
Harald Weltedf277252018-02-20 15:49:30 +0100658 }
659 case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100660 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100661 }
662 }
663 }
664
Harald Welteb3414b22017-11-23 18:22:10 +0100665 /* server only */
666 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
667 log("IPA: Connected");
668 g_ipa_conn_id := asp_evt.connOpened.connId;
Harald Welte0d846a72017-12-07 17:58:28 +0100669 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welte2d86aff2018-04-17 11:23:04 +0200670 if (g_mode == IPA_MODE_SERVER and g_ccm_enabled) {
Neels Hofmeyr3bf31d22018-08-24 14:44:32 +0200671 select (g_init_behavior) {
672 case (IPA_INIT_SEND_IPA_ID_GET) {
673 f_ccm_tx(valueof(ts_IPA_ID_GET));
674 }
675 case (IPA_INIT_SEND_IPA_ID_ACK) {
676 f_ccm_tx(valueof(ts_IPA_ACK));
677 }
678 }
Harald Welteb3414b22017-11-23 18:22:10 +0100679 }
680 }
681
682 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
683 log("IPA: Closed");
684 g_ipa_conn_id := -1;
Harald Welte0d846a72017-12-07 17:58:28 +0100685 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
Harald Welteb3414b22017-11-23 18:22:10 +0100686 self.stop;
687 }
688
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100689 [] IPA_PORT.receive(Socket_API_Definitions.PortEvent:{result:={errorCode:=ERROR_SOCKET, connId:=?, os_error_code:=?, os_error_text:=?}}) -> value port_evt {
690 log("PortEvent: ERROR_SOCKET: ", port_evt);
691 g_ipa_conn_id := -1;
692 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
693 self.stop;
694 }
695
Harald Weltedf277252018-02-20 15:49:30 +0100696#ifdef IPA_EMULATION_SCCP
Harald Welted86cdc62017-11-22 00:45:07 +0100697 /* Received SCCP -> down into IPA */
698 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Harald Weltec82eef42017-11-24 20:40:12 +0100699 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
700 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100701 IPA_PORT.send(ipa_tx);
702 }
Harald Weltedf277252018-02-20 15:49:30 +0100703#endif
Harald Weltec76f29f2017-11-22 12:46:46 +0100704
Harald Weltedf277252018-02-20 15:49:30 +0100705#ifdef IPA_EMULATION_MGCP
Harald Weltec82eef42017-11-24 20:40:12 +0100706 /* Received MGCP -> down into IPA */
707 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100708 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
709 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100710 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
711 }
712 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100713 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100714 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100715 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
716 }
Harald Weltedf277252018-02-20 15:49:30 +0100717#endif
Harald Weltec82eef42017-11-24 20:40:12 +0100718
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200719#ifdef IPA_EMULATION_CTRL
Harald Weltea76c4bb2017-12-09 02:06:07 +0100720 [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
721 payload := char2oct(enc_CtrlMessage(ctrl_msg));
722 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
723 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
724 }
Pau Espin Pedrolacc51192019-06-11 15:35:19 +0200725#endif
Harald Weltea76c4bb2017-12-09 02:06:07 +0100726
Harald Weltedf277252018-02-20 15:49:30 +0100727#ifdef IPA_EMULATION_GSUP
Harald Weltedf327232017-12-28 22:51:51 +0100728 [] IPA_GSUP_PORT.receive(GSUP_PDU:?) -> value gsup_msg {
Harald Welte2f562b12018-01-24 20:52:38 +0100729 f_gsup_preprocess_encoded(gsup_msg);
Harald Weltedf327232017-12-28 22:51:51 +0100730 payload := enc_GSUP_PDU(gsup_msg);
731 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_GSUP));
732 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
733 }
Harald Weltedf277252018-02-20 15:49:30 +0100734#endif
Harald Weltedf327232017-12-28 22:51:51 +0100735
Harald Welte7460a722018-10-10 12:28:27 +0200736#ifdef IPA_EMULATION_RSPRO
737 [] IPA_RSPRO_PORT.receive(RsproPDU:?) -> value rspro {
738 payload := enc_RsproPDU(rspro);
739 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_RSPRO));
740 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
741 }
742#endif
743
Harald Weltedf277252018-02-20 15:49:30 +0100744#ifdef IPA_EMULATION_RSL
Harald Welte0d846a72017-12-07 17:58:28 +0100745 /* Received RSL -> down into IPA */
746 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
747 IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
748 }
Harald Weltedf277252018-02-20 15:49:30 +0100749#endif
Harald Weltec6826662019-02-06 22:26:46 +0100750#ifdef IPA_EMULATION_OML
751 /* Received OML -> down into IPA */
752 [] IPA_OML_PORT.receive(OML_PDU:?) -> value oml {
753 IPA_PORT.send(f_from_oml(g_ipa_conn_id, oml));
754 }
755 [] IPA_OML_PORT.receive(octetstring:?) -> value payload {
756 IPA_PORT.send(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_OML, payload));
757 }
758#endif
Harald Welte0d846a72017-12-07 17:58:28 +0100759 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100760 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
761 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
762 }
763
764
Harald Welted86cdc62017-11-22 00:45:07 +0100765 }
766 }
767}
768
Harald Welte2e32e432018-05-24 20:00:00 +0200769/***********************************************************************
770 * IPA Event waiter component. Wait for ASP_IPA_EVENT_ID_ACK
771 ***********************************************************************/
772
773type component IPA_EventWaiter_CT {
774 port IPA_SP_PT IPA_SP_PORT;
775}
776
777function waiter_main(template ASP_IPA_Event wait_for := t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_ID_ACK))
778runs on IPA_EventWaiter_CT {
779
780 alt {
781 [] IPA_SP_PORT.receive(wait_for) {
782 setverdict(pass);
783 }
784 [] IPA_SP_PORT.receive { repeat; }
785 }
786}
787
788
Harald Welted86cdc62017-11-22 00:45:07 +0100789}