blob: ed5111032effbc2502308cfabe10435ab67c1dff [file] [log] [blame]
Harald Welted86cdc62017-11-22 00:45:07 +01001module IPA_Emulation {
2
3import from IPA_Types all;
4import from IPA_CodecPort all;
5import from IPA_CodecPort_CtrlFunct all;
6import from IPL4asp_Types all;
7import from MTP3asp_Types all;
8import from MTP3asp_PortType all;
9
10/*
11modulepar {
12}
13*/
14
Harald Welteb3414b22017-11-23 18:22:10 +010015type enumerated IpaMode {
16 IPA_MODE_CLIENT,
17 IPA_MODE_SERVER
18}
19
Harald Weltec76f29f2017-11-22 12:46:46 +010020type record ASP_IPA_Unitdata {
21 IpaStreamId streamId,
22 octetstring payload
23}
24
25type port IPA_SP_PT message {
26 inout ASP_IPA_Unitdata;
27} with { extension "internal" }
28
Harald Welted86cdc62017-11-22 00:45:07 +010029type component IPA_Emulation_CT {
30 /* down-facing port to IPA codec port */
31 port IPA_CODEC_PT IPA_PORT;
32 /* up-facing port to SCCP */
33 port MTP3asp_SP_PT MTP3_SP_PORT;
Harald Weltec76f29f2017-11-22 12:46:46 +010034 /* up-facing port for other streams */
35 port IPA_SP_PT IPA_SP_PORT;
Harald Welted86cdc62017-11-22 00:45:07 +010036
37 var boolean g_initialized := false;
38 var ConnectionId g_ipa_conn_id := -1;
Harald Welteb3414b22017-11-23 18:22:10 +010039
40 var IpaMode g_mode;
Harald Welted86cdc62017-11-22 00:45:07 +010041}
42
43function f_connect(charstring remote_host, PortNumber remote_port,
44 charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
45 var Result res;
46 res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
47 local_host, local_port, 0, { tcp:={} });
48 g_ipa_conn_id := res.connId;
49}
50
Harald Welteb3414b22017-11-23 18:22:10 +010051function f_bind(charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
52 var Result res;
53 res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT,
54 local_host, local_port, { tcp:={} });
55 g_ipa_conn_id := res.connId;
56}
57
Harald Welted86cdc62017-11-22 00:45:07 +010058template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
59 sio := { '10'B, '00'B, '0011'B },
60 opc := opc,
61 dpc := 0,
62 sls := 0,
63 data := data
64}
65
66
67private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
68 len := 0, /* overwritten by codec */
69 tag := tag,
70 data := payload
71}
72
73/* build IPA CCM ID RESP response from IPA CCM GET */
74private function f_ccm_make_id_resp(PDU_IPA_CCM get) return PDU_IPA_CCM {
75 var integer i;
76 var PDU_IPA_CCM resp := {
77 msg_type := IPAC_MSGT_ID_RESP,
78 u := {
79 resp := {}
80 }
81 }
82
83 for (i := 0; i < sizeof(get.u.get); i := i + 1) {
84 var IpaCcmIdTag tag := get.u.get[i].tag;
85 var charstring foo;
86 select (tag) {
87 case (IPAC_IDTAG_UNIT) {
88 foo := "0/1/2";
89 }
90 case (IPAC_IDTAG_UNITNAME) {
91 foo := "mahlzeit";
92 }
93 case else {
94 foo := "foo";
95 }
96 }
97 resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
98 }
99
100 return resp;
101}
102
103/* transmit IPA CCM message */
104private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
105 var IPA_Send ipa_tx := {
106 connId := g_ipa_conn_id,
107 streamId := IPAC_PROTO_CCM,
108 msg := enc_PDU_IPA_CCM(ccm)
109 }
110 log("CCM Tx:", ccm);
111 IPA_PORT.send(ipa_tx);
112}
113
114template PDU_IPA_CCM ts_IPA_PONG := {
115 msg_type := IPAC_MSGT_PONG,
116 u := omit
117}
118
119template PDU_IPA_CCM ts_IPA_ACK := {
120 msg_type := IPAC_MSGT_ID_ACK,
121 u := omit
122}
123
Harald Welteb3414b22017-11-23 18:22:10 +0100124template PDU_IPA_CCM ts_IPA_ID_GET := {
125 msg_type := IPAC_MSGT_ID_GET,
126 u := {
127 get := {
128 { 1, IPAC_IDTAG_UNITNAME }
129 }
130 }
131}
132
Harald Welted86cdc62017-11-22 00:45:07 +0100133/* receive IPA CCM message */
134private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
135 select (ccm.msg_type) {
136 case (IPAC_MSGT_PING) {
137 f_ccm_tx(valueof(ts_IPA_PONG));
138 }
139 case (IPAC_MSGT_ID_ACK) {
140 f_ccm_tx(valueof(ts_IPA_ACK));
141 }
142 case (IPAC_MSGT_ID_GET) {
143 f_ccm_tx(f_ccm_make_id_resp(ccm));
144 }
145 case else {
146 log("Unknown/unsupported IPA CCM message type", ccm);
147 }
148 }
149}
150
Harald Weltec76f29f2017-11-22 12:46:46 +0100151private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
152 var ASP_IPA_Unitdata ret := {
153 streamId := ipa_rx.streamId,
154 payload := ipa_rx.msg
155 }
156 return ret;
157}
158
159private function f_from_asp(ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
160 var IPA_Send ret := {
161 connId := connId,
162 streamId := ipa_tx.streamId,
163 msg := ipa_tx.payload
164 }
165 return ret;
166}
Harald Welted86cdc62017-11-22 00:45:07 +0100167
Harald Welteb3414b22017-11-23 18:22:10 +0100168function main_client(charstring remote_host, PortNumber remote_port,
169 charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
170 g_mode := IPA_MODE_CLIENT;
171 f_connect(remote_host, remote_port, local_host, local_port);
172 ScanEvents();
173}
174
175function main_server(charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
176 g_mode := IPA_MODE_SERVER;
177 f_bind(local_host, local_port);
178 ScanEvents();
179}
180
181private function ScanEvents() runs on IPA_Emulation_CT {
Harald Welted86cdc62017-11-22 00:45:07 +0100182 var IPA_RecvFrom ipa_rx;
Harald Weltec76f29f2017-11-22 12:46:46 +0100183 var ASP_IPA_Unitdata ipa_ud;
Harald Welted86cdc62017-11-22 00:45:07 +0100184 var ASP_MTP3_TRANSFERreq mtp_req;
Harald Welteb3414b22017-11-23 18:22:10 +0100185 var ASP_Event asp_evt;
Harald Welted86cdc62017-11-22 00:45:07 +0100186
187 while (true) {
188 alt {
189 /* Received IPA -> up into SCCP stack */
190 [] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
191 select (ipa_rx.streamId) {
192 case (IPAC_PROTO_CCM) {
193 var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
194 log("CCM Rx:", ccm);
195 f_ccm_rx(ccm);
196 }
197 case (IPAC_PROTO_SCCP) {
198 var ASP_MTP3_TRANSFERind mtp;
199 mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
200 MTP3_SP_PORT.send(mtp);
201 }
202 case else {
Harald Weltec76f29f2017-11-22 12:46:46 +0100203 IPA_SP_PORT.send(f_to_asp(ipa_rx));
Harald Welted86cdc62017-11-22 00:45:07 +0100204 }
205 }
206 }
207
Harald Welteb3414b22017-11-23 18:22:10 +0100208 /* server only */
209 [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
210 log("IPA: Connected");
211 g_ipa_conn_id := asp_evt.connOpened.connId;
212 if (g_mode == IPA_MODE_SERVER) {
213 f_ccm_tx(valueof(ts_IPA_ID_GET));
214 }
215 }
216
217 [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
218 log("IPA: Closed");
219 g_ipa_conn_id := -1;
220 self.stop;
221 }
222
Harald Welted86cdc62017-11-22 00:45:07 +0100223 /* Received SCCP -> down into IPA */
224 [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
225 var IPA_Send ipa_tx := {
226 connId := g_ipa_conn_id,
227 streamId := IPAC_PROTO_SCCP,
228 msg := mtp_req.data
229 }
230 IPA_PORT.send(ipa_tx);
231 }
Harald Weltec76f29f2017-11-22 12:46:46 +0100232
233 /* Received MISC (RSL/OML/CTRL/MGCP) -> down into IPA */
234 [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
235 IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
236 }
237
238
Harald Welted86cdc62017-11-22 00:45:07 +0100239 }
240 }
241}
242
243}