blob: 61f357ca6b09e934a0175487b2fbaf9d863eb9a8 [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 Welted86cdc62017-11-22 00:45:07 +010021modulepar {
Harald Welte92632e12017-11-25 02:31:20 +010022 /* Use Osmocom extended IPA mux header */
23 boolean mp_ipa_mgcp_uses_osmo_ext := true;
Harald Welted86cdc62017-11-22 00:45:07 +010024}
Harald Welted86cdc62017-11-22 00:45:07 +010025
Harald Welteb3414b22017-11-23 18:22:10 +010026type enumerated IpaMode {
27 IPA_MODE_CLIENT,
28 IPA_MODE_SERVER
29}
30
Harald Weltec76f29f2017-11-22 12:46:46 +010031type record ASP_IPA_Unitdata {
32 IpaStreamId streamId,
Harald Weltec82eef42017-11-24 20:40:12 +010033 IpaExtStreamId streamIdExt optional,
Harald Weltec76f29f2017-11-22 12:46:46 +010034 octetstring payload
35}
36
Harald Welte0d846a72017-12-07 17:58:28 +010037type enumerated ASP_IPA_EventUpDown {
38 ASP_IPA_EVENT_DOWN,
39 ASP_IPA_EVENT_UP,
40 ASP_IPA_EVENT_ID_ACK
41}
42
Harald Weltebdb63702017-12-09 01:15:44 +010043/* an event indicating us whether or not a connection is physically up or down,
44 * and whether we have received an ID_ACK */
Harald Welte0d846a72017-12-07 17:58:28 +010045type union ASP_IPA_Event {
46 ASP_IPA_EventUpDown up_down
47}
48
49template ASP_IPA_Event t_ASP_IPA_EVT_UD(ASP_IPA_EventUpDown ud) := {
50 up_down := ud
51}
52
Harald Welte1dd8f372017-11-25 02:25:27 +010053template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
54 template IpaExtStreamId esid := omit) := {
55 streamId := sid,
56 streamIdExt := esid,
57 payload := pl
58}
59
Harald Weltebdb63702017-12-09 01:15:44 +010060/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
Harald Welte0d846a72017-12-07 17:58:28 +010061type record ASP_RSL_Unitdata {
62 IpaStreamId streamId,
63 RSL_Message rsl
64};
65
Harald Welte7ae019e2017-12-09 00:54:15 +010066template ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
Harald Welte0d846a72017-12-07 17:58:28 +010067 streamId := sid,
68 rsl := valueof(rsl)
69}
70
Harald Welte7ae019e2017-12-09 00:54:15 +010071template ASP_RSL_Unitdata tr_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
72 streamId := sid,
73 rsl := rsl
74}
75
76
Harald Welte0d846a72017-12-07 17:58:28 +010077template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
78 IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );
79
Harald Weltebdb63702017-12-09 01:15:44 +010080/* Client port for general IPA messages, not further decoded */
Harald Weltec76f29f2017-11-22 12:46:46 +010081type port IPA_SP_PT message {
Harald Welte0d846a72017-12-07 17:58:28 +010082 inout ASP_IPA_Unitdata, ASP_IPA_Event;
Harald Weltec76f29f2017-11-22 12:46:46 +010083} with { extension "internal" }
84
Harald Weltebdb63702017-12-09 01:15:44 +010085/* Client port for MGCP inside IPA */
Harald Weltec82eef42017-11-24 20:40:12 +010086type port IPA_MGCP_PT message {
87 inout MgcpCommand, MgcpResponse;
88} with { extension "internal" }
89
Harald Weltebdb63702017-12-09 01:15:44 +010090/* Client port for A-bis RSL inside IPA */
Harald Welte0d846a72017-12-07 17:58:28 +010091type port IPA_RSL_PT message {
92 inout ASP_RSL_Unitdata, ASP_IPA_Event;
93} with { extension "internal" }
94
Harald Welted86cdc62017-11-22 00:45:07 +010095type component IPA_Emulation_CT {
96 /* down-facing port to IPA codec port */
97 port IPA_CODEC_PT IPA_PORT;
98 /* up-facing port to SCCP */
99 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltec82eef42017-11-24 20:40:12 +0100100 /* up-facing port for MGCP */
101 port IPA_MGCP_PT IPA_MGCP_PORT;
Harald Welte0d846a72017-12-07 17:58:28 +0100102 /* up-facing port for RSL */
103 port IPA_RSL_PT IPA_RSL_PORT;
Harald Weltec76f29f2017-11-22 12:46:46 +0100104 /* up-facing port for other streams */
105 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +0100106
107 var boolean g_initialized := false;
108 var ConnectionId g_ipa_conn_id := -1;
Harald Weltec82eef42017-11-24 20:40:12 +0100109 /* Are we a BSC/MGW (truel) or MSC (false) */
110 var boolean g_is_bsc_mgw;
Harald Welteb3414b22017-11-23 18:22:10 +0100111
112 var IpaMode g_mode;
Harald Weltee09921f2017-12-07 17:49:00 +0100113 var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
Harald Welted86cdc62017-11-22 00:45:07 +0100114}
115
Harald Weltee21096d2017-12-04 20:45:12 +0100116type record IPA_CCM_Parameters {
117 charstring ser_nr optional,
118 charstring name optional,
119 charstring location1 optional,
120 charstring location2 optional,
121 charstring equip_version optional,
122 charstring sw_version optional,
123 charstring ip_addr optional,
124 charstring mac_addr optional,
125 charstring unit_id optional,
126 charstring osmo_rand optional
127}
128
Harald Weltee09921f2017-12-07 17:49:00 +0100129const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
130 ser_nr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100131 name := "mahlzeit",
Harald Weltee09921f2017-12-07 17:49:00 +0100132 location1 := "",
133 location2 := "",
134 equip_version := "",
135 sw_version := "",
136 ip_addr := "",
137 mac_addr := "",
Harald Weltee21096d2017-12-04 20:45:12 +0100138 unit_id := "0/1/2",
Harald Weltee09921f2017-12-07 17:49:00 +0100139 osmo_rand := ""
Harald Weltee21096d2017-12-04 20:45:12 +0100140};
141
Harald Weltebdb63702017-12-09 01:15:44 +0100142/* Function to use to connect as client to a remote IPA Server */
Harald Welted86cdc62017-11-22 00:45:07 +0100143function f_connect(charstring remote_host, PortNumber remote_port,
Harald Weltee21096d2017-12-04 20:45:12 +0100144 charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100145 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100146 var Result res;
147 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
148 local_host, local_port, 0, { tcp:={} });
149 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100150 g_ccm_pars := ccm_pars;
Harald Welte12188832017-11-29 11:47:13 +0100151 /* Set function for dissecting the binary */
152 var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
153 IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});
154
Harald Weltec82eef42017-11-24 20:40:12 +0100155 g_is_bsc_mgw := true;
Harald Welted86cdc62017-11-22 00:45:07 +0100156}
157
Harald Weltebdb63702017-12-09 01:15:44 +0100158/* Function to use to bind to a local port as IPA server, accepting remote clients */
Harald Weltee21096d2017-12-04 20:45:12 +0100159function f_bind(charstring local_host, PortNumber local_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100160 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100161 var Result res;
162 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
163 local_host, local_port, { tcp:={} });
164 g_ipa_conn_id := res.connId;
Harald Weltee21096d2017-12-04 20:45:12 +0100165 g_ccm_pars := ccm_pars;
Harald Weltec82eef42017-11-24 20:40:12 +0100166 g_is_bsc_mgw := false;
Harald Welteb3414b22017-11-23 18:22:10 +0100167}
168
Harald Welted86cdc62017-11-22 00:45:07 +0100169template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
170 sio := { '10'B, '00'B, '0011'B },
171 opc := opc,
172 dpc := 0,
173 sls := 0,
174 data := data
175}
176
177
178private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
179 len := 0, /* overwritten by codec */
180 tag := tag,
181 data := payload
182}
183
Harald Welte0d846a72017-12-07 17:58:28 +0100184private function f_send_IPA_EVT(template ASP_IPA_Event evt) runs on IPA_Emulation_CT {
185 IPA_RSL_PORT.send(evt);
186 /* FIXME: to other ports */
187}
188
Harald Welted86cdc62017-11-22 00:45:07 +0100189/* build IPA CCM ID RESP response from IPA CCM GET */
Harald Weltee21096d2017-12-04 20:45:12 +0100190private 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 +0100191 var integer i;
192 var PDU_IPA_CCM resp := {
193 msg_type := IPAC_MSGT_ID_RESP,
194 u := {
195 resp := {}
196 }
197 }
198
199 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
200 var IpaCcmIdTag tag := get.u.get[i].tag;
201 var charstring foo;
202 select (tag) {
Harald Weltee21096d2017-12-04 20:45:12 +0100203 case (IPAC_IDTAG_SERNR) {
204 foo := g_ccm_pars.ser_nr;
Harald Welted86cdc62017-11-22 00:45:07 +0100205 }
206 case (IPAC_IDTAG_UNITNAME) {
Harald Weltee21096d2017-12-04 20:45:12 +0100207 foo := g_ccm_pars.name;
208 }
209 case (IPAC_IDTAG_LOCATION1) {
210 foo := g_ccm_pars.location1;
211 }
212 case (IPAC_IDTAG_LOCATION2) {
213 foo := g_ccm_pars.location2;
214 }
215 case (IPAC_IDTAG_EQUIPVERS) {
216 foo := g_ccm_pars.equip_version;
217 }
218 case (IPAC_IDTAG_SWVERSION) {
219 foo := g_ccm_pars.sw_version;
220 }
221 case (IPAC_IDTAG_IPADDR) {
222 foo := g_ccm_pars.ip_addr;
223 }
224 case (IPAC_IDTAG_MACADDR) {
225 foo := g_ccm_pars.mac_addr;
226 }
227 case (IPAC_IDTAG_UNIT) {
228 foo := g_ccm_pars.unit_id;
229 }
230 case (IPAC_IDTAG_OSMO_RAND) {
231 foo := g_ccm_pars.osmo_rand;
Harald Welted86cdc62017-11-22 00:45:07 +0100232 }
233 case else {
Harald Weltee21096d2017-12-04 20:45:12 +0100234 foo := "unknown";
Harald Welted86cdc62017-11-22 00:45:07 +0100235 }
236 }
237 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
238 }
239
240 return resp;
241}
242
243/* transmit IPA CCM message */
244private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
Harald Weltec82eef42017-11-24 20:40:12 +0100245 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 +0100246 log("CCM Tx:", ccm);
247 IPA_PORT.send(ipa_tx);
248}
249
250template PDU_IPA_CCM ts_IPA_PONG := {
251 msg_type := IPAC_MSGT_PONG,
252 u := omit
253}
254
255template PDU_IPA_CCM ts_IPA_ACK := {
256 msg_type := IPAC_MSGT_ID_ACK,
257 u := omit
258}
259
Harald Welteb3414b22017-11-23 18:22:10 +0100260template PDU_IPA_CCM ts_IPA_ID_GET := {
261 msg_type := IPAC_MSGT_ID_GET,
262 u := {
263 get := {
264 { 1, IPAC_IDTAG_UNITNAME }
265 }
266 }
267}
268
Harald Welted86cdc62017-11-22 00:45:07 +0100269/* receive IPA CCM message */
270private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
271 select (ccm.msg_type) {
272 case (IPAC_MSGT_PING) {
273 f_ccm_tx(valueof(ts_IPA_PONG));
274 }
275 case (IPAC_MSGT_ID_ACK) {
276 f_ccm_tx(valueof(ts_IPA_ACK));
277 }
278 case (IPAC_MSGT_ID_GET) {
279 f_ccm_tx(f_ccm_make_id_resp(ccm));
280 }
281 case else {
282 log("Unknown/unsupported IPA CCM message type", ccm);
283 }
284 }
285}
286
Harald Weltec76f29f2017-11-22 12:46:46 +0100287private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
288 var ASP_IPA_Unitdata ret := {
289 streamId := ipa_rx.streamId,
Harald Welte2a8f8472017-11-23 21:11:34 +0100290 streamIdExt := ipa_rx.streamIdExt,
Harald Weltec76f29f2017-11-22 12:46:46 +0100291 payload := ipa_rx.msg
292 }
293 return ret;
294}
295
296private function f_from_asp(ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
Harald Weltec82eef42017-11-24 20:40:12 +0100297 var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
298 ipa_tx.streamIdExt));
Harald Weltec76f29f2017-11-22 12:46:46 +0100299 return ret;
300}
Harald Welted86cdc62017-11-22 00:45:07 +0100301
Harald Welte0d846a72017-12-07 17:58:28 +0100302private function f_from_rsl(ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
303 var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
304 var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
305 return ret;
306}
307
Harald Weltebdb63702017-12-09 01:15:44 +0100308/* main function to use for a client-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100309function main_client(charstring remote_host, PortNumber remote_port,
Harald Weltee09921f2017-12-07 17:49:00 +0100310 charstring local_host, PortNumber local_port,
311 IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
Harald Welteb3414b22017-11-23 18:22:10 +0100312 g_mode := IPA_MODE_CLIENT;
Harald Weltee09921f2017-12-07 17:49:00 +0100313 f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
Harald Welteb3414b22017-11-23 18:22:10 +0100314 ScanEvents();
315}
316
Harald Weltebdb63702017-12-09 01:15:44 +0100317/* main function to use for a server-side IPA implementation */
Harald Welteb3414b22017-11-23 18:22:10 +0100318function main_server(charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
319 g_mode := IPA_MODE_SERVER;
320 f_bind(local_host, local_port);
321 ScanEvents();
322}
323
Harald Weltec82eef42017-11-24 20:40:12 +0100324private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
325 var charstring msg_ch := oct2char(msg);
326 if (g_is_bsc_mgw) {
327 log("============");
328 log(msg_ch);
329 IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
330 } else {
331 IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
332 }
333}
334
Harald Welte92632e12017-11-25 02:31:20 +0100335private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
336 if (mp_ipa_mgcp_uses_osmo_ext) {
337 return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
338 } else {
339 return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
340 }
341}
342
Harald Weltebdb63702017-12-09 01:15:44 +0100343/* main loop function for both client and server. 'thread' of the component */
Harald Welteb3414b22017-11-23 18:22:10 +0100344private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100345 var IPA_RecvFrom ipa_rx;
Harald Weltec76f29f2017-11-22 12:46:46 +0100346 var ASP_IPA_Unitdata ipa_ud;
Harald Welted86cdc62017-11-22 00:45:07 +0100347 var ASP_MTP3_TRANSFERreq mtp_req;
Harald Welteb3414b22017-11-23 18:22:10 +0100348 var ASP_Event asp_evt;
Harald Weltec82eef42017-11-24 20:40:12 +0100349 var MgcpCommand mgcp_cmd;
350 var MgcpResponse mgcp_rsp;
Harald Welte1dd8f372017-11-25 02:25:27 +0100351 var octetstring payload;
Harald Welte0d846a72017-12-07 17:58:28 +0100352 var ASP_RSL_Unitdata rsl;
Harald Welted86cdc62017-11-22 00:45:07 +0100353
354 while (true) {
355 alt {
356 /* Received IPA -> up into SCCP stack */
357 [] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
358 select (ipa_rx.streamId) {
359 case (IPAC_PROTO_CCM) {
360 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
361 log("CCM Rx:", ccm);
362 f_ccm_rx(ccm);
Harald Weltec82eef42017-11-24 20:40:12 +0100363 } case (IPAC_PROTO_SCCP) {
Harald Welted86cdc62017-11-22 00:45:07 +0100364 var ASP_MTP3_TRANSFERind mtp;
365 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
366 MTP3_SP_PORT.send(mtp);
Harald Weltec82eef42017-11-24 20:40:12 +0100367 } case (IPAC_PROTO_MGCP_OLD) {
368 f_mgcp_to_user(ipa_rx.msg);
Harald Welte0d846a72017-12-07 17:58:28 +0100369 } case (t_IpaSidRSL) {
370 rsl := {
371 streamId := ipa_rx.streamId,
372 rsl := dec_RSL_Message(ipa_rx.msg)
373 };
374 IPA_RSL_PORT.send(rsl);
Harald Weltec82eef42017-11-24 20:40:12 +0100375 } case (IPAC_PROTO_OSMO) {
376 select (ipa_rx.streamIdExt) {
377 case (IPAC_PROTO_EXT_MGCP) {
378 f_mgcp_to_user(ipa_rx.msg);
379 } case else {
380 IPA_SP_PORT.send(f_to_asp(ipa_rx));
381 }
Harald Welted86cdc62017-11-22 00:45:07 +0100382 }
Harald Weltec82eef42017-11-24 20:40:12 +0100383 } case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100384 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100385 }
386 }
387 }
388
Harald Welteb3414b22017-11-23 18:22:10 +0100389 /* server only */
390 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
391 log("IPA: Connected");
392 g_ipa_conn_id := asp_evt.connOpened.connId;
Harald Welte0d846a72017-12-07 17:58:28 +0100393 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
Harald Welteb3414b22017-11-23 18:22:10 +0100394 if (g_mode == IPA_MODE_SERVER) {
395 f_ccm_tx(valueof(ts_IPA_ID_GET));
396 }
397 }
398
399 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
400 log("IPA: Closed");
401 g_ipa_conn_id := -1;
Harald Welte0d846a72017-12-07 17:58:28 +0100402 f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
Harald Welteb3414b22017-11-23 18:22:10 +0100403 self.stop;
404 }
405
Harald Welted86cdc62017-11-22 00:45:07 +0100406 /* Received SCCP -> down into IPA */
407 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
Harald Weltec82eef42017-11-24 20:40:12 +0100408 var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
409 mtp_req.data));
Harald Welted86cdc62017-11-22 00:45:07 +0100410 IPA_PORT.send(ipa_tx);
411 }
Harald Weltec76f29f2017-11-22 12:46:46 +0100412
Harald Weltec82eef42017-11-24 20:40:12 +0100413 /* Received MGCP -> down into IPA */
414 [] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
Harald Welte92632e12017-11-25 02:31:20 +0100415 payload := char2oct(enc_MgcpCommand(mgcp_cmd));
416 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100417 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
418 }
419 [] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
Harald Welte1dd8f372017-11-25 02:25:27 +0100420 payload := char2oct(enc_MgcpResponse(mgcp_rsp));
Harald Welte92632e12017-11-25 02:31:20 +0100421 ipa_ud := f_mgcp_to_ud(payload);
Harald Weltec82eef42017-11-24 20:40:12 +0100422 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
423 }
424
Harald Welte0d846a72017-12-07 17:58:28 +0100425 /* Received RSL -> down into IPA */
426 [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
427 IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
428 }
Harald Weltec82eef42017-11-24 20:40:12 +0100429
Harald Welte0d846a72017-12-07 17:58:28 +0100430
431 /* Received MISC (OML/CTRL) -> down into IPA */
Harald Weltec76f29f2017-11-22 12:46:46 +0100432 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
433 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
434 }
435
436
Harald Welted86cdc62017-11-22 00:45:07 +0100437 }
438 }
439}
440
441}