blob: 2fd9b18ea5e6b27cb3bf08aa200e2f11a93afbe3 [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
67 template MgcpResponse tr_MgcpResp_Err(template MgcpResponseCode code) := {
68 line := {
69 code := code,
70 trans_id := ?,
71 string := ?
72 },
73 params := {},
74 sdp := omit
75 }
76
77 template MgcpCommandLine t_MgcpCmdLine(template charstring verb, template MgcpTransId trans_id, template charstring ep) := {
78 verb := verb,
79 trans_id := trans_id,
80 ep := ep,
81 ver := "1.0"
82 };
83
84 template MgcpCommand ts_CRCX(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, template SDP_Message sdp := omit) := {
85 line := t_MgcpCmdLine("CRCX", trans_id, ep),
86 params := {
87 t_MgcpParConnMode(mode),
88 ts_MgcpParCallId(call_id),
89 //t_MgcpParReqId(omit),
Daniel Willmannfbef7142017-11-30 13:16:14 +010090 t_MgcpParLocConnOpt("p:20, a:AMR")
Harald Welte4029e8c2017-11-23 22:00:42 +010091 },
92 sdp := sdp
93 }
94
Philipp Maier45635f42018-06-05 17:28:02 +020095 template MgcpCommand ts_CRCX_no_lco(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, template SDP_Message sdp := omit) := {
96 line := t_MgcpCmdLine("CRCX", trans_id, ep),
97 params := {
98 t_MgcpParConnMode(mode),
99 ts_MgcpParCallId(call_id)
100 },
101 sdp := sdp
102 }
103
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200104 template MgcpCommand ts_CRCX_osmux(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
105 line := t_MgcpCmdLine("CRCX", trans_id, ep),
106 params := {
107 t_MgcpParConnMode(mode),
108 ts_MgcpParCallId(call_id),
109 //t_MgcpParReqId(omit),
110 t_MgcpParLocConnOpt("p:20, a:AMR"),
111 ts_MgcpParOsmuxCID(osmux_cid)
112 },
113 sdp := sdp
114 }
115
Daniel Willmannfdb48682022-02-08 16:22:59 +0100116 template MgcpCommand tr_CRCX(template MgcpEndpoint ep := ?, template SDP_Message sdp := *) := {
Harald Welte4017d552018-01-26 21:40:05 +0100117 line := t_MgcpCmdLine("CRCX", ?, ep),
Harald Welte90029572017-11-24 23:39:50 +0100118 params := *,
Daniel Willmannfdb48682022-02-08 16:22:59 +0100119 sdp := sdp
Harald Welte90029572017-11-24 23:39:50 +0100120 }
121
Harald Welte4029e8c2017-11-23 22:00:42 +0100122 template MgcpResponse tr_CRCX_ACK := {
123 line := {
124 code := "200",
Harald Welte51f34ad2017-11-24 20:40:43 +0100125 trans_id := ?,
Harald Welte4029e8c2017-11-23 22:00:42 +0100126 string := "OK"
127 },
128 params:= { { "I", ? }, *},
129 sdp := ?
130 }
131
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200132 template MgcpResponse tr_CRCX_ACK_osmux := {
133 line := {
134 code := "200",
135 trans_id := ?,
136 string := "OK"
137 },
138 params:= { { "I", ? }, {"X-OSMUX", ?}, *},
139 sdp := ?
140 }
141
Harald Welte90029572017-11-24 23:39:50 +0100142 template MgcpResponse ts_CRCX_ACK(MgcpTransId trans_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := {
143 line := {
144 code := "200",
145 trans_id := trans_id,
146 string := "OK"
147 },
148 params:= { ts_MgcpParConnectionId(conn_id) },
149 sdp := sdp
150 }
151
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200152 template MgcpResponse ts_CRCX_ACK_osmux(MgcpTransId trans_id, MgcpConnectionId conn_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
153 line := {
154 code := "200",
155 trans_id := trans_id,
156 string := "OK"
157 },
158 params:= {
159 ts_MgcpParConnectionId(conn_id),
160 ts_MgcpParOsmuxCID(osmux_cid)
161 },
162 sdp := sdp
163 }
164
Harald Welte4029e8c2017-11-23 22:00:42 +0100165 template MgcpCommand ts_MDCX(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := {
166 line := t_MgcpCmdLine("MDCX", trans_id, ep),
167 params := {
168 t_MgcpParConnMode(mode),
169 ts_MgcpParCallId(call_id),
170 ts_MgcpParConnectionId(conn_id),
171 //t_MgcpParReqId(omit),
Daniel Willmannfbef7142017-11-30 13:16:14 +0100172 t_MgcpParLocConnOpt("p:20, a:AMR")
Harald Welte4029e8c2017-11-23 22:00:42 +0100173 },
174 sdp := sdp
175 }
176
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200177 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) := {
178 line := t_MgcpCmdLine("MDCX", trans_id, ep),
179 params := {
180 t_MgcpParConnMode(mode),
181 ts_MgcpParCallId(call_id),
182 ts_MgcpParConnectionId(conn_id),
183 //t_MgcpParReqId(omit),
184 t_MgcpParLocConnOpt("p:20, a:AMR"),
185 ts_MgcpParOsmuxCID(osmux_cid)
186 },
187 sdp := sdp
188 }
189
Daniel Willmannfdb48682022-02-08 16:22:59 +0100190 template MgcpCommand tr_MDCX(template SDP_Message sdp := *) := {
Harald Welte90029572017-11-24 23:39:50 +0100191 line := t_MgcpCmdLine("MDCX", ?, ?),
192 params := *,
Daniel Willmannfdb48682022-02-08 16:22:59 +0100193 sdp := sdp
Harald Welte90029572017-11-24 23:39:50 +0100194 }
195
Harald Weltebb7523b2018-03-29 08:52:01 +0200196 template MgcpResponse tr_MDCX_ACK := {
197 line := {
198 code := "200",
199 trans_id := ?,
200 string := "OK"
201 },
202 params := *,
203 sdp := ?
204 }
205
Harald Welte90029572017-11-24 23:39:50 +0100206 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 +0200207 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 +0100208
Harald Welte4029e8c2017-11-23 22:00:42 +0100209 /* have a function that generates a template, rather than a template in order to handle
210 * optional parameters */
211 function ts_DLCX(MgcpTransId trans_id, charstring ep, template MgcpCallId call_id := omit,
212 template MgcpConnectionId conn_id := omit) return template MgcpCommand {
213 var template MgcpCommand cmd;
214 cmd.line := t_MgcpCmdLine("DLCX", trans_id, ep);
215 cmd.params := {};
216 cmd.sdp := omit;
217 if (isvalue(call_id)) {
218 f_mgcp_par_append(cmd.params, ts_MgcpParCallId(valueof(call_id)));
219 if (isvalue(conn_id)) {
220 f_mgcp_par_append(cmd.params, ts_MgcpParConnectionId(valueof(conn_id)));
221 }
222 }
223 return cmd;
224 }
225
Harald Welteb71901a2018-01-26 19:16:05 +0100226 template MgcpCommand tr_DLCX(template MgcpEndpoint ep := ?) := {
227 line := t_MgcpCmdLine("DLCX", ?, ep),
Harald Welte90029572017-11-24 23:39:50 +0100228 params := *,
229 sdp := *
230 }
231
Harald Weltec82eef42017-11-24 20:40:12 +0100232 template MgcpResponse tr_DLCX_ACK := {
233 line := {
Daniel Willmann961e5c92017-11-30 16:37:40 +0100234 code := ("200", "250"),
Harald Weltec82eef42017-11-24 20:40:12 +0100235 trans_id := ?,
236 string := "OK"
237 },
238 params:= *,
239 sdp := *
240 }
241
Harald Welteb71901a2018-01-26 19:16:05 +0100242 template MgcpResponse ts_DLCX_ACK2(MgcpTransId trans_id) := {
243 line := {
244 code := "250",
245 trans_id := trans_id,
246 string := "OK"
247 },
248 params:= { /* list of ConnectionIDs */ },
249 sdp := omit
250 }
251
252
253
Harald Welte90029572017-11-24 23:39:50 +0100254 template MgcpResponse ts_DLCX_ACK(MgcpTransId trans_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := ts_CRCX_ACK(trans_id, conn_id, sdp);
255
Harald Weltee98bb2e2017-11-29 12:09:48 +0100256 template MgcpCommand tr_RSIP := {
257 line := t_MgcpCmdLine("RSIP", ?, ?),
258 params := *,
259 sdp := *
260 }
261
Harald Welte4029e8c2017-11-23 22:00:42 +0100262 /* SDP Templates */
263 template SDP_Origin ts_SDP_origin(charstring addr, charstring session_id,
264 charstring session_version := "1",
265 charstring addr_type := "IP4",
266 charstring user_name := "-") := {
267 user_name := user_name,
268 session_id := session_id,
269 session_version := session_version,
270 net_type := "IN",
271 addr_type := addr_type,
272 addr := addr
273 }
274
275 template SDP_connection ts_SDP_connection_IP(charstring addr, charstring addr_type := "IP4",
276 template integer ttl := omit,
277 template integer num_of_addr := omit) :={
278 net_type := "IN",
279 addr_type := addr_type,
280 conn_addr := {
281 addr := addr,
282 ttl := ttl,
283 num_of_addr := num_of_addr
284 }
285 }
286
Daniel Willmannfdb48682022-02-08 16:22:59 +0100287 template SDP_connection tr_SDP_connection_IP(template charstring addr, template charstring addr_type := ?,
288 template integer ttl := *,
289 template integer num_of_addr := *) := {
290 net_type := "IN",
291 addr_type := addr_type,
292 conn_addr := {
293 addr := addr,
294 ttl := ttl,
295 num_of_addr := num_of_addr
296 }
297 }
298
Harald Welte4029e8c2017-11-23 22:00:42 +0100299 template SDP_time ts_SDP_time(charstring beg, charstring end) := {
300 time_field := {
301 start_time := beg,
302 stop_time := end
303 },
304 time_repeat := omit
305 }
306
307 template SDP_media_desc ts_SDP_media_desc(integer port_number, SDP_fmt_list fmts,
308 SDP_attribute_list attributes) := {
309 media_field := {
310 media := "audio",
311 ports := {
312 port_number := port_number,
313 num_of_ports := omit
314 },
315 transport := "RTP/AVP",
316 fmts := fmts
317 },
318 information := omit,
319 connections := omit,
320 bandwidth := omit,
321 key := omit,
322 attributes := attributes
323 }
324
Daniel Willmannfdb48682022-02-08 16:22:59 +0100325 template SDP_media_desc tr_SDP_media_desc(template integer port_number := ?,
326 template SDP_fmt_list fmts := ?,
327 template SDP_attribute_list attributes := ?) := {
328 media_field := {
329 media := "audio",
330 ports := {
331 port_number := port_number,
332 num_of_ports := omit
333 },
334 transport := "RTP/AVP",
335 fmts := fmts
336 },
337 information := *,
338 connections := *,
339 bandwidth := *,
340 key := *,
341 attributes := attributes
342 }
343
Harald Welte4029e8c2017-11-23 22:00:42 +0100344 /* master template for generating SDP based in template arguments */
345 template SDP_Message ts_SDP(charstring local_addr, charstring remote_addr,
346 charstring session_id, charstring session_version,
347 integer rtp_port, SDP_fmt_list fmts,
348 SDP_attribute_list attributes) := {
349 protocol_version := 0,
Pau Espin Pedrol384e9492020-09-03 17:05:19 +0200350 origin := ts_SDP_origin(local_addr, session_id, session_version, f_mgcp_addr2addrtype(local_addr)),
Harald Welte4029e8c2017-11-23 22:00:42 +0100351 session_name := "-",
352 information := omit,
353 uri := omit,
354 emails := omit,
355 phone_numbers := omit,
Pau Espin Pedrol384e9492020-09-03 17:05:19 +0200356 connection := ts_SDP_connection_IP(remote_addr, f_mgcp_addr2addrtype(remote_addr)),
Harald Welte4029e8c2017-11-23 22:00:42 +0100357 bandwidth := omit,
358 times := { ts_SDP_time("0","0") },
359 timezone_adjustments := omit,
360 key := omit,
361 attributes := omit,
362 media_list := { ts_SDP_media_desc(rtp_port, fmts, attributes) }
363 }
364
Daniel Willmannfdb48682022-02-08 16:22:59 +0100365 template SDP_Message tr_SDP(template charstring remote_addr := ?, template integer rtp_port := ?) := {
366 protocol_version := 0,
367 origin := ?,
368 session_name := ?,
369 information := *,
370 uri := *,
371 emails := *,
372 phone_numbers := *,
373 connection := tr_SDP_connection_IP(remote_addr, ?),
374 bandwidth := *,
375 times := ?,
376 timezone_adjustments := *,
377 key := *,
378 attributes := *,
379 media_list := { tr_SDP_media_desc(rtp_port) }
380 }
381
Harald Welte4029e8c2017-11-23 22:00:42 +0100382 template SDP_attribute ts_SDP_rtpmap(integer fmt, charstring val) := {
383 rtpmap := {
384 attr_value := int2str(fmt) & " " & val
385 }
386 }
387 template SDP_attribute ts_SDP_ptime(integer p) := {
388 ptime := {
389 attr_value := int2str(p)
390 }
391 }
Philipp Maierc8c0b402019-03-07 10:48:45 +0100392 template SDP_attribute ts_SDP_fmtp(integer fmt, charstring val) := {
393 fmtp := {
394 attr_value := int2str(fmt) & " " & val
395 }
396 }
Harald Welte4029e8c2017-11-23 22:00:42 +0100397
Pau Espin Pedrol384e9492020-09-03 17:05:19 +0200398 function f_mgcp_addr2addrtype(charstring addr) return charstring {
399 for (var integer i := 0; i < lengthof(addr); i := i + 1) {
400 if (addr[i] == ":") {
401 return "IP6";
402 }
403 }
404 return "IP4";
405 }
406
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200407 /* -1 is wildcard, positive is translated as string */
408 function f_mgcp_osmux_cid_encode(MgcpOsmuxCID osmux_cid) return charstring {
409 if (osmux_cid == -1) {
410 return "*";
411 }
412 return int2str(osmux_cid);
413 }
414
415 function f_mgcp_osmux_cid_decode(charstring osmux_cid) return MgcpOsmuxCID {
416 if (osmux_cid == "*") {
417 return -1;
418 }
419 return str2int(osmux_cid);
420 }
421
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100422 function f_mgcp_contains_par(MgcpMessage msg, MgcpInfoCode code) return boolean {
423 var MgcpParameterList pars;
424 if (ischosen(msg.command)) {
425 pars := msg.command.params;
426 } else {
427 pars := msg.response.params;
428 }
429 for (var integer i := 0; i < lengthof(pars); i := i + 1) {
430 var MgcpParameter par := pars[i];
431 if (par.code == code) {
432 return true;
433 }
434 }
435 return false;
436 }
437
Harald Welteb71901a2018-01-26 19:16:05 +0100438 function f_mgcp_extract_par(MgcpMessage msg, MgcpInfoCode code) return charstring {
439 var MgcpParameterList pars;
440 if (ischosen(msg.command)) {
441 pars := msg.command.params;
442 } else {
443 pars := msg.response.params;
444 }
445 for (var integer i := 0; i < lengthof(pars); i := i + 1) {
446 var MgcpParameter par := pars[i];
447 if (par.code == code) {
448 return par.val;
Harald Welte4c11d562017-11-24 23:39:00 +0100449 }
450 }
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200451 setverdict(fail, "Could not extract parameters for code ", code);
Harald Welteb71901a2018-01-26 19:16:05 +0100452 return "";
453 }
454
Harald Welte1fe74812018-01-29 21:57:26 +0100455 function f_MgcpResp_extract_par(MgcpResponse resp, MgcpInfoCode code) return charstring {
Harald Welteb71901a2018-01-26 19:16:05 +0100456 var MgcpMessage msg := {
457 response := resp
458 }
Harald Welte1fe74812018-01-29 21:57:26 +0100459 return f_mgcp_extract_par(msg, code);
Harald Welteb71901a2018-01-26 19:16:05 +0100460 }
461
Harald Welte1fe74812018-01-29 21:57:26 +0100462 function f_MgcpCmd_extract_par(MgcpCommand cmd, MgcpInfoCode code) return charstring {
Harald Welteb71901a2018-01-26 19:16:05 +0100463 var MgcpMessage msg := {
464 command := cmd
465 }
Harald Welte1fe74812018-01-29 21:57:26 +0100466 return f_mgcp_extract_par(msg, code);
Harald Welte4c11d562017-11-24 23:39:00 +0100467 }
468
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100469 function f_MgcpCmd_contains_par(MgcpCommand cmd, MgcpInfoCode code) return boolean {
470 var MgcpMessage msg := {
471 command := cmd
472 }
473 return f_mgcp_contains_par(msg, code);
474 }
475
Harald Welte1fe74812018-01-29 21:57:26 +0100476 function f_MgcpResp_extract_conn_id(MgcpResponse resp) return MgcpConnectionId {
477 return str2hex(f_MgcpResp_extract_par(resp, "I"));
478 }
479
480 function f_MgcpCmd_extract_call_id(MgcpCommand cmd) return MgcpCallId {
481 return str2hex(f_MgcpCmd_extract_par(cmd, "C"));
482 }
483
484 function f_MgcpCmd_extract_conn_id(MgcpCommand cmd) return MgcpConnectionId {
485 return str2hex(f_MgcpCmd_extract_par(cmd, "I"));
486 }
487
Pau Espin Pedrolb2c6b382019-05-14 13:40:49 +0200488 function f_MgcpCmd_extract_osmux_cid(MgcpCommand cmd) return MgcpOsmuxCID {
489 return f_mgcp_osmux_cid_decode(f_MgcpCmd_extract_par(cmd, "X-OSMUX"));
490 }
491
Harald Welte1fe74812018-01-29 21:57:26 +0100492
Harald Welte4c11d562017-11-24 23:39:00 +0100493 function f_mgcp_alloc_tid() return MgcpTransId {
494 return int2str(float2int(rnd()*2147483647.0));
495 }
496
497 function f_mgcp_alloc_call_id() return MgcpCallId {
498 return int2hex(float2int(rnd()*2147483647.0), 8);
499 }
500
501 function f_mgcp_alloc_conn_id() return MgcpConnectionId {
502 return int2hex(float2int(rnd()*2147483647.0), 8);
503 }
504
Harald Weltebb5a1212018-01-26 10:34:44 +0100505 /* those verbs that related to a connection (and hence have ConnectionId) */
506 template MgcpVerb tr_MgcpVerb_ConnectionOriented := ("CRCX", "MDCX", "DLCX", "AUCX");
507 /* entire command template matching only connection oriented verbs */
508 template MgcpCommand tr_MgcpCommand_CO := {
509 line := {
510 verb := tr_MgcpVerb_ConnectionOriented,
511 trans_id := ?,
512 ep := ?,
513 ver := ?
514 },
515 params := *,
516 sdp := *
517 }
518
Neels Hofmeyrac7526d2019-10-15 16:54:37 +0200519 function f_mgcp_find_param_entry(MgcpParameterList pars, MgcpInfoCode code, out charstring ret)
520 return boolean {
521 for (var integer i := 0; i < sizeof(pars); i := i+1) {
522 if (pars[i].code == code) {
523 ret := pars[i].val;
524 return true;
525 }
526 }
527 return false;
528 }
529
Harald Welte363cb0a2018-01-30 19:35:53 +0100530 function f_mgcp_find_param(MgcpMessage msg, MgcpInfoCode code, out charstring ret)
531 return boolean {
532 var MgcpParameterList pars;
533 if (ischosen(msg.command)) {
534 pars := msg.command.params;
535 } else {
536 pars := msg.response.params;
537 }
Neels Hofmeyrac7526d2019-10-15 16:54:37 +0200538 return f_mgcp_find_param_entry(pars, code, ret);
Harald Welte363cb0a2018-01-30 19:35:53 +0100539 }
540
541 /* template to determine if a MGCP endpoint is a wildcard endpoint */
542 template charstring t_MGCP_EP_wildcard := (pattern "\*@*", pattern "rtpbridge/\*@*");
543
Harald Welteb71901a2018-01-26 19:16:05 +0100544
Harald Welte4029e8c2017-11-23 22:00:42 +0100545}