blob: ddedb39d8d4801747f2ae7a634742445a52dd011 [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;
20
Harald Weltea76c4bb2017-12-09 02:06:07 +010021import from Osmocom_CTRL_Types all;
22
Harald Welted86cdc62017-11-22 00:45:07 +010023modulepar {
Harald Welte92632e12017-11-25 02:31:20 +010024 /* Use Osmocom extended IPA mux header */
25 boolean mp_ipa_mgcp_uses_osmo_ext := true;
Harald Welted86cdc62017-11-22 00:45:07 +010026}
Harald Welted86cdc62017-11-22 00:45:07 +010027
Harald Welteb3414b22017-11-23 18:22:10 +010028type enumerated IpaMode {
29 IPA_MODE_CLIENT,
30 IPA_MODE_SERVER
31}
32
Harald Weltec76f29f2017-11-22 12:46:46 +010033type record ASP_IPA_Unitdata {
34 IpaStreamId streamId,
Harald Weltec82eef42017-11-24 20:40:12 +010035 IpaExtStreamId streamIdExt optional,
Harald Weltec76f29f2017-11-22 12:46:46 +010036 octetstring payload
37}
38
Harald Welte0d846a72017-12-07 17:58:28 +010039type enumerated ASP_IPA_EventUpDown {
40 ASP_IPA_EVENT_DOWN,
41 ASP_IPA_EVENT_UP,
42 ASP_IPA_EVENT_ID_ACK
43}
44
Harald Weltebdb63702017-12-09 01:15:44 +010045/* an event indicating us whether or not a connection is physically up or down,
46 * and whether we have received an ID_ACK */
Harald Welte0d846a72017-12-07 17:58:28 +010047type union ASP_IPA_Event {
48 ASP_IPA_EventUpDown up_down
49}
50
51template ASP_IPA_Event t_ASP_IPA_EVT_UD(ASP_IPA_EventUpDown ud) := {
52 up_down := ud
53}
54
Harald Welte1dd8f372017-11-25 02:25:27 +010055template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
56 template IpaExtStreamId esid := omit) := {
57 streamId := sid,
58 streamIdExt := esid,
59 payload := pl
60}
61
Harald Weltebdb63702017-12-09 01:15:44 +010062/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +010063type record ASP_RSL_Unitdata {
64 IpaStreamId streamId,
65 RSL_Message rsl
66};
67
Harald Welte7ae019e2017-12-09 00:54:15 +010068template ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
Harald Welte0d846a72017-12-07 17:58:28 +010069 streamId := sid,
70 rsl := valueof(rsl)
71}
72
Harald Welte7ae019e2017-12-09 00:54:15 +010073template ASP_RSL_Unitdata tr_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
74 streamId := sid,
75 rsl := rsl
76}
77
78
Harald Welte0d846a72017-12-07 17:58:28 +010079template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
80 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
81
Harald Weltebdb63702017-12-09 01:15:44 +010082/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +010083type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +010084 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +010085} with { extension "internal" }
86
Harald Weltebdb63702017-12-09 01:15:44 +010087/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +010088type port IPA_MGCP_PT message {
89 inout MgcpCommand, MgcpResponse;
90} with { extension "internal" }
91
Harald Weltebdb63702017-12-09 01:15:44 +010092/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +010093type port IPA_RSL_PT message {
94 inout ASP_RSL_Unitdata, ASP_IPA_Event;
95} with { extension "internal" }
96
Harald Weltea76c4bb2017-12-09 02:06:07 +010097/* Client port for CTRL inside IPA */
98type port IPA_CTRL_PT message {
99 inout CtrlMessage, ASP_IPA_Event;
100} with { extension "internal" }
101
Harald Welted86cdc62017-11-22 00:45:07 +0100102type component IPA_Emulation_CT {
103 /* down-facing port to IPA codec port */
104 port IPA_CODEC_PT IPA_PORT;
105 /* up-facing port to SCCP */
106 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltec82eef42017-11-24 20:40:12 +0100107 /* up-facing port for MGCP */
108 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Welte0d846a72017-12-07 17:58:28 +0100109 /* up-facing port for RSL */
110 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100111 /* up-facing port for CTRL */
112 port IPA_CTRL_PT IPA_CTRL_PORT;
Harald Weltec76f29f2017-11-22 12:46:46 +0100113 /* up-facing port for other streams */
114 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100115
116 var boolean g_initialized := false;
117 var ConnectionId g_ipa_conn_id := -1;
Harald Weltec82eef42017-11-24 20:40:12 +0100118 /* Are we a BSC/MGW (truel) or MSC (false) */
119 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100120
121 var IpaMode g_mode;
Harald Weltee09921f2017-12-07 17:49:00 +0100122 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100123}
124
Harald Weltee21096d2017-12-04 20:45:12 +0100125type record IPA_CCM_Parameters {
126 charstring ser_nr optional,
127 charstring name optional,
128 charstring location1 optional,
129 charstring location2 optional,
130 charstring equip_version optional,
131 charstring sw_version optional,
132 charstring ip_addr optional,
133 charstring mac_addr optional,
134 charstring unit_id optional,
135 charstring osmo_rand optional
136}
137
Harald Weltee09921f2017-12-07 17:49:00 +0100138const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
139 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100140 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100141 location1 := "",
142 location2 := "",
143 equip_version := "",
144 sw_version := "",
145 ip_addr := "",
146 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100147 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100148 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100149};
150
Harald Weltebdb63702017-12-09 01:15:44 +0100151/* Function to use to connect as client to a remote IPA Server */
Harald Welted86cdc62017-11-22 00:45:07 +0100152function f_connect(charstring remote_host, PortNumber remote_port,
Harald Weltee21096d2017-12-04 20:45:12 +0100153 charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100154 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100155 var Result res;
156 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
157 local_host, local_port, 0, { tcp:={} });
158 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100159 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100160 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100161}
162
Harald Weltebdb63702017-12-09 01:15:44 +0100163/* Function to use to bind to a local port as IPA server, accepting remote clients */
Harald Weltee21096d2017-12-04 20:45:12 +0100164function f_bind(charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100165 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100166 var Result res;
167 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
168 local_host, local_port, { tcp:={} });
169 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100170 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100171 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100172}
173
Harald Welted86cdc62017-11-22 00:45:07 +0100174template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
175 sio := { '10'B, '00'B, '0011'B },
176 opc := opc,
177 dpc := 0,
178 sls := 0,
179 data := data
180}
181
182
183private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
184 len := 0, /* overwritten by codec */
185 tag := tag,
186 data := payload
187}
188
Harald Welte0d846a72017-12-07 17:58:28 +0100189private function f_send_IPA_EVT(template ASP_IPA_Event evt) runs on IPA_Emulation_CT {
Harald Welte5819b552017-12-09 02:55:46 +0100190 if (IPA_RSL_PORT.checkstate("Connected")) {
191 IPA_RSL_PORT.send(evt);
192 }
193 if (IPA_CTRL_PORT.checkstate("Connected")) {
194 IPA_CTRL_PORT.send(evt);
195 }
Harald Welte0d846a72017-12-07 17:58:28 +0100196 /* FIXME: to other ports */
197}
198
Harald Welted86cdc62017-11-22 00:45:07 +0100199/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100200private 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 +0100201 var integer i;
202 var PDU_IPA_CCM resp := {
203 msg_type := IPAC_MSGT_ID_RESP,
204 u := {
205 resp := {}
206 }
207 }
208
209 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
210 var IpaCcmIdTag tag := get.u.get[i].tag;
211 var charstring foo;
212 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100213 case (IPAC_IDTAG_SERNR) {
214 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100215 }
216 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100217 foo := g_ccm_pars.name;
218 }
219 case (IPAC_IDTAG_LOCATION1) {
220 foo := g_ccm_pars.location1;
221 }
222 case (IPAC_IDTAG_LOCATION2) {
223 foo := g_ccm_pars.location2;
224 }
225 case (IPAC_IDTAG_EQUIPVERS) {
226 foo := g_ccm_pars.equip_version;
227 }
228 case (IPAC_IDTAG_SWVERSION) {
229 foo := g_ccm_pars.sw_version;
230 }
231 case (IPAC_IDTAG_IPADDR) {
232 foo := g_ccm_pars.ip_addr;
233 }
234 case (IPAC_IDTAG_MACADDR) {
235 foo := g_ccm_pars.mac_addr;
236 }
237 case (IPAC_IDTAG_UNIT) {
238 foo := g_ccm_pars.unit_id;
239 }
240 case (IPAC_IDTAG_OSMO_RAND) {
241 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100242 }
243 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100244 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100245 }
246 }
247 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
248 }
249
250 return resp;
251}
252
253/* transmit IPA CCM message */
254private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Weltec82eef42017-11-24 20:40:12 +0100255 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 +0100256 log("CCM Tx:", ccm);
257 IPA_PORT.send(ipa_tx);
258}
259
260template PDU_IPA_CCM ts_IPA_PONG := {
261 msg_type := IPAC_MSGT_PONG,
262 u := omit
263}
264
265template PDU_IPA_CCM ts_IPA_ACK := {
266 msg_type := IPAC_MSGT_ID_ACK,
267 u := omit
268}
269
Harald Welteb3414b22017-11-23 18:22:10 +0100270template PDU_IPA_CCM ts_IPA_ID_GET := {
271 msg_type := IPAC_MSGT_ID_GET,
272 u := {
273 get := {
274 { 1, IPAC_IDTAG_UNITNAME }
275 }
276 }
277}
278
Harald Welted86cdc62017-11-22 00:45:07 +0100279/* receive IPA CCM message */
280private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
281 select (ccm.msg_type) {
282 case (IPAC_MSGT_PING) {
283 f_ccm_tx(valueof(ts_IPA_PONG));
284 }
285 case (IPAC_MSGT_ID_ACK) {
286 f_ccm_tx(valueof(ts_IPA_ACK));
287 }
288 case (IPAC_MSGT_ID_GET) {
289 f_ccm_tx(f_ccm_make_id_resp(ccm));
290 }
291 case else {
292 log("Unknown/unsupported IPA CCM message type", ccm);
293 }
294 }
295}
296
Harald Weltec76f29f2017-11-22 12:46:46 +0100297private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
298 var ASP_IPA_Unitdata ret := {
299 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100300 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100301 payload := ipa_rx.msg
302 }
303 return ret;
304}
305
306private function f_from_asp(ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100307 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
308 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100309 return ret;
310}
Harald Welted86cdc62017-11-22 00:45:07 +0100311
Harald Welte0d846a72017-12-07 17:58:28 +0100312private function f_from_rsl(ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
313 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
314 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
315 return ret;
316}
317
Harald Weltebdb63702017-12-09 01:15:44 +0100318/* main function to use for a client-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100319function main_client(charstring remote_host, PortNumber remote_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100320 charstring local_host, PortNumber local_port,
321 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100322 g_mode := IPA_MODE_CLIENT;
Harald Weltee09921f2017-12-07 17:49:00 +0100323 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welte03c0e562017-12-09 02:55:12 +0100324 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100325 ScanEvents();
326}
327
Harald Weltebdb63702017-12-09 01:15:44 +0100328/* main function to use for a server-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100329function main_server(charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
330 g_mode := IPA_MODE_SERVER;
331 f_bind(local_host, local_port);
332 ScanEvents();
333}
334
Harald Weltec82eef42017-11-24 20:40:12 +0100335private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
336 var charstring msg_ch := oct2char(msg);
337 if (g_is_bsc_mgw) {
338 log("============");
339 log(msg_ch);
340 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
341 } else {
342 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
343 }
344}
345
Harald Weltea76c4bb2017-12-09 02:06:07 +0100346private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
347 var charstring msg_ch := oct2char(msg);
348 IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
349}
350
Harald Welte92632e12017-11-25 02:31:20 +0100351private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
352 if (mp_ipa_mgcp_uses_osmo_ext) {
353 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
354 } else {
355 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
356 }
357}
358
Harald Weltebdb63702017-12-09 01:15:44 +0100359/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100360private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100361 var IPA_RecvFrom ipa_rx;
Harald Weltec76f29f2017-11-22 12:46:46 +0100362 var ASP_IPA_Unitdata ipa_ud;
Harald Welted86cdc62017-11-22 00:45:07 +0100363 var ASP_MTP3_TRANSFERreq mtp_req;
Harald Welteb3414b22017-11-23 18:22:10 +0100364 var ASP_Event asp_evt;
Harald Weltec82eef42017-11-24 20:40:12 +0100365 var MgcpCommand mgcp_cmd;
366 var MgcpResponse mgcp_rsp;
Harald Weltea76c4bb2017-12-09 02:06:07 +0100367 var CtrlMessage ctrl_msg;
Harald Welte1dd8f372017-11-25 02:25:27 +0100368 var octetstring payload;
Harald Welte0d846a72017-12-07 17:58:28 +0100369 var ASP_RSL_Unitdata rsl;
Harald Welted86cdc62017-11-22 00:45:07 +0100370
Harald Welte3e6ad892017-12-12 14:39:46 +0100371 /* Set function for dissecting the binary */
372 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
373 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});
374
Harald Welted86cdc62017-11-22 00:45:07 +0100375 while (true) {
376 alt {
377 /* Received IPA -> up into SCCP stack */
378 [] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
379 select (ipa_rx.streamId) {
380 case (IPAC_PROTO_CCM) {
381 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
382 log("CCM Rx:", ccm);
383 f_ccm_rx(ccm);
Harald Weltec82eef42017-11-24 20:40:12 +0100384 } case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100385 var ASP_MTP3_TRANSFERind mtp;
386 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
387 MTP3_SP_PORT.send(mtp);
Harald Weltec82eef42017-11-24 20:40:12 +0100388 } case (IPAC_PROTO_MGCP_OLD) {
389 f_mgcp_to_user(ipa_rx.msg);
Harald Welte0d846a72017-12-07 17:58:28 +0100390 } case (t_IpaSidRSL) {
391 rsl := {
392 streamId := ipa_rx.streamId,
393 rsl := dec_RSL_Message(ipa_rx.msg)
394 };
395 IPA_RSL_PORT.send(rsl);
Harald Weltec82eef42017-11-24 20:40:12 +0100396 } case (IPAC_PROTO_OSMO) {
397 select (ipa_rx.streamIdExt) {
398 case (IPAC_PROTO_EXT_MGCP) {
399 f_mgcp_to_user(ipa_rx.msg);
Harald Weltea76c4bb2017-12-09 02:06:07 +0100400 } case (IPAC_PROTO_EXT_CTRL) {
401 f_ctrl_to_user(ipa_rx.msg);
Harald Weltec82eef42017-11-24 20:40:12 +0100402 } case else {
403 IPA_SP_PORT.send(f_to_asp(ipa_rx));
404 }
Harald Welted86cdc62017-11-22 00:45:07 +0100405 }
Harald Weltec82eef42017-11-24 20:40:12 +0100406 } case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100407 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100408 }
409 }
410 }
411
Harald Welteb3414b22017-11-23 18:22:10 +0100412 /* server only */
413 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
414 log("IPA: Connected");
415 g_ipa_conn_id := asp_evt.connOpened.connId;
Harald Welte0d846a72017-12-07 17:58:28 +0100416 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100417 if (g_mode == IPA_MODE_SERVER) {
418 f_ccm_tx(valueof(ts_IPA_ID_GET));
419 }
420 }
421
422 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
423 log("IPA: Closed");
424 g_ipa_conn_id := -1;
Harald Welte0d846a72017-12-07 17:58:28 +0100425 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
Harald Welteb3414b22017-11-23 18:22:10 +0100426 self.stop;
427 }
428
Harald Welted86cdc62017-11-22 00:45:07 +0100429 /* Received SCCP -> down into IPA */
430 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Harald Weltec82eef42017-11-24 20:40:12 +0100431 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
432 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100433 IPA_PORT.send(ipa_tx);
434 }
Harald Weltec76f29f2017-11-22 12:46:46 +0100435
Harald Weltec82eef42017-11-24 20:40:12 +0100436 /* Received MGCP -> down into IPA */
437 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100438 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
439 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100440 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
441 }
442 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100443 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100444 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100445 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
446 }
447
Harald Weltea76c4bb2017-12-09 02:06:07 +0100448 [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
449 payload := char2oct(enc_CtrlMessage(ctrl_msg));
450 ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
451 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
452 }
453
Harald Welte0d846a72017-12-07 17:58:28 +0100454 /* Received RSL -> down into IPA */
455 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
456 IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
457 }
Harald Weltec82eef42017-11-24 20:40:12 +0100458
Harald Welte0d846a72017-12-07 17:58:28 +0100459
460 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100461 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
462 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
463 }
464
465
Harald Welted86cdc62017-11-22 00:45:07 +0100466 }
467 }
468}
469
470}