blob: 53a86ecd1dbfb2d9452b76f1ce6fcf58c0e69116 [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
Harald Welte35bb7162018-01-03 21:07:52 +01005 * handshake for establishing the identity of the client to the server.
6 *
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 *
11 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
12 * All rights reserved.
13 *
14 * Released under the terms of GNU General Public License, Version 2 or
15 * (at your option) any later version.
16 */
Harald Weltebdb63702017-12-09 01:15:44 +010017
Harald Welted86cdc62017-11-22 00:45:07 +010018import from IPA_Types all;
19import from IPA_CodecPort all;
20import from IPA_CodecPort_CtrlFunct all;
21import from IPL4asp_Types all;
Harald Welte12188832017-11-29 11:47:13 +010022import from IPL4asp_PortType all;
Harald Welted86cdc62017-11-22 00:45:07 +010023import from MTP3asp_Types all;
24import from MTP3asp_PortType all;
Harald Welte0d846a72017-12-07 17:58:28 +010025import from RSL_Types all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010026import from Socket_API_Definitions all;
Harald Welted86cdc62017-11-22 00:45:07 +010027
Harald Weltec82eef42017-11-24 20:40:12 +010028import from MGCP_Types all;
Harald Weltedf327232017-12-28 22:51:51 +010029import from GSUP_Types all;
Harald Weltec82eef42017-11-24 20:40:12 +010030
Harald Weltea76c4bb2017-12-09 02:06:07 +010031import from Osmocom_CTRL_Types all;
32
Harald Welted86cdc62017-11-22 00:45:07 +010033modulepar {
Harald Welte92632e12017-11-25 02:31:20 +010034 /* Use Osmocom extended IPA mux header */
35 boolean mp_ipa_mgcp_uses_osmo_ext := true;
Harald Welted86cdc62017-11-22 00:45:07 +010036}
Harald Welted86cdc62017-11-22 00:45:07 +010037
Harald Welteb3414b22017-11-23 18:22:10 +010038type enumerated IpaMode {
39 IPA_MODE_CLIENT,
40 IPA_MODE_SERVER
41}
42
Harald Weltec76f29f2017-11-22 12:46:46 +010043type record ASP_IPA_Unitdata {
44 IpaStreamId streamId,
Harald Weltec82eef42017-11-24 20:40:12 +010045 IpaExtStreamId streamIdExt optional,
Harald Weltec76f29f2017-11-22 12:46:46 +010046 octetstring payload
47}
48
Harald Welte0d846a72017-12-07 17:58:28 +010049type enumerated ASP_IPA_EventUpDown {
50 ASP_IPA_EVENT_DOWN,
51 ASP_IPA_EVENT_UP,
52 ASP_IPA_EVENT_ID_ACK
53}
54
Harald Weltebdb63702017-12-09 01:15:44 +010055/* an event indicating us whether or not a connection is physically up or down,
56 * and whether we have received an ID_ACK */
Harald Welte0d846a72017-12-07 17:58:28 +010057type union ASP_IPA_Event {
58 ASP_IPA_EventUpDown up_down
59}
60
61template ASP_IPA_Event t_ASP_IPA_EVT_UD(ASP_IPA_EventUpDown ud) := {
62 up_down := ud
63}
64
Harald Welte1dd8f372017-11-25 02:25:27 +010065template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
66 template IpaExtStreamId esid := omit) := {
67 streamId := sid,
68 streamIdExt := esid,
69 payload := pl
70}
71
Harald Weltebdb63702017-12-09 01:15:44 +010072/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +010073type record ASP_RSL_Unitdata {
74 IpaStreamId streamId,
75 RSL_Message rsl
76};
77
Harald Welte7ae019e2017-12-09 00:54:15 +010078template ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
Harald Welte0d846a72017-12-07 17:58:28 +010079 streamId := sid,
80 rsl := valueof(rsl)
81}
82
Harald Welte7ae019e2017-12-09 00:54:15 +010083template ASP_RSL_Unitdata tr_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
84 streamId := sid,
85 rsl := rsl
86}
87
88
Harald Welte0d846a72017-12-07 17:58:28 +010089template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
90 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
91
Harald Weltebdb63702017-12-09 01:15:44 +010092/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +010093type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +010094 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +010095} with { extension "internal" }
96
Harald Weltebdb63702017-12-09 01:15:44 +010097/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +010098type port IPA_MGCP_PT message {
99 inout MgcpCommand, MgcpResponse;
100} with { extension "internal" }
101
Harald Weltebdb63702017-12-09 01:15:44 +0100102/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +0100103type port IPA_RSL_PT message {
104 inout ASP_RSL_Unitdata, ASP_IPA_Event;
105} with { extension "internal" }
106
Harald Weltea76c4bb2017-12-09 02:06:07 +0100107/* Client port for CTRL inside IPA */
108type port IPA_CTRL_PT message {
109 inout CtrlMessage, ASP_IPA_Event;
110} with { extension "internal" }
111
Harald Weltedf327232017-12-28 22:51:51 +0100112/* Client port for CTRL inside IPA */
113type port IPA_GSUP_PT message {
114 inout GSUP_PDU, ASP_IPA_Event;
115} with { extension "internal" }
116
117
Harald Welted86cdc62017-11-22 00:45:07 +0100118type component IPA_Emulation_CT {
119 /* down-facing port to IPA codec port */
120 port IPA_CODEC_PT IPA_PORT;
121 /* up-facing port to SCCP */
122 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltec82eef42017-11-24 20:40:12 +0100123 /* up-facing port for MGCP */
124 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Welte0d846a72017-12-07 17:58:28 +0100125 /* up-facing port for RSL */
126 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100127 /* up-facing port for CTRL */
128 port IPA_CTRL_PT IPA_CTRL_PORT;
Harald Weltedf327232017-12-28 22:51:51 +0100129 /* up-facing port for GSUP */
130 port IPA_GSUP_PT IPA_GSUP_PORT;
131
Harald Weltec76f29f2017-11-22 12:46:46 +0100132 /* up-facing port for other streams */
133 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100134
135 var boolean g_initialized := false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100136 var IPL4asp_Types.ConnectionId g_ipa_conn_id := -1;
Harald Weltec82eef42017-11-24 20:40:12 +0100137 /* Are we a BSC/MGW (truel) or MSC (false) */
138 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100139
140 var IpaMode g_mode;
Harald Weltee09921f2017-12-07 17:49:00 +0100141 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100142}
143
Harald Weltee21096d2017-12-04 20:45:12 +0100144type record IPA_CCM_Parameters {
145 charstring ser_nr optional,
146 charstring name optional,
147 charstring location1 optional,
148 charstring location2 optional,
149 charstring equip_version optional,
150 charstring sw_version optional,
151 charstring ip_addr optional,
152 charstring mac_addr optional,
153 charstring unit_id optional,
154 charstring osmo_rand optional
155}
156
Harald Weltee09921f2017-12-07 17:49:00 +0100157const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
158 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100159 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100160 location1 := "",
161 location2 := "",
162 equip_version := "",
163 sw_version := "",
164 ip_addr := "",
165 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100166 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100167 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100168};
169
Harald Weltebdb63702017-12-09 01:15:44 +0100170/* Function to use to connect as client to a remote IPA Server */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100171function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
172 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100173 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100174 var IPL4asp_Types.Result res;
Harald Welted86cdc62017-11-22 00:45:07 +0100175 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
176 local_host, local_port, 0, { tcp:={} });
177 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100178 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100179 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100180}
181
Harald Weltebdb63702017-12-09 01:15:44 +0100182/* Function to use to bind to a local port as IPA server, accepting remote clients */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100183function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100184 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100185 var IPL4asp_Types.Result res;
Harald Welteb3414b22017-11-23 18:22:10 +0100186 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
187 local_host, local_port, { tcp:={} });
188 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100189 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100190 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100191}
192
Harald Welted86cdc62017-11-22 00:45:07 +0100193template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
194 sio := { '10'B, '00'B, '0011'B },
195 opc := opc,
196 dpc := 0,
197 sls := 0,
198 data := data
199}
200
201
202private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
203 len := 0, /* overwritten by codec */
204 tag := tag,
205 data := payload
206}
207
Harald Welte0d846a72017-12-07 17:58:28 +0100208private function f_send_IPA_EVT(template ASP_IPA_Event evt) runs on IPA_Emulation_CT {
Harald Welte5819b552017-12-09 02:55:46 +0100209 if (IPA_RSL_PORT.checkstate("Connected")) {
210 IPA_RSL_PORT.send(evt);
211 }
212 if (IPA_CTRL_PORT.checkstate("Connected")) {
213 IPA_CTRL_PORT.send(evt);
214 }
Harald Weltedf327232017-12-28 22:51:51 +0100215 if (IPA_GSUP_PORT.checkstate("Connected")) {
216 IPA_GSUP_PORT.send(evt);
217 }
Harald Welte0d846a72017-12-07 17:58:28 +0100218 /* FIXME: to other ports */
219}
220
Harald Welted86cdc62017-11-22 00:45:07 +0100221/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100222private 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 +0100223 var integer i;
224 var PDU_IPA_CCM resp := {
225 msg_type := IPAC_MSGT_ID_RESP,
226 u := {
227 resp := {}
228 }
229 }
230
231 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
232 var IpaCcmIdTag tag := get.u.get[i].tag;
233 var charstring foo;
234 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100235 case (IPAC_IDTAG_SERNR) {
236 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100237 }
238 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100239 foo := g_ccm_pars.name;
240 }
241 case (IPAC_IDTAG_LOCATION1) {
242 foo := g_ccm_pars.location1;
243 }
244 case (IPAC_IDTAG_LOCATION2) {
245 foo := g_ccm_pars.location2;
246 }
247 case (IPAC_IDTAG_EQUIPVERS) {
248 foo := g_ccm_pars.equip_version;
249 }
250 case (IPAC_IDTAG_SWVERSION) {
251 foo := g_ccm_pars.sw_version;
252 }
253 case (IPAC_IDTAG_IPADDR) {
254 foo := g_ccm_pars.ip_addr;
255 }
256 case (IPAC_IDTAG_MACADDR) {
257 foo := g_ccm_pars.mac_addr;
258 }
259 case (IPAC_IDTAG_UNIT) {
260 foo := g_ccm_pars.unit_id;
261 }
262 case (IPAC_IDTAG_OSMO_RAND) {
263 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100264 }
265 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100266 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100267 }
268 }
269 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
270 }
271
272 return resp;
273}
274
275/* transmit IPA CCM message */
276private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Weltec82eef42017-11-24 20:40:12 +0100277 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 +0100278 log("CCM Tx:", ccm);
279 IPA_PORT.send(ipa_tx);
280}
281
282template PDU_IPA_CCM ts_IPA_PONG := {
283 msg_type := IPAC_MSGT_PONG,
284 u := omit
285}
286
287template PDU_IPA_CCM ts_IPA_ACK := {
288 msg_type := IPAC_MSGT_ID_ACK,
289 u := omit
290}
291
Harald Welteb3414b22017-11-23 18:22:10 +0100292template PDU_IPA_CCM ts_IPA_ID_GET := {
293 msg_type := IPAC_MSGT_ID_GET,
294 u := {
295 get := {
296 { 1, IPAC_IDTAG_UNITNAME }
297 }
298 }
299}
300
Harald Welted86cdc62017-11-22 00:45:07 +0100301/* receive IPA CCM message */
302private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
303 select (ccm.msg_type) {
304 case (IPAC_MSGT_PING) {
305 f_ccm_tx(valueof(ts_IPA_PONG));
306 }
307 case (IPAC_MSGT_ID_ACK) {
308 f_ccm_tx(valueof(ts_IPA_ACK));
309 }
310 case (IPAC_MSGT_ID_GET) {
311 f_ccm_tx(f_ccm_make_id_resp(ccm));
312 }
313 case else {
314 log("Unknown/unsupported IPA CCM message type", ccm);
315 }
316 }
317}
318
Harald Weltec76f29f2017-11-22 12:46:46 +0100319private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
320 var ASP_IPA_Unitdata ret := {
321 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100322 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100323 payload := ipa_rx.msg
324 }
325 return ret;
326}
327
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100328private function f_from_asp(IPL4asp_Types.ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100329 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
330 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100331 return ret;
332}
Harald Welted86cdc62017-11-22 00:45:07 +0100333
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100334private function f_from_rsl(IPL4asp_Types.ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
Harald Welte0d846a72017-12-07 17:58:28 +0100335 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
336 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
337 return ret;
338}
339
Harald Weltebdb63702017-12-09 01:15:44 +0100340/* main function to use for a client-side IPA implementation */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100341function main_client(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
342 charstring local_host, IPL4asp_Types.PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100343 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100344 g_mode := IPA_MODE_CLIENT;
Harald Weltee09921f2017-12-07 17:49:00 +0100345 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welte03c0e562017-12-09 02:55:12 +0100346 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100347 ScanEvents();
348}
349
Harald Weltebdb63702017-12-09 01:15:44 +0100350/* main function to use for a server-side IPA implementation */
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100351function main_server(charstring local_host, IPL4asp_Types.PortNumber local_port) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100352 g_mode := IPA_MODE_SERVER;
353 f_bind(local_host, local_port);
354 ScanEvents();
355}
356
Harald Weltec82eef42017-11-24 20:40:12 +0100357private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
358 var charstring msg_ch := oct2char(msg);
359 if (g_is_bsc_mgw) {
360 log("============");
361 log(msg_ch);
362 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
363 } else {
364 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
365 }
366}
367
Harald Weltea76c4bb2017-12-09 02:06:07 +0100368private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
369 var charstring msg_ch := oct2char(msg);
370 IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
371}
372
Harald Weltedf327232017-12-28 22:51:51 +0100373private function f_gsup_to_user(octetstring msg) runs on IPA_Emulation_CT {
Harald Welte2f562b12018-01-24 20:52:38 +0100374 var GSUP_PDU gsup := dec_GSUP_PDU(msg);
375 f_gsup_postprocess_decoded(gsup);
376 IPA_GSUP_PORT.send(gsup);
Harald Weltedf327232017-12-28 22:51:51 +0100377}
378
Harald Welte92632e12017-11-25 02:31:20 +0100379private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
380 if (mp_ipa_mgcp_uses_osmo_ext) {
381 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
382 } else {
383 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
384 }
385}
386
Harald Weltebdb63702017-12-09 01:15:44 +0100387/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100388private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100389 var IPA_RecvFrom ipa_rx;
Harald Weltec76f29f2017-11-22 12:46:46 +0100390 var ASP_IPA_Unitdata ipa_ud;
Harald Welted86cdc62017-11-22 00:45:07 +0100391 var ASP_MTP3_TRANSFERreq mtp_req;
Harald Welteb3414b22017-11-23 18:22:10 +0100392 var ASP_Event asp_evt;
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100393 var Socket_API_Definitions.PortEvent port_evt;
Harald Weltec82eef42017-11-24 20:40:12 +0100394 var MgcpCommand mgcp_cmd;
395 var MgcpResponse mgcp_rsp;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100396 var CtrlMessage ctrl_msg;
Harald Weltedf327232017-12-28 22:51:51 +0100397 var GSUP_PDU gsup_msg;
Harald Welte1dd8f372017-11-25 02:25:27 +0100398 var octetstring payload;
Harald Welte0d846a72017-12-07 17:58:28 +0100399 var ASP_RSL_Unitdata rsl;
Harald Welted86cdc62017-11-22 00:45:07 +0100400
Harald Welte3e6ad892017-12-12 14:39:46 +0100401 /* Set function for dissecting the binary */
402 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
403 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});
404
Harald Welted86cdc62017-11-22 00:45:07 +0100405 while (true) {
406 alt {
407 /* Received IPA -> up into SCCP stack */
408 [] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
409 select (ipa_rx.streamId) {
410 case (IPAC_PROTO_CCM) {
411 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
412 log("CCM Rx:", ccm);
413 f_ccm_rx(ccm);
Harald Weltec82eef42017-11-24 20:40:12 +0100414 } case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100415 var ASP_MTP3_TRANSFERind mtp;
416 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
417 MTP3_SP_PORT.send(mtp);
Harald Weltec82eef42017-11-24 20:40:12 +0100418 } case (IPAC_PROTO_MGCP_OLD) {
419 f_mgcp_to_user(ipa_rx.msg);
Harald Welte0d846a72017-12-07 17:58:28 +0100420 } case (t_IpaSidRSL) {
421 rsl := {
422 streamId := ipa_rx.streamId,
423 rsl := dec_RSL_Message(ipa_rx.msg)
424 };
425 IPA_RSL_PORT.send(rsl);
Harald Weltec82eef42017-11-24 20:40:12 +0100426 } case (IPAC_PROTO_OSMO) {
427 select (ipa_rx.streamIdExt) {
428 case (IPAC_PROTO_EXT_MGCP) {
429 f_mgcp_to_user(ipa_rx.msg);
Harald Weltea76c4bb2017-12-09 02:06:07 +0100430 } case (IPAC_PROTO_EXT_CTRL) {
431 f_ctrl_to_user(ipa_rx.msg);
Harald Weltedf327232017-12-28 22:51:51 +0100432 } case (IPAC_PROTO_EXT_GSUP) {
433 f_gsup_to_user(ipa_rx.msg);
Harald Weltec82eef42017-11-24 20:40:12 +0100434 } case else {
435 IPA_SP_PORT.send(f_to_asp(ipa_rx));
436 }
Harald Welted86cdc62017-11-22 00:45:07 +0100437 }
Harald Weltec82eef42017-11-24 20:40:12 +0100438 } case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100439 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100440 }
441 }
442 }
443
Harald Welteb3414b22017-11-23 18:22:10 +0100444 /* server only */
445 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
446 log("IPA: Connected");
447 g_ipa_conn_id := asp_evt.connOpened.connId;
Harald Welte0d846a72017-12-07 17:58:28 +0100448 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100449 if (g_mode == IPA_MODE_SERVER) {
450 f_ccm_tx(valueof(ts_IPA_ID_GET));
451 }
452 }
453
454 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
455 log("IPA: Closed");
456 g_ipa_conn_id := -1;
Harald Welte0d846a72017-12-07 17:58:28 +0100457 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
Harald Welteb3414b22017-11-23 18:22:10 +0100458 self.stop;
459 }
460
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100461 [] IPA_PORT.receive(Socket_API_Definitions.PortEvent:{result:={errorCode:=ERROR_SOCKET, connId:=?, os_error_code:=?, os_error_text:=?}}) -> value port_evt {
462 log("PortEvent: ERROR_SOCKET: ", port_evt);
463 g_ipa_conn_id := -1;
464 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
465 self.stop;
466 }
467
Harald Welted86cdc62017-11-22 00:45:07 +0100468 /* Received SCCP -> down into IPA */
469 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Harald Weltec82eef42017-11-24 20:40:12 +0100470 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
471 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100472 IPA_PORT.send(ipa_tx);
473 }
Harald Weltec76f29f2017-11-22 12:46:46 +0100474
Harald Weltec82eef42017-11-24 20:40:12 +0100475 /* Received MGCP -> down into IPA */
476 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100477 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
478 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100479 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
480 }
481 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100482 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100483 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100484 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
485 }
486
Harald Weltea76c4bb2017-12-09 02:06:07 +0100487 [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
488 payload := char2oct(enc_CtrlMessage(ctrl_msg));
489 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
490 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
491 }
492
Harald Weltedf327232017-12-28 22:51:51 +0100493 [] IPA_GSUP_PORT.receive(GSUP_PDU:?) -> value gsup_msg {
Harald Welte2f562b12018-01-24 20:52:38 +0100494 f_gsup_preprocess_encoded(gsup_msg);
Harald Weltedf327232017-12-28 22:51:51 +0100495 payload := enc_GSUP_PDU(gsup_msg);
496 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_GSUP));
497 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
498 }
499
Harald Welte0d846a72017-12-07 17:58:28 +0100500 /* Received RSL -> down into IPA */
501 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
502 IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
503 }
Harald Weltec82eef42017-11-24 20:40:12 +0100504
Harald Welte0d846a72017-12-07 17:58:28 +0100505
506 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100507 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
508 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
509 }
510
511
Harald Welted86cdc62017-11-22 00:45:07 +0100512 }
513 }
514}
515
516}