blob: 9bad69fe47352c36524ad3ab498ebd0fd4d93bb7 [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
5 * handshake for establishing the identity of the client to the server. It already knows
6 * certain well-known sub-protocols such as A-bis RSL, MGCP and SCCP and transcodes messages
7 * so the user can work with abstract data types rather than binary messages. It handles
8 * multiple packets inside one TCP segment */
9
Harald Welted86cdc62017-11-22 00:45:07 +010010import from IPA_Types all;
11import from IPA_CodecPort all;
12import from IPA_CodecPort_CtrlFunct all;
13import from IPL4asp_Types all;
Harald Welte12188832017-11-29 11:47:13 +010014import from IPL4asp_PortType all;
Harald Welted86cdc62017-11-22 00:45:07 +010015import from MTP3asp_Types all;
16import from MTP3asp_PortType all;
Harald Welte0d846a72017-12-07 17:58:28 +010017import from RSL_Types all;
Harald Welted86cdc62017-11-22 00:45:07 +010018
Harald Weltec82eef42017-11-24 20:40:12 +010019import from MGCP_Types all;
Harald Weltedf327232017-12-28 22:51:51 +010020import from GSUP_Types all;
Harald Weltec82eef42017-11-24 20:40:12 +010021
Harald Weltea76c4bb2017-12-09 02:06:07 +010022import from Osmocom_CTRL_Types all;
23
Harald Welted86cdc62017-11-22 00:45:07 +010024modulepar {
Harald Welte92632e12017-11-25 02:31:20 +010025 /* Use Osmocom extended IPA mux header */
26 boolean mp_ipa_mgcp_uses_osmo_ext := true;
Harald Welted86cdc62017-11-22 00:45:07 +010027}
Harald Welted86cdc62017-11-22 00:45:07 +010028
Harald Welteb3414b22017-11-23 18:22:10 +010029type enumerated IpaMode {
30 IPA_MODE_CLIENT,
31 IPA_MODE_SERVER
32}
33
Harald Weltec76f29f2017-11-22 12:46:46 +010034type record ASP_IPA_Unitdata {
35 IpaStreamId streamId,
Harald Weltec82eef42017-11-24 20:40:12 +010036 IpaExtStreamId streamIdExt optional,
Harald Weltec76f29f2017-11-22 12:46:46 +010037 octetstring payload
38}
39
Harald Welte0d846a72017-12-07 17:58:28 +010040type enumerated ASP_IPA_EventUpDown {
41 ASP_IPA_EVENT_DOWN,
42 ASP_IPA_EVENT_UP,
43 ASP_IPA_EVENT_ID_ACK
44}
45
Harald Weltebdb63702017-12-09 01:15:44 +010046/* an event indicating us whether or not a connection is physically up or down,
47 * and whether we have received an ID_ACK */
Harald Welte0d846a72017-12-07 17:58:28 +010048type union ASP_IPA_Event {
49 ASP_IPA_EventUpDown up_down
50}
51
52template ASP_IPA_Event t_ASP_IPA_EVT_UD(ASP_IPA_EventUpDown ud) := {
53 up_down := ud
54}
55
Harald Welte1dd8f372017-11-25 02:25:27 +010056template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
57 template IpaExtStreamId esid := omit) := {
58 streamId := sid,
59 streamIdExt := esid,
60 payload := pl
61}
62
Harald Weltebdb63702017-12-09 01:15:44 +010063/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +010064type record ASP_RSL_Unitdata {
65 IpaStreamId streamId,
66 RSL_Message rsl
67};
68
Harald Welte7ae019e2017-12-09 00:54:15 +010069template ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
Harald Welte0d846a72017-12-07 17:58:28 +010070 streamId := sid,
71 rsl := valueof(rsl)
72}
73
Harald Welte7ae019e2017-12-09 00:54:15 +010074template ASP_RSL_Unitdata tr_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
75 streamId := sid,
76 rsl := rsl
77}
78
79
Harald Welte0d846a72017-12-07 17:58:28 +010080template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
81 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
82
Harald Weltebdb63702017-12-09 01:15:44 +010083/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +010084type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +010085 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +010086} with { extension "internal" }
87
Harald Weltebdb63702017-12-09 01:15:44 +010088/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +010089type port IPA_MGCP_PT message {
90 inout MgcpCommand, MgcpResponse;
91} with { extension "internal" }
92
Harald Weltebdb63702017-12-09 01:15:44 +010093/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +010094type port IPA_RSL_PT message {
95 inout ASP_RSL_Unitdata, ASP_IPA_Event;
96} with { extension "internal" }
97
Harald Weltea76c4bb2017-12-09 02:06:07 +010098/* Client port for CTRL inside IPA */
99type port IPA_CTRL_PT message {
100 inout CtrlMessage, ASP_IPA_Event;
101} with { extension "internal" }
102
Harald Weltedf327232017-12-28 22:51:51 +0100103/* Client port for CTRL inside IPA */
104type port IPA_GSUP_PT message {
105 inout GSUP_PDU, ASP_IPA_Event;
106} with { extension "internal" }
107
108
Harald Welted86cdc62017-11-22 00:45:07 +0100109type component IPA_Emulation_CT {
110 /* down-facing port to IPA codec port */
111 port IPA_CODEC_PT IPA_PORT;
112 /* up-facing port to SCCP */
113 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltec82eef42017-11-24 20:40:12 +0100114 /* up-facing port for MGCP */
115 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Welte0d846a72017-12-07 17:58:28 +0100116 /* up-facing port for RSL */
117 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100118 /* up-facing port for CTRL */
119 port IPA_CTRL_PT IPA_CTRL_PORT;
Harald Weltedf327232017-12-28 22:51:51 +0100120 /* up-facing port for GSUP */
121 port IPA_GSUP_PT IPA_GSUP_PORT;
122
Harald Weltec76f29f2017-11-22 12:46:46 +0100123 /* up-facing port for other streams */
124 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100125
126 var boolean g_initialized := false;
127 var ConnectionId g_ipa_conn_id := -1;
Harald Weltec82eef42017-11-24 20:40:12 +0100128 /* Are we a BSC/MGW (truel) or MSC (false) */
129 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100130
131 var IpaMode g_mode;
Harald Weltee09921f2017-12-07 17:49:00 +0100132 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100133}
134
Harald Weltee21096d2017-12-04 20:45:12 +0100135type record IPA_CCM_Parameters {
136 charstring ser_nr optional,
137 charstring name optional,
138 charstring location1 optional,
139 charstring location2 optional,
140 charstring equip_version optional,
141 charstring sw_version optional,
142 charstring ip_addr optional,
143 charstring mac_addr optional,
144 charstring unit_id optional,
145 charstring osmo_rand optional
146}
147
Harald Weltee09921f2017-12-07 17:49:00 +0100148const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
149 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100150 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100151 location1 := "",
152 location2 := "",
153 equip_version := "",
154 sw_version := "",
155 ip_addr := "",
156 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100157 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100158 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100159};
160
Harald Weltebdb63702017-12-09 01:15:44 +0100161/* Function to use to connect as client to a remote IPA Server */
Harald Welted86cdc62017-11-22 00:45:07 +0100162function f_connect(charstring remote_host, PortNumber remote_port,
Harald Weltee21096d2017-12-04 20:45:12 +0100163 charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100164 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100165 var Result res;
166 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
167 local_host, local_port, 0, { tcp:={} });
168 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100169 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100170 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100171}
172
Harald Weltebdb63702017-12-09 01:15:44 +0100173/* Function to use to bind to a local port as IPA server, accepting remote clients */
Harald Weltee21096d2017-12-04 20:45:12 +0100174function f_bind(charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100175 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100176 var Result res;
177 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
178 local_host, local_port, { tcp:={} });
179 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100180 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100181 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100182}
183
Harald Welted86cdc62017-11-22 00:45:07 +0100184template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
185 sio := { '10'B, '00'B, '0011'B },
186 opc := opc,
187 dpc := 0,
188 sls := 0,
189 data := data
190}
191
192
193private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
194 len := 0, /* overwritten by codec */
195 tag := tag,
196 data := payload
197}
198
Harald Welte0d846a72017-12-07 17:58:28 +0100199private function f_send_IPA_EVT(template ASP_IPA_Event evt) runs on IPA_Emulation_CT {
Harald Welte5819b552017-12-09 02:55:46 +0100200 if (IPA_RSL_PORT.checkstate("Connected")) {
201 IPA_RSL_PORT.send(evt);
202 }
203 if (IPA_CTRL_PORT.checkstate("Connected")) {
204 IPA_CTRL_PORT.send(evt);
205 }
Harald Weltedf327232017-12-28 22:51:51 +0100206 if (IPA_GSUP_PORT.checkstate("Connected")) {
207 IPA_GSUP_PORT.send(evt);
208 }
Harald Welte0d846a72017-12-07 17:58:28 +0100209 /* FIXME: to other ports */
210}
211
Harald Welted86cdc62017-11-22 00:45:07 +0100212/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100213private 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 +0100214 var integer i;
215 var PDU_IPA_CCM resp := {
216 msg_type := IPAC_MSGT_ID_RESP,
217 u := {
218 resp := {}
219 }
220 }
221
222 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
223 var IpaCcmIdTag tag := get.u.get[i].tag;
224 var charstring foo;
225 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100226 case (IPAC_IDTAG_SERNR) {
227 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100228 }
229 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100230 foo := g_ccm_pars.name;
231 }
232 case (IPAC_IDTAG_LOCATION1) {
233 foo := g_ccm_pars.location1;
234 }
235 case (IPAC_IDTAG_LOCATION2) {
236 foo := g_ccm_pars.location2;
237 }
238 case (IPAC_IDTAG_EQUIPVERS) {
239 foo := g_ccm_pars.equip_version;
240 }
241 case (IPAC_IDTAG_SWVERSION) {
242 foo := g_ccm_pars.sw_version;
243 }
244 case (IPAC_IDTAG_IPADDR) {
245 foo := g_ccm_pars.ip_addr;
246 }
247 case (IPAC_IDTAG_MACADDR) {
248 foo := g_ccm_pars.mac_addr;
249 }
250 case (IPAC_IDTAG_UNIT) {
251 foo := g_ccm_pars.unit_id;
252 }
253 case (IPAC_IDTAG_OSMO_RAND) {
254 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100255 }
256 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100257 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100258 }
259 }
260 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
261 }
262
263 return resp;
264}
265
266/* transmit IPA CCM message */
267private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Weltec82eef42017-11-24 20:40:12 +0100268 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 +0100269 log("CCM Tx:", ccm);
270 IPA_PORT.send(ipa_tx);
271}
272
273template PDU_IPA_CCM ts_IPA_PONG := {
274 msg_type := IPAC_MSGT_PONG,
275 u := omit
276}
277
278template PDU_IPA_CCM ts_IPA_ACK := {
279 msg_type := IPAC_MSGT_ID_ACK,
280 u := omit
281}
282
Harald Welteb3414b22017-11-23 18:22:10 +0100283template PDU_IPA_CCM ts_IPA_ID_GET := {
284 msg_type := IPAC_MSGT_ID_GET,
285 u := {
286 get := {
287 { 1, IPAC_IDTAG_UNITNAME }
288 }
289 }
290}
291
Harald Welted86cdc62017-11-22 00:45:07 +0100292/* receive IPA CCM message */
293private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
294 select (ccm.msg_type) {
295 case (IPAC_MSGT_PING) {
296 f_ccm_tx(valueof(ts_IPA_PONG));
297 }
298 case (IPAC_MSGT_ID_ACK) {
299 f_ccm_tx(valueof(ts_IPA_ACK));
300 }
301 case (IPAC_MSGT_ID_GET) {
302 f_ccm_tx(f_ccm_make_id_resp(ccm));
303 }
304 case else {
305 log("Unknown/unsupported IPA CCM message type", ccm);
306 }
307 }
308}
309
Harald Weltec76f29f2017-11-22 12:46:46 +0100310private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
311 var ASP_IPA_Unitdata ret := {
312 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100313 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100314 payload := ipa_rx.msg
315 }
316 return ret;
317}
318
319private function f_from_asp(ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100320 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
321 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100322 return ret;
323}
Harald Welted86cdc62017-11-22 00:45:07 +0100324
Harald Welte0d846a72017-12-07 17:58:28 +0100325private function f_from_rsl(ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
326 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
327 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
328 return ret;
329}
330
Harald Weltebdb63702017-12-09 01:15:44 +0100331/* main function to use for a client-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100332function main_client(charstring remote_host, PortNumber remote_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100333 charstring local_host, PortNumber local_port,
334 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100335 g_mode := IPA_MODE_CLIENT;
Harald Weltee09921f2017-12-07 17:49:00 +0100336 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welte03c0e562017-12-09 02:55:12 +0100337 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100338 ScanEvents();
339}
340
Harald Weltebdb63702017-12-09 01:15:44 +0100341/* main function to use for a server-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100342function main_server(charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
343 g_mode := IPA_MODE_SERVER;
344 f_bind(local_host, local_port);
345 ScanEvents();
346}
347
Harald Weltec82eef42017-11-24 20:40:12 +0100348private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
349 var charstring msg_ch := oct2char(msg);
350 if (g_is_bsc_mgw) {
351 log("============");
352 log(msg_ch);
353 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
354 } else {
355 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
356 }
357}
358
Harald Weltea76c4bb2017-12-09 02:06:07 +0100359private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
360 var charstring msg_ch := oct2char(msg);
361 IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
362}
363
Harald Weltedf327232017-12-28 22:51:51 +0100364private function f_gsup_to_user(octetstring msg) runs on IPA_Emulation_CT {
365 IPA_GSUP_PORT.send(dec_GSUP_PDU(msg));
366}
367
Harald Welte92632e12017-11-25 02:31:20 +0100368private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
369 if (mp_ipa_mgcp_uses_osmo_ext) {
370 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
371 } else {
372 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
373 }
374}
375
Harald Weltebdb63702017-12-09 01:15:44 +0100376/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100377private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100378 var IPA_RecvFrom ipa_rx;
Harald Weltec76f29f2017-11-22 12:46:46 +0100379 var ASP_IPA_Unitdata ipa_ud;
Harald Welted86cdc62017-11-22 00:45:07 +0100380 var ASP_MTP3_TRANSFERreq mtp_req;
Harald Welteb3414b22017-11-23 18:22:10 +0100381 var ASP_Event asp_evt;
Harald Weltec82eef42017-11-24 20:40:12 +0100382 var MgcpCommand mgcp_cmd;
383 var MgcpResponse mgcp_rsp;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100384 var CtrlMessage ctrl_msg;
Harald Weltedf327232017-12-28 22:51:51 +0100385 var GSUP_PDU gsup_msg;
Harald Welte1dd8f372017-11-25 02:25:27 +0100386 var octetstring payload;
Harald Welte0d846a72017-12-07 17:58:28 +0100387 var ASP_RSL_Unitdata rsl;
Harald Welted86cdc62017-11-22 00:45:07 +0100388
Harald Welte3e6ad892017-12-12 14:39:46 +0100389 /* Set function for dissecting the binary */
390 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
391 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});
392
Harald Welted86cdc62017-11-22 00:45:07 +0100393 while (true) {
394 alt {
395 /* Received IPA -> up into SCCP stack */
396 [] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
397 select (ipa_rx.streamId) {
398 case (IPAC_PROTO_CCM) {
399 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
400 log("CCM Rx:", ccm);
401 f_ccm_rx(ccm);
Harald Weltec82eef42017-11-24 20:40:12 +0100402 } case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100403 var ASP_MTP3_TRANSFERind mtp;
404 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
405 MTP3_SP_PORT.send(mtp);
Harald Weltec82eef42017-11-24 20:40:12 +0100406 } case (IPAC_PROTO_MGCP_OLD) {
407 f_mgcp_to_user(ipa_rx.msg);
Harald Welte0d846a72017-12-07 17:58:28 +0100408 } case (t_IpaSidRSL) {
409 rsl := {
410 streamId := ipa_rx.streamId,
411 rsl := dec_RSL_Message(ipa_rx.msg)
412 };
413 IPA_RSL_PORT.send(rsl);
Harald Weltec82eef42017-11-24 20:40:12 +0100414 } case (IPAC_PROTO_OSMO) {
415 select (ipa_rx.streamIdExt) {
416 case (IPAC_PROTO_EXT_MGCP) {
417 f_mgcp_to_user(ipa_rx.msg);
Harald Weltea76c4bb2017-12-09 02:06:07 +0100418 } case (IPAC_PROTO_EXT_CTRL) {
419 f_ctrl_to_user(ipa_rx.msg);
Harald Weltedf327232017-12-28 22:51:51 +0100420 } case (IPAC_PROTO_EXT_GSUP) {
421 f_gsup_to_user(ipa_rx.msg);
Harald Weltec82eef42017-11-24 20:40:12 +0100422 } case else {
423 IPA_SP_PORT.send(f_to_asp(ipa_rx));
424 }
Harald Welted86cdc62017-11-22 00:45:07 +0100425 }
Harald Weltec82eef42017-11-24 20:40:12 +0100426 } case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100427 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100428 }
429 }
430 }
431
Harald Welteb3414b22017-11-23 18:22:10 +0100432 /* server only */
433 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
434 log("IPA: Connected");
435 g_ipa_conn_id := asp_evt.connOpened.connId;
Harald Welte0d846a72017-12-07 17:58:28 +0100436 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100437 if (g_mode == IPA_MODE_SERVER) {
438 f_ccm_tx(valueof(ts_IPA_ID_GET));
439 }
440 }
441
442 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
443 log("IPA: Closed");
444 g_ipa_conn_id := -1;
Harald Welte0d846a72017-12-07 17:58:28 +0100445 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
Harald Welteb3414b22017-11-23 18:22:10 +0100446 self.stop;
447 }
448
Harald Welted86cdc62017-11-22 00:45:07 +0100449 /* Received SCCP -> down into IPA */
450 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Harald Weltec82eef42017-11-24 20:40:12 +0100451 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
452 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100453 IPA_PORT.send(ipa_tx);
454 }
Harald Weltec76f29f2017-11-22 12:46:46 +0100455
Harald Weltec82eef42017-11-24 20:40:12 +0100456 /* Received MGCP -> down into IPA */
457 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100458 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
459 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100460 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
461 }
462 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100463 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100464 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100465 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
466 }
467
Harald Weltea76c4bb2017-12-09 02:06:07 +0100468 [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
469 payload := char2oct(enc_CtrlMessage(ctrl_msg));
470 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
471 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
472 }
473
Harald Weltedf327232017-12-28 22:51:51 +0100474 [] IPA_GSUP_PORT.receive(GSUP_PDU:?) -> value gsup_msg {
475 payload := enc_GSUP_PDU(gsup_msg);
476 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_GSUP));
477 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
478 }
479
Harald Welte0d846a72017-12-07 17:58:28 +0100480 /* Received RSL -> down into IPA */
481 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
482 IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
483 }
Harald Weltec82eef42017-11-24 20:40:12 +0100484
Harald Welte0d846a72017-12-07 17:58:28 +0100485
486 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100487 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
488 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
489 }
490
491
Harald Welted86cdc62017-11-22 00:45:07 +0100492 }
493 }
494}
495
496}