blob: e5a05bc1647d4e6c6e7a736416a8ce8851445972 [file] [log] [blame]
Harald Welte4029e8c2017-11-23 22:00:42 +01001module MGCP_Templates {
2
Harald Welte35bb7162018-01-03 21:07:52 +01003/* MGCP Templates, building on top of MGCP_Types (Osmocom) and SDP_Types from Ericsson.
4 *
5 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 */
11
12
Harald Welte4029e8c2017-11-23 22:00:42 +010013 import from MGCP_Types all;
14 import from SDP_Types all;
15
16 function f_mgcp_par_append(inout template MgcpParameterList list, template MgcpParameter par) {
17 var integer len := lengthof(list);
18 list[len] := par;
19 }
20
21 /* 3.2.2.6 Connection Mode (sendonly, recvonly, sendrecv, confrnce, inactive, loopback,
22 * conttest, netwloop, netwtest) */
23 template MgcpParameter t_MgcpParConnMode(template MgcpConnectionMode mode) := { "M", mode };
24
25 /* 3.2.2.2 CallId: maximum 32 hex chars */
26 template MgcpParameter ts_MgcpParCallId(MgcpCallId cid) := {
27 code := "C",
28 val := hex2str(cid)
29 };
30
31 /* 3.2.2.18 RequestIdentifier: Maximum 32 hex chars */
32 template MgcpParameter ts_MgcpParReqId(MgcpRequestId rid) := {
33 code := "X",
34 val := hex2str(rid)
35 };
36
Harald Welte363cb0a2018-01-30 19:35:53 +010037 /* 3.2.1.3 SpecificEndpointId */
38 template MgcpParameter ts_MgcpParSpecEP(MgcpEndpoint ep) := {
39 code := "Z",
40 val := ep
41 };
42
Harald Welte4029e8c2017-11-23 22:00:42 +010043 /* 3.2.2.10: LocalConnectionOptions (codec, packetization, bandwidth, ToS, eco, gain, silence, ...) */
44 template MgcpParameter t_MgcpParLocConnOpt(template charstring lco) := { "L", lco };
45
46 /* 3.2.2.5: ConnectionId: maximum 32 hex chars */
47 template MgcpParameter ts_MgcpParConnectionId(MgcpConnectionId cid) := {
48 code := "I",
49 val := hex2str(cid)
50 };
51
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +020052 /* Osmocom extension: X-Osmux: {*,%u} */
53 template MgcpParameter ts_MgcpParOsmuxCID(MgcpOsmuxCID osmux_cid) := {
54 code := "X-OSMUX",
55 val := f_mgcp_osmux_cid_encode(osmux_cid)
56 };
57
Pau Espin Pedrolbefd3aa2020-09-21 10:54:42 +020058 /* Osmocom extension: X-Osmux: {*,%u} */
59 template MgcpParameter t_MgcpParOsmoIGN(template charstring val) := {
60 code := "X-OSMO-IGN",
61 val := val
62 };
63
Harald Welte4029e8c2017-11-23 22:00:42 +010064 /* osmo-bsc_mgcp implements L/C/M/X only, osmo-mgw adds 'I' */
65 /* SDP: osmo-bsc_mgcp implements Tx of v,o,s,c,t,m,a */
66
Vadim Yanitskiy87ebd0b2022-06-28 03:58:33 +070067 template (value) MgcpResponse
68 ts_MgcpResp_Err(template (value) MgcpTransId trans_id,
69 template (value) MgcpResponseCode code,
70 template (value) charstring string := "FAIL") := {
71 line := {
72 code := code,
73 trans_id := trans_id,
74 string := string
75 },
76 params := {},
77 sdp := omit
78 }
79 template MgcpResponse
80 tr_MgcpResp_Err(template (present) MgcpResponseCode code) := {
Harald Welte4029e8c2017-11-23 22:00:42 +010081 line := {
82 code := code,
83 trans_id := ?,
84 string := ?
85 },
86 params := {},
87 sdp := omit
88 }
89
90 template MgcpCommandLine t_MgcpCmdLine(template charstring verb, template MgcpTransId trans_id, template charstring ep) := {
91 verb := verb,
92 trans_id := trans_id,
93 ep := ep,
94 ver := "1.0"
95 };
96
97 template MgcpCommand ts_CRCX(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, template SDP_Message sdp := omit) := {
98 line := t_MgcpCmdLine("CRCX", trans_id, ep),
99 params := {
100 t_MgcpParConnMode(mode),
101 ts_MgcpParCallId(call_id),
102 //t_MgcpParReqId(omit),
Daniel Willmannfbef7142017-11-30 13:16:14 +0100103 t_MgcpParLocConnOpt("p:20, a:AMR")
Harald Welte4029e8c2017-11-23 22:00:42 +0100104 },
105 sdp := sdp
106 }
107
Philipp Maier45635f42018-06-05 17:28:02 +0200108 template MgcpCommand ts_CRCX_no_lco(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, template SDP_Message sdp := omit) := {
109 line := t_MgcpCmdLine("CRCX", trans_id, ep),
110 params := {
111 t_MgcpParConnMode(mode),
112 ts_MgcpParCallId(call_id)
113 },
114 sdp := sdp
115 }
116
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200117 template MgcpCommand ts_CRCX_osmux(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
118 line := t_MgcpCmdLine("CRCX", trans_id, ep),
119 params := {
120 t_MgcpParConnMode(mode),
121 ts_MgcpParCallId(call_id),
122 //t_MgcpParReqId(omit),
123 t_MgcpParLocConnOpt("p:20, a:AMR"),
124 ts_MgcpParOsmuxCID(osmux_cid)
125 },
126 sdp := sdp
127 }
128
Daniel Willmannfdb48682022-02-08 16:22:59 +0100129 template MgcpCommand tr_CRCX(template MgcpEndpoint ep := ?, template SDP_Message sdp := *) := {
Harald Welte4017d552018-01-26 21:40:05 +0100130 line := t_MgcpCmdLine("CRCX", ?, ep),
Harald Welte90029572017-11-24 23:39:50 +0100131 params := *,
Daniel Willmannfdb48682022-02-08 16:22:59 +0100132 sdp := sdp
Harald Welte90029572017-11-24 23:39:50 +0100133 }
134
Harald Welte4029e8c2017-11-23 22:00:42 +0100135 template MgcpResponse tr_CRCX_ACK := {
136 line := {
137 code := "200",
Harald Welte51f34ad2017-11-24 20:40:43 +0100138 trans_id := ?,
Harald Welte4029e8c2017-11-23 22:00:42 +0100139 string := "OK"
140 },
141 params:= { { "I", ? }, *},
142 sdp := ?
143 }
144
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200145 template MgcpResponse tr_CRCX_ACK_osmux := {
146 line := {
147 code := "200",
148 trans_id := ?,
149 string := "OK"
150 },
151 params:= { { "I", ? }, {"X-OSMUX", ?}, *},
152 sdp := ?
153 }
154
Harald Welte90029572017-11-24 23:39:50 +0100155 template MgcpResponse ts_CRCX_ACK(MgcpTransId trans_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := {
156 line := {
157 code := "200",
158 trans_id := trans_id,
159 string := "OK"
160 },
161 params:= { ts_MgcpParConnectionId(conn_id) },
162 sdp := sdp
163 }
164
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200165 template MgcpResponse ts_CRCX_ACK_osmux(MgcpTransId trans_id, MgcpConnectionId conn_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
166 line := {
167 code := "200",
168 trans_id := trans_id,
169 string := "OK"
170 },
171 params:= {
172 ts_MgcpParConnectionId(conn_id),
173 ts_MgcpParOsmuxCID(osmux_cid)
174 },
175 sdp := sdp
176 }
177
Harald Welte4029e8c2017-11-23 22:00:42 +0100178 template MgcpCommand ts_MDCX(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := {
179 line := t_MgcpCmdLine("MDCX", trans_id, ep),
180 params := {
181 t_MgcpParConnMode(mode),
182 ts_MgcpParCallId(call_id),
183 ts_MgcpParConnectionId(conn_id),
184 //t_MgcpParReqId(omit),
Daniel Willmannfbef7142017-11-30 13:16:14 +0100185 t_MgcpParLocConnOpt("p:20, a:AMR")
Harald Welte4029e8c2017-11-23 22:00:42 +0100186 },
187 sdp := sdp
188 }
189
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200190 template MgcpCommand ts_MDCX_osmux(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpConnectionId conn_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
191 line := t_MgcpCmdLine("MDCX", trans_id, ep),
192 params := {
193 t_MgcpParConnMode(mode),
194 ts_MgcpParCallId(call_id),
195 ts_MgcpParConnectionId(conn_id),
196 //t_MgcpParReqId(omit),
197 t_MgcpParLocConnOpt("p:20, a:AMR"),
198 ts_MgcpParOsmuxCID(osmux_cid)
199 },
200 sdp := sdp
201 }
202
Daniel Willmannfdb48682022-02-08 16:22:59 +0100203 template MgcpCommand tr_MDCX(template SDP_Message sdp := *) := {
Harald Welte90029572017-11-24 23:39:50 +0100204 line := t_MgcpCmdLine("MDCX", ?, ?),
205 params := *,
Daniel Willmannfdb48682022-02-08 16:22:59 +0100206 sdp := sdp
Harald Welte90029572017-11-24 23:39:50 +0100207 }
208
Harald Weltebb7523b2018-03-29 08:52:01 +0200209 template MgcpResponse tr_MDCX_ACK := {
210 line := {
211 code := "200",
212 trans_id := ?,
213 string := "OK"
214 },
215 params := *,
216 sdp := ?
217 }
218
Harald Welte90029572017-11-24 23:39:50 +0100219 template MgcpResponse ts_MDCX_ACK(MgcpTransId trans_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := ts_CRCX_ACK(trans_id, conn_id, sdp);
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200220 template MgcpResponse ts_MDCX_ACK_osmux(MgcpTransId trans_id, MgcpConnectionId conn_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := ts_CRCX_ACK_osmux(trans_id, conn_id, osmux_cid, sdp);
Harald Welte90029572017-11-24 23:39:50 +0100221
Harald Welte4029e8c2017-11-23 22:00:42 +0100222 /* have a function that generates a template, rather than a template in order to handle
223 * optional parameters */
224 function ts_DLCX(MgcpTransId trans_id, charstring ep, template MgcpCallId call_id := omit,
225 template MgcpConnectionId conn_id := omit) return template MgcpCommand {
226 var template MgcpCommand cmd;
227 cmd.line := t_MgcpCmdLine("DLCX", trans_id, ep);
228 cmd.params := {};
229 cmd.sdp := omit;
230 if (isvalue(call_id)) {
231 f_mgcp_par_append(cmd.params, ts_MgcpParCallId(valueof(call_id)));
232 if (isvalue(conn_id)) {
233 f_mgcp_par_append(cmd.params, ts_MgcpParConnectionId(valueof(conn_id)));
234 }
235 }
236 return cmd;
237 }
238
Harald Welteb71901a2018-01-26 19:16:05 +0100239 template MgcpCommand tr_DLCX(template MgcpEndpoint ep := ?) := {
240 line := t_MgcpCmdLine("DLCX", ?, ep),
Harald Welte90029572017-11-24 23:39:50 +0100241 params := *,
242 sdp := *
243 }
244
Harald Weltec82eef42017-11-24 20:40:12 +0100245 template MgcpResponse tr_DLCX_ACK := {
246 line := {
Daniel Willmann961e5c92017-11-30 16:37:40 +0100247 code := ("200", "250"),
Harald Weltec82eef42017-11-24 20:40:12 +0100248 trans_id := ?,
249 string := "OK"
250 },
251 params:= *,
252 sdp := *
253 }
254
Harald Welteb71901a2018-01-26 19:16:05 +0100255 template MgcpResponse ts_DLCX_ACK2(MgcpTransId trans_id) := {
256 line := {
257 code := "250",
258 trans_id := trans_id,
259 string := "OK"
260 },
261 params:= { /* list of ConnectionIDs */ },
262 sdp := omit
263 }
264
265
266
Harald Welte90029572017-11-24 23:39:50 +0100267 template MgcpResponse ts_DLCX_ACK(MgcpTransId trans_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := ts_CRCX_ACK(trans_id, conn_id, sdp);
268
Harald Weltee98bb2e2017-11-29 12:09:48 +0100269 template MgcpCommand tr_RSIP := {
270 line := t_MgcpCmdLine("RSIP", ?, ?),
271 params := *,
272 sdp := *
273 }
274
Harald Welte4029e8c2017-11-23 22:00:42 +0100275 /* SDP Templates */
276 template SDP_Origin ts_SDP_origin(charstring addr, charstring session_id,
277 charstring session_version := "1",
278 charstring addr_type := "IP4",
279 charstring user_name := "-") := {
280 user_name := user_name,
281 session_id := session_id,
282 session_version := session_version,
283 net_type := "IN",
284 addr_type := addr_type,
285 addr := addr
286 }
287
288 template SDP_connection ts_SDP_connection_IP(charstring addr, charstring addr_type := "IP4",
289 template integer ttl := omit,
290 template integer num_of_addr := omit) :={
291 net_type := "IN",
292 addr_type := addr_type,
293 conn_addr := {
294 addr := addr,
295 ttl := ttl,
296 num_of_addr := num_of_addr
297 }
298 }
299
Daniel Willmannfdb48682022-02-08 16:22:59 +0100300 template SDP_connection tr_SDP_connection_IP(template charstring addr, template charstring addr_type := ?,
301 template integer ttl := *,
302 template integer num_of_addr := *) := {
303 net_type := "IN",
304 addr_type := addr_type,
305 conn_addr := {
306 addr := addr,
307 ttl := ttl,
308 num_of_addr := num_of_addr
309 }
310 }
311
Harald Welte4029e8c2017-11-23 22:00:42 +0100312 template SDP_time ts_SDP_time(charstring beg, charstring end) := {
313 time_field := {
314 start_time := beg,
315 stop_time := end
316 },
317 time_repeat := omit
318 }
319
320 template SDP_media_desc ts_SDP_media_desc(integer port_number, SDP_fmt_list fmts,
321 SDP_attribute_list attributes) := {
322 media_field := {
323 media := "audio",
324 ports := {
325 port_number := port_number,
326 num_of_ports := omit
327 },
328 transport := "RTP/AVP",
329 fmts := fmts
330 },
331 information := omit,
332 connections := omit,
333 bandwidth := omit,
334 key := omit,
335 attributes := attributes
336 }
337
Daniel Willmannfdb48682022-02-08 16:22:59 +0100338 template SDP_media_desc tr_SDP_media_desc(template integer port_number := ?,
339 template SDP_fmt_list fmts := ?,
340 template SDP_attribute_list attributes := ?) := {
341 media_field := {
342 media := "audio",
343 ports := {
344 port_number := port_number,
345 num_of_ports := omit
346 },
347 transport := "RTP/AVP",
348 fmts := fmts
349 },
350 information := *,
351 connections := *,
352 bandwidth := *,
353 key := *,
354 attributes := attributes
355 }
356
Harald Welte4029e8c2017-11-23 22:00:42 +0100357 /* master template for generating SDP based in template arguments */
358 template SDP_Message ts_SDP(charstring local_addr, charstring remote_addr,
359 charstring session_id, charstring session_version,
360 integer rtp_port, SDP_fmt_list fmts,
361 SDP_attribute_list attributes) := {
362 protocol_version := 0,
Pau Espin Pedrol384e9492020-09-03 17:05:19 +0200363 origin := ts_SDP_origin(local_addr, session_id, session_version, f_mgcp_addr2addrtype(local_addr)),
Harald Welte4029e8c2017-11-23 22:00:42 +0100364 session_name := "-",
365 information := omit,
366 uri := omit,
367 emails := omit,
368 phone_numbers := omit,
Pau Espin Pedrol384e9492020-09-03 17:05:19 +0200369 connection := ts_SDP_connection_IP(remote_addr, f_mgcp_addr2addrtype(remote_addr)),
Harald Welte4029e8c2017-11-23 22:00:42 +0100370 bandwidth := omit,
371 times := { ts_SDP_time("0","0") },
372 timezone_adjustments := omit,
373 key := omit,
374 attributes := omit,
375 media_list := { ts_SDP_media_desc(rtp_port, fmts, attributes) }
376 }
377
Daniel Willmannfdb48682022-02-08 16:22:59 +0100378 template SDP_Message tr_SDP(template charstring remote_addr := ?, template integer rtp_port := ?) := {
379 protocol_version := 0,
380 origin := ?,
381 session_name := ?,
382 information := *,
383 uri := *,
384 emails := *,
385 phone_numbers := *,
386 connection := tr_SDP_connection_IP(remote_addr, ?),
387 bandwidth := *,
388 times := ?,
389 timezone_adjustments := *,
390 key := *,
391 attributes := *,
392 media_list := { tr_SDP_media_desc(rtp_port) }
393 }
394
Harald Welte4029e8c2017-11-23 22:00:42 +0100395 template SDP_attribute ts_SDP_rtpmap(integer fmt, charstring val) := {
396 rtpmap := {
397 attr_value := int2str(fmt) & " " & val
398 }
399 }
400 template SDP_attribute ts_SDP_ptime(integer p) := {
401 ptime := {
402 attr_value := int2str(p)
403 }
404 }
Philipp Maierc8c0b402019-03-07 10:48:45 +0100405 template SDP_attribute ts_SDP_fmtp(integer fmt, charstring val) := {
406 fmtp := {
407 attr_value := int2str(fmt) & " " & val
408 }
409 }
Harald Welte4029e8c2017-11-23 22:00:42 +0100410
Pau Espin Pedrol384e9492020-09-03 17:05:19 +0200411 function f_mgcp_addr2addrtype(charstring addr) return charstring {
412 for (var integer i := 0; i < lengthof(addr); i := i + 1) {
413 if (addr[i] == ":") {
414 return "IP6";
415 }
416 }
417 return "IP4";
418 }
419
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200420 /* -1 is wildcard, positive is translated as string */
421 function f_mgcp_osmux_cid_encode(MgcpOsmuxCID osmux_cid) return charstring {
422 if (osmux_cid == -1) {
423 return "*";
424 }
425 return int2str(osmux_cid);
426 }
427
428 function f_mgcp_osmux_cid_decode(charstring osmux_cid) return MgcpOsmuxCID {
429 if (osmux_cid == "*") {
430 return -1;
431 }
432 return str2int(osmux_cid);
433 }
434
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100435 function f_mgcp_contains_par(MgcpMessage msg, MgcpInfoCode code) return boolean {
436 var MgcpParameterList pars;
437 if (ischosen(msg.command)) {
438 pars := msg.command.params;
439 } else {
440 pars := msg.response.params;
441 }
442 for (var integer i := 0; i < lengthof(pars); i := i + 1) {
443 var MgcpParameter par := pars[i];
444 if (par.code == code) {
445 return true;
446 }
447 }
448 return false;
449 }
450
Harald Welteb71901a2018-01-26 19:16:05 +0100451 function f_mgcp_extract_par(MgcpMessage msg, MgcpInfoCode code) return charstring {
452 var MgcpParameterList pars;
453 if (ischosen(msg.command)) {
454 pars := msg.command.params;
455 } else {
456 pars := msg.response.params;
457 }
458 for (var integer i := 0; i < lengthof(pars); i := i + 1) {
459 var MgcpParameter par := pars[i];
460 if (par.code == code) {
461 return par.val;
Harald Welte4c11d562017-11-24 23:39:00 +0100462 }
463 }
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200464 setverdict(fail, "Could not extract parameters for code ", code);
Harald Welteb71901a2018-01-26 19:16:05 +0100465 return "";
466 }
467
Harald Welte1fe74812018-01-29 21:57:26 +0100468 function f_MgcpResp_extract_par(MgcpResponse resp, MgcpInfoCode code) return charstring {
Harald Welteb71901a2018-01-26 19:16:05 +0100469 var MgcpMessage msg := {
470 response := resp
471 }
Harald Welte1fe74812018-01-29 21:57:26 +0100472 return f_mgcp_extract_par(msg, code);
Harald Welteb71901a2018-01-26 19:16:05 +0100473 }
474
Harald Welte1fe74812018-01-29 21:57:26 +0100475 function f_MgcpCmd_extract_par(MgcpCommand cmd, MgcpInfoCode code) return charstring {
Harald Welteb71901a2018-01-26 19:16:05 +0100476 var MgcpMessage msg := {
477 command := cmd
478 }
Harald Welte1fe74812018-01-29 21:57:26 +0100479 return f_mgcp_extract_par(msg, code);
Harald Welte4c11d562017-11-24 23:39:00 +0100480 }
481
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100482 function f_MgcpCmd_contains_par(MgcpCommand cmd, MgcpInfoCode code) return boolean {
483 var MgcpMessage msg := {
484 command := cmd
485 }
486 return f_mgcp_contains_par(msg, code);
487 }
488
Harald Welte1fe74812018-01-29 21:57:26 +0100489 function f_MgcpResp_extract_conn_id(MgcpResponse resp) return MgcpConnectionId {
490 return str2hex(f_MgcpResp_extract_par(resp, "I"));
491 }
492
493 function f_MgcpCmd_extract_call_id(MgcpCommand cmd) return MgcpCallId {
494 return str2hex(f_MgcpCmd_extract_par(cmd, "C"));
495 }
496
497 function f_MgcpCmd_extract_conn_id(MgcpCommand cmd) return MgcpConnectionId {
498 return str2hex(f_MgcpCmd_extract_par(cmd, "I"));
499 }
500
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200501 function f_MgcpCmd_extract_osmux_cid(MgcpCommand cmd) return MgcpOsmuxCID {
502 return f_mgcp_osmux_cid_decode(f_MgcpCmd_extract_par(cmd, "X-OSMUX"));
503 }
504
Harald Welte1fe74812018-01-29 21:57:26 +0100505
Harald Welte4c11d562017-11-24 23:39:00 +0100506 function f_mgcp_alloc_tid() return MgcpTransId {
507 return int2str(float2int(rnd()*2147483647.0));
508 }
509
510 function f_mgcp_alloc_call_id() return MgcpCallId {
511 return int2hex(float2int(rnd()*2147483647.0), 8);
512 }
513
514 function f_mgcp_alloc_conn_id() return MgcpConnectionId {
515 return int2hex(float2int(rnd()*2147483647.0), 8);
516 }
517
Harald Weltebb5a1212018-01-26 10:34:44 +0100518 /* those verbs that related to a connection (and hence have ConnectionId) */
519 template MgcpVerb tr_MgcpVerb_ConnectionOriented := ("CRCX", "MDCX", "DLCX", "AUCX");
520 /* entire command template matching only connection oriented verbs */
521 template MgcpCommand tr_MgcpCommand_CO := {
522 line := {
523 verb := tr_MgcpVerb_ConnectionOriented,
524 trans_id := ?,
525 ep := ?,
526 ver := ?
527 },
528 params := *,
529 sdp := *
530 }
531
Neels Hofmeyrac7526d2019-10-15 16:54:37 +0200532 function f_mgcp_find_param_entry(MgcpParameterList pars, MgcpInfoCode code, out charstring ret)
533 return boolean {
534 for (var integer i := 0; i < sizeof(pars); i := i+1) {
535 if (pars[i].code == code) {
536 ret := pars[i].val;
537 return true;
538 }
539 }
540 return false;
541 }
542
Harald Welte363cb0a2018-01-30 19:35:53 +0100543 function f_mgcp_find_param(MgcpMessage msg, MgcpInfoCode code, out charstring ret)
544 return boolean {
545 var MgcpParameterList pars;
546 if (ischosen(msg.command)) {
547 pars := msg.command.params;
548 } else {
549 pars := msg.response.params;
550 }
Neels Hofmeyrac7526d2019-10-15 16:54:37 +0200551 return f_mgcp_find_param_entry(pars, code, ret);
Harald Welte363cb0a2018-01-30 19:35:53 +0100552 }
553
554 /* template to determine if a MGCP endpoint is a wildcard endpoint */
555 template charstring t_MGCP_EP_wildcard := (pattern "\*@*", pattern "rtpbridge/\*@*");
556
Harald Welteb71901a2018-01-26 19:16:05 +0100557
Harald Welte4029e8c2017-11-23 22:00:42 +0100558}