blob: b3e28e93e4cef72fb225ab7fa41f4f618a7c0be9 [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;
Harald Welted86cdc62017-11-22 00:45:07 +010026
Harald Weltec82eef42017-11-24 20:40:12 +010027import from MGCP_Types all;
Harald Weltedf327232017-12-28 22:51:51 +010028import from GSUP_Types all;
Harald Weltec82eef42017-11-24 20:40:12 +010029
Harald Weltea76c4bb2017-12-09 02:06:07 +010030import from Osmocom_CTRL_Types all;
31
Harald Welted86cdc62017-11-22 00:45:07 +010032modulepar {
Harald Welte92632e12017-11-25 02:31:20 +010033 /* Use Osmocom extended IPA mux header */
34 boolean mp_ipa_mgcp_uses_osmo_ext := true;
Harald Welted86cdc62017-11-22 00:45:07 +010035}
Harald Welted86cdc62017-11-22 00:45:07 +010036
Harald Welteb3414b22017-11-23 18:22:10 +010037type enumerated IpaMode {
38 IPA_MODE_CLIENT,
39 IPA_MODE_SERVER
40}
41
Harald Weltec76f29f2017-11-22 12:46:46 +010042type record ASP_IPA_Unitdata {
43 IpaStreamId streamId,
Harald Weltec82eef42017-11-24 20:40:12 +010044 IpaExtStreamId streamIdExt optional,
Harald Weltec76f29f2017-11-22 12:46:46 +010045 octetstring payload
46}
47
Harald Welte0d846a72017-12-07 17:58:28 +010048type enumerated ASP_IPA_EventUpDown {
49 ASP_IPA_EVENT_DOWN,
50 ASP_IPA_EVENT_UP,
51 ASP_IPA_EVENT_ID_ACK
52}
53
Harald Weltebdb63702017-12-09 01:15:44 +010054/* an event indicating us whether or not a connection is physically up or down,
55 * and whether we have received an ID_ACK */
Harald Welte0d846a72017-12-07 17:58:28 +010056type union ASP_IPA_Event {
57 ASP_IPA_EventUpDown up_down
58}
59
60template ASP_IPA_Event t_ASP_IPA_EVT_UD(ASP_IPA_EventUpDown ud) := {
61 up_down := ud
62}
63
Harald Welte1dd8f372017-11-25 02:25:27 +010064template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
65 template IpaExtStreamId esid := omit) := {
66 streamId := sid,
67 streamIdExt := esid,
68 payload := pl
69}
70
Harald Weltebdb63702017-12-09 01:15:44 +010071/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +010072type record ASP_RSL_Unitdata {
73 IpaStreamId streamId,
74 RSL_Message rsl
75};
76
Harald Welte7ae019e2017-12-09 00:54:15 +010077template ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
Harald Welte0d846a72017-12-07 17:58:28 +010078 streamId := sid,
79 rsl := valueof(rsl)
80}
81
Harald Welte7ae019e2017-12-09 00:54:15 +010082template ASP_RSL_Unitdata tr_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
83 streamId := sid,
84 rsl := rsl
85}
86
87
Harald Welte0d846a72017-12-07 17:58:28 +010088template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
89 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
90
Harald Weltebdb63702017-12-09 01:15:44 +010091/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +010092type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +010093 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +010094} with { extension "internal" }
95
Harald Weltebdb63702017-12-09 01:15:44 +010096/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +010097type port IPA_MGCP_PT message {
98 inout MgcpCommand, MgcpResponse;
99} with { extension "internal" }
100
Harald Weltebdb63702017-12-09 01:15:44 +0100101/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +0100102type port IPA_RSL_PT message {
103 inout ASP_RSL_Unitdata, ASP_IPA_Event;
104} with { extension "internal" }
105
Harald Weltea76c4bb2017-12-09 02:06:07 +0100106/* Client port for CTRL inside IPA */
107type port IPA_CTRL_PT message {
108 inout CtrlMessage, ASP_IPA_Event;
109} with { extension "internal" }
110
Harald Weltedf327232017-12-28 22:51:51 +0100111/* Client port for CTRL inside IPA */
112type port IPA_GSUP_PT message {
113 inout GSUP_PDU, ASP_IPA_Event;
114} with { extension "internal" }
115
116
Harald Welted86cdc62017-11-22 00:45:07 +0100117type component IPA_Emulation_CT {
118 /* down-facing port to IPA codec port */
119 port IPA_CODEC_PT IPA_PORT;
120 /* up-facing port to SCCP */
121 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltec82eef42017-11-24 20:40:12 +0100122 /* up-facing port for MGCP */
123 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Welte0d846a72017-12-07 17:58:28 +0100124 /* up-facing port for RSL */
125 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100126 /* up-facing port for CTRL */
127 port IPA_CTRL_PT IPA_CTRL_PORT;
Harald Weltedf327232017-12-28 22:51:51 +0100128 /* up-facing port for GSUP */
129 port IPA_GSUP_PT IPA_GSUP_PORT;
130
Harald Weltec76f29f2017-11-22 12:46:46 +0100131 /* up-facing port for other streams */
132 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100133
134 var boolean g_initialized := false;
135 var ConnectionId g_ipa_conn_id := -1;
Harald Weltec82eef42017-11-24 20:40:12 +0100136 /* Are we a BSC/MGW (truel) or MSC (false) */
137 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100138
139 var IpaMode g_mode;
Harald Weltee09921f2017-12-07 17:49:00 +0100140 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100141}
142
Harald Weltee21096d2017-12-04 20:45:12 +0100143type record IPA_CCM_Parameters {
144 charstring ser_nr optional,
145 charstring name optional,
146 charstring location1 optional,
147 charstring location2 optional,
148 charstring equip_version optional,
149 charstring sw_version optional,
150 charstring ip_addr optional,
151 charstring mac_addr optional,
152 charstring unit_id optional,
153 charstring osmo_rand optional
154}
155
Harald Weltee09921f2017-12-07 17:49:00 +0100156const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
157 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100158 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100159 location1 := "",
160 location2 := "",
161 equip_version := "",
162 sw_version := "",
163 ip_addr := "",
164 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100165 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100166 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100167};
168
Harald Weltebdb63702017-12-09 01:15:44 +0100169/* Function to use to connect as client to a remote IPA Server */
Harald Welted86cdc62017-11-22 00:45:07 +0100170function f_connect(charstring remote_host, PortNumber remote_port,
Harald Weltee21096d2017-12-04 20:45:12 +0100171 charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100172 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100173 var Result res;
174 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
175 local_host, local_port, 0, { tcp:={} });
176 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100177 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100178 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100179}
180
Harald Weltebdb63702017-12-09 01:15:44 +0100181/* Function to use to bind to a local port as IPA server, accepting remote clients */
Harald Weltee21096d2017-12-04 20:45:12 +0100182function f_bind(charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100183 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100184 var Result res;
185 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
186 local_host, local_port, { tcp:={} });
187 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100188 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100189 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100190}
191
Harald Welted86cdc62017-11-22 00:45:07 +0100192template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
193 sio := { '10'B, '00'B, '0011'B },
194 opc := opc,
195 dpc := 0,
196 sls := 0,
197 data := data
198}
199
200
201private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
202 len := 0, /* overwritten by codec */
203 tag := tag,
204 data := payload
205}
206
Harald Welte0d846a72017-12-07 17:58:28 +0100207private function f_send_IPA_EVT(template ASP_IPA_Event evt) runs on IPA_Emulation_CT {
Harald Welte5819b552017-12-09 02:55:46 +0100208 if (IPA_RSL_PORT.checkstate("Connected")) {
209 IPA_RSL_PORT.send(evt);
210 }
211 if (IPA_CTRL_PORT.checkstate("Connected")) {
212 IPA_CTRL_PORT.send(evt);
213 }
Harald Weltedf327232017-12-28 22:51:51 +0100214 if (IPA_GSUP_PORT.checkstate("Connected")) {
215 IPA_GSUP_PORT.send(evt);
216 }
Harald Welte0d846a72017-12-07 17:58:28 +0100217 /* FIXME: to other ports */
218}
219
Harald Welted86cdc62017-11-22 00:45:07 +0100220/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100221private 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 +0100222 var integer i;
223 var PDU_IPA_CCM resp := {
224 msg_type := IPAC_MSGT_ID_RESP,
225 u := {
226 resp := {}
227 }
228 }
229
230 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
231 var IpaCcmIdTag tag := get.u.get[i].tag;
232 var charstring foo;
233 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100234 case (IPAC_IDTAG_SERNR) {
235 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100236 }
237 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100238 foo := g_ccm_pars.name;
239 }
240 case (IPAC_IDTAG_LOCATION1) {
241 foo := g_ccm_pars.location1;
242 }
243 case (IPAC_IDTAG_LOCATION2) {
244 foo := g_ccm_pars.location2;
245 }
246 case (IPAC_IDTAG_EQUIPVERS) {
247 foo := g_ccm_pars.equip_version;
248 }
249 case (IPAC_IDTAG_SWVERSION) {
250 foo := g_ccm_pars.sw_version;
251 }
252 case (IPAC_IDTAG_IPADDR) {
253 foo := g_ccm_pars.ip_addr;
254 }
255 case (IPAC_IDTAG_MACADDR) {
256 foo := g_ccm_pars.mac_addr;
257 }
258 case (IPAC_IDTAG_UNIT) {
259 foo := g_ccm_pars.unit_id;
260 }
261 case (IPAC_IDTAG_OSMO_RAND) {
262 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100263 }
264 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100265 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100266 }
267 }
268 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
269 }
270
271 return resp;
272}
273
274/* transmit IPA CCM message */
275private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Weltec82eef42017-11-24 20:40:12 +0100276 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 +0100277 log("CCM Tx:", ccm);
278 IPA_PORT.send(ipa_tx);
279}
280
281template PDU_IPA_CCM ts_IPA_PONG := {
282 msg_type := IPAC_MSGT_PONG,
283 u := omit
284}
285
286template PDU_IPA_CCM ts_IPA_ACK := {
287 msg_type := IPAC_MSGT_ID_ACK,
288 u := omit
289}
290
Harald Welteb3414b22017-11-23 18:22:10 +0100291template PDU_IPA_CCM ts_IPA_ID_GET := {
292 msg_type := IPAC_MSGT_ID_GET,
293 u := {
294 get := {
295 { 1, IPAC_IDTAG_UNITNAME }
296 }
297 }
298}
299
Harald Welted86cdc62017-11-22 00:45:07 +0100300/* receive IPA CCM message */
301private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
302 select (ccm.msg_type) {
303 case (IPAC_MSGT_PING) {
304 f_ccm_tx(valueof(ts_IPA_PONG));
305 }
306 case (IPAC_MSGT_ID_ACK) {
307 f_ccm_tx(valueof(ts_IPA_ACK));
308 }
309 case (IPAC_MSGT_ID_GET) {
310 f_ccm_tx(f_ccm_make_id_resp(ccm));
311 }
312 case else {
313 log("Unknown/unsupported IPA CCM message type", ccm);
314 }
315 }
316}
317
Harald Weltec76f29f2017-11-22 12:46:46 +0100318private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
319 var ASP_IPA_Unitdata ret := {
320 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100321 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100322 payload := ipa_rx.msg
323 }
324 return ret;
325}
326
327private function f_from_asp(ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100328 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
329 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100330 return ret;
331}
Harald Welted86cdc62017-11-22 00:45:07 +0100332
Harald Welte0d846a72017-12-07 17:58:28 +0100333private function f_from_rsl(ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
334 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
335 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
336 return ret;
337}
338
Harald Weltebdb63702017-12-09 01:15:44 +0100339/* main function to use for a client-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100340function main_client(charstring remote_host, PortNumber remote_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100341 charstring local_host, PortNumber local_port,
342 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100343 g_mode := IPA_MODE_CLIENT;
Harald Weltee09921f2017-12-07 17:49:00 +0100344 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welte03c0e562017-12-09 02:55:12 +0100345 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100346 ScanEvents();
347}
348
Harald Weltebdb63702017-12-09 01:15:44 +0100349/* main function to use for a server-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100350function main_server(charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
351 g_mode := IPA_MODE_SERVER;
352 f_bind(local_host, local_port);
353 ScanEvents();
354}
355
Harald Weltec82eef42017-11-24 20:40:12 +0100356private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
357 var charstring msg_ch := oct2char(msg);
358 if (g_is_bsc_mgw) {
359 log("============");
360 log(msg_ch);
361 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
362 } else {
363 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
364 }
365}
366
Harald Weltea76c4bb2017-12-09 02:06:07 +0100367private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
368 var charstring msg_ch := oct2char(msg);
369 IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
370}
371
Harald Weltedf327232017-12-28 22:51:51 +0100372private function f_gsup_to_user(octetstring msg) runs on IPA_Emulation_CT {
Harald Welte2f562b12018-01-24 20:52:38 +0100373 var GSUP_PDU gsup := dec_GSUP_PDU(msg);
374 f_gsup_postprocess_decoded(gsup);
375 IPA_GSUP_PORT.send(gsup);
Harald Weltedf327232017-12-28 22:51:51 +0100376}
377
Harald Welte92632e12017-11-25 02:31:20 +0100378private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
379 if (mp_ipa_mgcp_uses_osmo_ext) {
380 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
381 } else {
382 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
383 }
384}
385
Harald Weltebdb63702017-12-09 01:15:44 +0100386/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100387private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100388 var IPA_RecvFrom ipa_rx;
Harald Weltec76f29f2017-11-22 12:46:46 +0100389 var ASP_IPA_Unitdata ipa_ud;
Harald Welted86cdc62017-11-22 00:45:07 +0100390 var ASP_MTP3_TRANSFERreq mtp_req;
Harald Welteb3414b22017-11-23 18:22:10 +0100391 var ASP_Event asp_evt;
Harald Weltec82eef42017-11-24 20:40:12 +0100392 var MgcpCommand mgcp_cmd;
393 var MgcpResponse mgcp_rsp;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100394 var CtrlMessage ctrl_msg;
Harald Weltedf327232017-12-28 22:51:51 +0100395 var GSUP_PDU gsup_msg;
Harald Welte1dd8f372017-11-25 02:25:27 +0100396 var octetstring payload;
Harald Welte0d846a72017-12-07 17:58:28 +0100397 var ASP_RSL_Unitdata rsl;
Harald Welted86cdc62017-11-22 00:45:07 +0100398
Harald Welte3e6ad892017-12-12 14:39:46 +0100399 /* Set function for dissecting the binary */
400 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
401 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});
402
Harald Welted86cdc62017-11-22 00:45:07 +0100403 while (true) {
404 alt {
405 /* Received IPA -> up into SCCP stack */
406 [] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
407 select (ipa_rx.streamId) {
408 case (IPAC_PROTO_CCM) {
409 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
410 log("CCM Rx:", ccm);
411 f_ccm_rx(ccm);
Harald Weltec82eef42017-11-24 20:40:12 +0100412 } case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100413 var ASP_MTP3_TRANSFERind mtp;
414 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
415 MTP3_SP_PORT.send(mtp);
Harald Weltec82eef42017-11-24 20:40:12 +0100416 } case (IPAC_PROTO_MGCP_OLD) {
417 f_mgcp_to_user(ipa_rx.msg);
Harald Welte0d846a72017-12-07 17:58:28 +0100418 } case (t_IpaSidRSL) {
419 rsl := {
420 streamId := ipa_rx.streamId,
421 rsl := dec_RSL_Message(ipa_rx.msg)
422 };
423 IPA_RSL_PORT.send(rsl);
Harald Weltec82eef42017-11-24 20:40:12 +0100424 } case (IPAC_PROTO_OSMO) {
425 select (ipa_rx.streamIdExt) {
426 case (IPAC_PROTO_EXT_MGCP) {
427 f_mgcp_to_user(ipa_rx.msg);
Harald Weltea76c4bb2017-12-09 02:06:07 +0100428 } case (IPAC_PROTO_EXT_CTRL) {
429 f_ctrl_to_user(ipa_rx.msg);
Harald Weltedf327232017-12-28 22:51:51 +0100430 } case (IPAC_PROTO_EXT_GSUP) {
431 f_gsup_to_user(ipa_rx.msg);
Harald Weltec82eef42017-11-24 20:40:12 +0100432 } case else {
433 IPA_SP_PORT.send(f_to_asp(ipa_rx));
434 }
Harald Welted86cdc62017-11-22 00:45:07 +0100435 }
Harald Weltec82eef42017-11-24 20:40:12 +0100436 } case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100437 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100438 }
439 }
440 }
441
Harald Welteb3414b22017-11-23 18:22:10 +0100442 /* server only */
443 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
444 log("IPA: Connected");
445 g_ipa_conn_id := asp_evt.connOpened.connId;
Harald Welte0d846a72017-12-07 17:58:28 +0100446 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100447 if (g_mode == IPA_MODE_SERVER) {
448 f_ccm_tx(valueof(ts_IPA_ID_GET));
449 }
450 }
451
452 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
453 log("IPA: Closed");
454 g_ipa_conn_id := -1;
Harald Welte0d846a72017-12-07 17:58:28 +0100455 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
Harald Welteb3414b22017-11-23 18:22:10 +0100456 self.stop;
457 }
458
Harald Welted86cdc62017-11-22 00:45:07 +0100459 /* Received SCCP -> down into IPA */
460 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Harald Weltec82eef42017-11-24 20:40:12 +0100461 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
462 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100463 IPA_PORT.send(ipa_tx);
464 }
Harald Weltec76f29f2017-11-22 12:46:46 +0100465
Harald Weltec82eef42017-11-24 20:40:12 +0100466 /* Received MGCP -> down into IPA */
467 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100468 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
469 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100470 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
471 }
472 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100473 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100474 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100475 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
476 }
477
Harald Weltea76c4bb2017-12-09 02:06:07 +0100478 [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
479 payload := char2oct(enc_CtrlMessage(ctrl_msg));
480 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
481 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
482 }
483
Harald Weltedf327232017-12-28 22:51:51 +0100484 [] IPA_GSUP_PORT.receive(GSUP_PDU:?) -> value gsup_msg {
Harald Welte2f562b12018-01-24 20:52:38 +0100485 f_gsup_preprocess_encoded(gsup_msg);
Harald Weltedf327232017-12-28 22:51:51 +0100486 payload := enc_GSUP_PDU(gsup_msg);
487 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_GSUP));
488 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
489 }
490
Harald Welte0d846a72017-12-07 17:58:28 +0100491 /* Received RSL -> down into IPA */
492 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
493 IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
494 }
Harald Weltec82eef42017-11-24 20:40:12 +0100495
Harald Welte0d846a72017-12-07 17:58:28 +0100496
497 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100498 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
499 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
500 }
501
502
Harald Welted86cdc62017-11-22 00:45:07 +0100503 }
504 }
505}
506
507}