blob: 1209ff60c570b76767ee98afcc03ad979f31c47a [file] [log] [blame]
Daniel Willmannfa870f52018-01-17 12:37:14 +01001module MGCP_Emulation {
2
3import from MGCP_CodecPort all;
4import from MGCP_CodecPort_CtrlFunct all;
5import from MGCP_Types all;
6import from MGCP_Templates all;
7import from Osmocom_Types all;
8import from IPL4asp_Types all;
9
10type component MGCP_ConnHdlr {
11 port MGCP_Conn_PT MGCP;
Harald Weltec27eaae2018-01-25 18:43:23 +010012 var MgcpConnectionId mgcp_conn_id;
Daniel Willmannfa870f52018-01-17 12:37:14 +010013}
14
15/* port between individual per-connection components and this dispatcher */
16type port MGCP_Conn_PT message {
17 inout MgcpCommand, MgcpResponse;
18} with { extension "internal" };
19
20
21type component MGCP_Emulation_CT {
22 /* Port facing to the UDP SUT */
23 port MGCP_CODEC_PT MGCP;
24 /* All MGCP_ConnHdlr MGCP ports connect here
25 * MGCP_Emulation_CT.main needs to figure out what messages
26 * to send where with CLIENT.send() to vc_conn */
27 port MGCP_Conn_PT CLIENT;
28 /* currently tracked connections */
29// var ConnectionData ConnectionTable[16];
30 /* pending expected CRCX */
31 var ExpectData ExpectTable[8];
32 /* procedure based port to register for incoming connections */
33 port MGCPEM_PROC_PT PROC;
34
35 var charstring g_mgcp_id;
Daniel Willmann166bbb32018-01-17 15:28:04 +010036 var integer g_mgcp_conn_id := -1;
Daniel Willmannfa870f52018-01-17 12:37:14 +010037}
38
39type function MGCPCreateCallback(MgcpCommand cmd, charstring id)
40runs on MGCP_Emulation_CT return MGCP_ConnHdlr;
41
42type record MGCPOps {
43 MGCPCreateCallback create_cb
44}
45
46type record MGCP_conn_parameters {
47 charstring callagent_ip,
48 uint16_t callagent_udp_port,
49 charstring mgw_ip,
50 uint16_t mgw_udp_port
51}
52
Daniel Willmann166bbb32018-01-17 15:28:04 +010053function tr_MGCP_RecvFrom_R(template MgcpMessage msg)
54runs on MGCP_Emulation_CT return template MGCP_RecvFrom {
55 var template MGCP_RecvFrom mrf := {
56 connId := g_mgcp_conn_id,
57 remName := ?,
58 remPort := ?,
59 locName := ?,
60 locPort := ?,
61 msg := msg
62 }
63 return mrf;
64}
65
Daniel Willmann955627a2018-01-17 15:22:32 +010066function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_Emulation_CT {
Daniel Willmannfa870f52018-01-17 12:37:14 +010067 var Result res;
68 g_mgcp_id := id;
69 //f_conn_table_init();
Daniel Willmann955627a2018-01-17 15:22:32 +010070 f_expect_table_init();
Daniel Willmannfa870f52018-01-17 12:37:14 +010071
72 map(self:MGCP, system:MGCP_CODEC_PT);
73 res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.mgw_ip,
74p.mgw_udp_port,
75 p.callagent_ip, p.callagent_udp_port, 0, { udp:={} });
76
Daniel Willmann166bbb32018-01-17 15:28:04 +010077 g_mgcp_conn_id := res.connId;
Daniel Willmannfa870f52018-01-17 12:37:14 +010078
79 while (true) {
Daniel Willmann166bbb32018-01-17 15:28:04 +010080 var MGCP_ConnHdlr vc_conn;
81 var ExpectCriteria crit;
82 var MGCP_RecvFrom mrf;
83 var MgcpMessage msg;
84 var MgcpCommand cmd;
85 var MgcpResponse resp;
86
Daniel Willmannfa870f52018-01-17 12:37:14 +010087 alt {
Daniel Willmann166bbb32018-01-17 15:28:04 +010088 /* MGCP from client */
89 [] CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn {
90 /* Pass message through */
91 msg.response := resp;
92 MGCP.send(t_MGCP_Send(g_mgcp_conn_id, msg));
Daniel Willmannfa870f52018-01-17 12:37:14 +010093 }
Daniel Willmann166bbb32018-01-17 15:28:04 +010094 [] MGCP.receive(tr_MGCP_RecvFrom_R(?)) -> value mrf {
95 if (ischosen(mrf.msg.command)) {
96 cmd := mrf.msg.command;
97 vc_conn := ops.create_cb.apply(cmd, id);
98 f_handle_userData(vc_conn, cmd);
99 } else {
100 setverdict(fail, "Received unexpected MGCP response: ", mrf.msg.response);
101 self.stop;
102 }
Daniel Willmannfa870f52018-01-17 12:37:14 +0100103 }
Daniel Willmann955627a2018-01-17 15:22:32 +0100104 [] PROC.getcall(MGCPEM_register:{?,?}) -> param(crit, vc_conn) {
105 f_create_expect(crit, vc_conn);
106 PROC.reply(MGCPEM_register:{crit, vc_conn});
107 }
Daniel Willmannfa870f52018-01-17 12:37:14 +0100108 }
109 }
110}
111
Daniel Willmann166bbb32018-01-17 15:28:04 +0100112private function f_handle_userData(MGCP_ConnHdlr conn, MgcpCommand cmd)
113runs on MGCP_Emulation_CT {
114 CLIENT.send(cmd) to conn;
115}
116
Daniel Willmannfa870f52018-01-17 12:37:14 +0100117/* "Expect" Handling */
118
119/* */
Daniel Willmann955627a2018-01-17 15:22:32 +0100120type record ExpectCriteria {
121 MgcpConnectionId connid optional,
122 MgcpEndpoint endpoint optional,
123 MgcpTransId transid optional
Daniel Willmannfa870f52018-01-17 12:37:14 +0100124}
125
126type record ExpectData {
127 ExpectCriteria crit optional,
Daniel Willmann955627a2018-01-17 15:22:32 +0100128 MGCP_ConnHdlr vc_conn
Daniel Willmannfa870f52018-01-17 12:37:14 +0100129}
130
Daniel Willmann955627a2018-01-17 15:22:32 +0100131signature MGCPEM_register(in ExpectCriteria cmd, in MGCP_ConnHdlr hdlr);
Daniel Willmannfa870f52018-01-17 12:37:14 +0100132
133type port MGCPEM_PROC_PT procedure {
134 inout MGCPEM_register;
135} with { extension "internal" };
136
137function f_get_mgcp_by_crit(ExpectCriteria crit)
138return template MgcpCommand {
139 template MgcpCommand ret := {
140 };
141
142 return ret;
143}
144
145/* Function that can be used as create_cb and will usse the expect table */
146function ExpectedCreateCallback(MgcpCommand cmd, charstring id)
147runs on MGCP_Emulation_CT return MGCP_ConnHdlr {
148 var MGCP_ConnHdlr ret := null;
149 var template MgcpCommand mgcpcmd;
150 var integer i;
151
152 /* Ensure cmd is a CRCX? */
153
154 for (i := 0; i < sizeof(ExpectTable); i := i+1) {
Daniel Willmann955627a2018-01-17 15:22:32 +0100155 if (not ispresent(ExpectTable[i].crit)) {
Daniel Willmannfa870f52018-01-17 12:37:14 +0100156 continue;
157 }
Daniel Willmann955627a2018-01-17 15:22:32 +0100158 /* FIXME: Ignore criteria for now */
159// mgcpcmd := f_get_mgcp_by_crit(ExpectTable[i].crit);
160// if (match(cmd, mgcpcmd)) {
Daniel Willmannfa870f52018-01-17 12:37:14 +0100161 ret := ExpectTable[i].vc_conn;
162 /* Release this entry */
163 ExpectTable[i].crit := omit;
164 ExpectTable[i].vc_conn := null;
165 log("Found Expect[", i, "] for ", cmd, " handled at ", ret);
166 return ret;
Daniel Willmann955627a2018-01-17 15:22:32 +0100167// }
Daniel Willmannfa870f52018-01-17 12:37:14 +0100168 }
169 setverdict(fail, "Couldn't find Expect for CRCX", cmd);
170 return ret;
171}
172
173private function f_create_expect(ExpectCriteria crit, MGCP_ConnHdlr hdlr)
174runs on MGCP_Emulation_CT {
175 var integer i;
176
177 /* Check an entry like this is not already presnt */
178 for (i := 0; i < sizeof(ExpectTable); i := i+1) {
179 if (crit == ExpectTable[i].crit) {
180 setverdict(fail, "Crit already present", crit);
181 self.stop;
182 }
183 }
184 for (i := 0; i < sizeof(ExpectTable); i := i+1) {
185 if (not ispresent(ExpectTable[i].crit)) {
186 ExpectTable[i].crit := crit;
187 ExpectTable[i].vc_conn := hdlr;
188 log("Created Expect[", i, "] for ", crit, " to be handled at ", hdlr);
189 return;
190 }
191 }
192 setverdict(fail, "No space left in ExpectTable")
193}
194
Daniel Willmann955627a2018-01-17 15:22:32 +0100195private function f_expect_table_init()
196runs on MGCP_Emulation_CT {
197 var integer i;
198 for (i := 0; i < sizeof(ExpectTable); i := i + 1) {
199 ExpectTable[i].crit := omit;
200 }
201}
202
Daniel Willmannfa870f52018-01-17 12:37:14 +0100203}