blob: b586ff67b5a4e7ac2317e6395fcadc80099ccbfe [file] [log] [blame]
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
5 * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
6 * (C) 2009-2011 by On-Waves
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020024#include <osmocom/core/talloc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020025#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020026#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020027#include <osmocom/mgcp/mgcp_internal.h>
28#include <osmocom/mgcp/vty.h>
29#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010030#include <osmocom/mgcp/mgcp_endp.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020031
32#include <string.h>
33
34#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
35#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
36#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
37
38static struct mgcp_config *g_cfg = NULL;
39
40static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
41{
42 struct mgcp_trunk_config *trunk;
43
44 if (nr == 0)
45 trunk = &cfg->trunk;
46 else
47 trunk = mgcp_trunk_num(cfg, nr);
48
49 return trunk;
50}
51
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020052struct cmd_node mgcp_node = {
53 MGCP_NODE,
54 "%s(config-mgcp)# ",
55 1,
56};
57
58struct cmd_node trunk_node = {
59 TRUNK_NODE,
60 "%s(config-mgcp-trunk)# ",
61 1,
62};
63
64static int config_write_mgcp(struct vty *vty)
65{
66 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maier12943ea2018-01-17 15:40:25 +010067 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020068 if (g_cfg->local_ip)
69 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020070 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
71 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Philipp Maierf1889d82017-11-08 14:59:39 +010072 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020073 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
74 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020075 if (g_cfg->net_ports.bind_addr)
Philipp Maierf1889d82017-11-08 14:59:39 +010076 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020077 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010078 if (g_cfg->net_ports.bind_addr_probe)
79 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
80 else
81 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020082 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
83 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
84 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
85 else if (g_cfg->trunk.keepalive_interval)
86 vty_out(vty, " rtp keep-alive %d%s",
87 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
88 else
89 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
90
91 if (g_cfg->trunk.omit_rtcp)
92 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
93 else
94 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020095 if (g_cfg->trunk.force_constant_ssrc
96 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020097 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020098 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
99 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200100 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200101 g_cfg->trunk.force_aligned_timing ? "" : "no ",
102 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200103 } else
104 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
105 if (g_cfg->trunk.audio_payload != -1)
106 vty_out(vty, " sdp audio-payload number %d%s",
107 g_cfg->trunk.audio_payload, VTY_NEWLINE);
108 if (g_cfg->trunk.audio_name)
109 vty_out(vty, " sdp audio-payload name %s%s",
110 g_cfg->trunk.audio_name, VTY_NEWLINE);
111 if (g_cfg->trunk.audio_fmtp_extra)
112 vty_out(vty, " sdp audio fmtp-extra %s%s",
113 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
114 vty_out(vty, " %ssdp audio-payload send-ptime%s",
115 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
116 vty_out(vty, " %ssdp audio-payload send-name%s",
117 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200118 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
119 vty_out(vty, " number endpoints %u%s",
Philipp Maierfcd06552017-11-10 17:32:22 +0100120 g_cfg->trunk.vty_number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200121 vty_out(vty, " %sallow-transcoding%s",
122 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
123 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200124 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
125 VTY_NEWLINE);
126 if (g_cfg->force_ptime > 0)
127 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
128 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200129
130 switch (g_cfg->osmux) {
131 case OSMUX_USAGE_ON:
132 vty_out(vty, " osmux on%s", VTY_NEWLINE);
133 break;
134 case OSMUX_USAGE_ONLY:
135 vty_out(vty, " osmux only%s", VTY_NEWLINE);
136 break;
137 case OSMUX_USAGE_OFF:
138 default:
139 vty_out(vty, " osmux off%s", VTY_NEWLINE);
140 break;
141 }
142 if (g_cfg->osmux) {
143 vty_out(vty, " osmux bind-ip %s%s",
144 g_cfg->osmux_addr, VTY_NEWLINE);
145 vty_out(vty, " osmux batch-factor %d%s",
146 g_cfg->osmux_batch, VTY_NEWLINE);
147 vty_out(vty, " osmux batch-size %u%s",
148 g_cfg->osmux_batch_size, VTY_NEWLINE);
149 vty_out(vty, " osmux port %u%s",
150 g_cfg->osmux_port, VTY_NEWLINE);
151 vty_out(vty, " osmux dummy %s%s",
152 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
153 }
154 return CMD_SUCCESS;
155}
156
Philipp Maiercede2a42018-07-03 14:14:21 +0200157static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200158{
Philipp Maiercede2a42018-07-03 14:14:21 +0200159 struct mgcp_rtp_state *state = &conn->state;
160 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200161 struct mgcp_rtp_codec *codec = end->codec;
Philipp Maiercede2a42018-07-03 14:14:21 +0200162 struct rate_ctr *dropped_packets;
163
164 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200165
166 vty_out(vty,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200167 " Timestamp Errs: %lu->%lu%s"
Philipp Maiercede2a42018-07-03 14:14:21 +0200168 " Dropped Packets: %lu%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200169 " Payload Type: %d Rate: %u Channels: %d %s"
170 " Frame Duration: %u Frame Denominator: %u%s"
171 " FPP: %d Packet Duration: %u%s"
172 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
173 " Output-Enabled: %d Force-PTIME: %d%s",
Philipp Maier9e1d1642018-05-09 16:26:34 +0200174 state->in_stream.err_ts_ctr->current,
175 state->out_stream.err_ts_ctr->current,
176 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200177 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200178 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200179 codec->frame_duration_num, codec->frame_duration_den,
180 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
181 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
182 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
183 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200184}
185
Philipp Maier87bd9be2017-08-22 16:35:41 +0200186static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
187 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200188{
189 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200190 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200191
192 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
193 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
194 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
195
196 if (!cfg->endpoints) {
197 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
198 return;
199 }
200
201 for (i = 1; i < cfg->number_endpoints; ++i) {
202 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200203
Philipp Maier87bd9be2017-08-22 16:35:41 +0200204 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
205
206 llist_for_each_entry(conn, &endp->conns, entry) {
207 vty_out(vty, " CONN: %s%s",
208 mgcp_conn_dump(conn), VTY_NEWLINE);
209
210 if (verbose) {
211 /* FIXME: Also add verbosity for other
212 * connection types (E1) as soon as
213 * the implementation is available */
214 if (conn->type == MGCP_CONN_TYPE_RTP) {
Philipp Maiercede2a42018-07-03 14:14:21 +0200215 dump_rtp_end(vty, &conn->u.rtp);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200216 }
217 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200218 }
219 }
220}
221
222DEFUN(show_mcgp, show_mgcp_cmd,
223 "show mgcp [stats]",
224 SHOW_STR
225 "Display information about the MGCP Media Gateway\n"
226 "Include Statistics\n")
227{
228 struct mgcp_trunk_config *trunk;
229 int show_stats = argc >= 1;
230
231 dump_trunk(vty, &g_cfg->trunk, show_stats);
232
233 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200234 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200235
236 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200237 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
238 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200239
240 return CMD_SUCCESS;
241}
242
Philipp Maier87bd9be2017-08-22 16:35:41 +0200243DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200244{
245 vty->node = MGCP_NODE;
246 return CMD_SUCCESS;
247}
248
249DEFUN(cfg_mgcp_local_ip,
250 cfg_mgcp_local_ip_cmd,
251 "local ip A.B.C.D",
252 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200253 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200254{
255 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
256 return CMD_SUCCESS;
257}
258
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200259#define BIND_STR "Listen/Bind related socket option\n"
260DEFUN(cfg_mgcp_bind_ip,
261 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200262 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200263{
264 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
265 return CMD_SUCCESS;
266}
267
268DEFUN(cfg_mgcp_bind_port,
269 cfg_mgcp_bind_port_cmd,
270 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200271 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200272{
273 unsigned int port = atoi(argv[0]);
274 g_cfg->source_port = port;
275 return CMD_SUCCESS;
276}
277
278DEFUN(cfg_mgcp_bind_early,
279 cfg_mgcp_bind_early_cmd,
280 "bind early (0|1)",
281 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200282 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200283{
284 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
285 return CMD_WARNING;
286}
287
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200288#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200289#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200290#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200291#define RANGE_START_STR "Start of the range of ports\n"
292#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200293
Philipp Maierf1889d82017-11-08 14:59:39 +0100294DEFUN(cfg_mgcp_rtp_port_range,
295 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200296 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200297 RTP_STR "Range of ports to use for the NET side\n"
298 RANGE_START_STR RANGE_END_STR)
299{
Philipp Maiera19547b2018-05-22 13:44:34 +0200300 int start;
301 int end;
302
303 start = atoi(argv[0]);
304 end = atoi(argv[1]);
305
306 if (end < start) {
307 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
308 end, start, VTY_NEWLINE);
309 return CMD_WARNING;
310 }
311
312 if (start & 1) {
313 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
314 start, start & 0xFFFE, VTY_NEWLINE);
315 start &= 0xFFFE;
316 }
317
318 if ((end & 1) == 0) {
319 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
320 end, end | 1, VTY_NEWLINE);
321 end |= 1;
322 }
323
324 g_cfg->net_ports.range_start = start;
325 g_cfg->net_ports.range_end = end;
326 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
327
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200328 return CMD_SUCCESS;
329}
Philipp Maierf1889d82017-11-08 14:59:39 +0100330ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
331 cfg_mgcp_rtp_net_range_cmd,
332 "rtp net-range <0-65534> <0-65534>",
333 RTP_STR "Range of ports to use for the NET side\n"
334 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200335
Philipp Maierf1889d82017-11-08 14:59:39 +0100336DEFUN(cfg_mgcp_rtp_bind_ip,
337 cfg_mgcp_rtp_bind_ip_cmd,
338 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200339 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
340{
341 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
342 return CMD_SUCCESS;
343}
Philipp Maierf1889d82017-11-08 14:59:39 +0100344ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
345 cfg_mgcp_rtp_net_bind_ip_cmd,
346 "rtp net-bind-ip A.B.C.D",
347 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200348
Philipp Maierf1889d82017-11-08 14:59:39 +0100349DEFUN(cfg_mgcp_rtp_no_bind_ip,
350 cfg_mgcp_rtp_no_bind_ip_cmd,
351 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200352 NO_STR RTP_STR "Bind endpoints facing the Network\n"
353 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200354{
355 talloc_free(g_cfg->net_ports.bind_addr);
356 g_cfg->net_ports.bind_addr = NULL;
357 return CMD_SUCCESS;
358}
Philipp Maierf1889d82017-11-08 14:59:39 +0100359ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
360 cfg_mgcp_rtp_no_net_bind_ip_cmd,
361 "no rtp net-bind-ip",
362 NO_STR RTP_STR "Bind endpoints facing the Network\n"
363 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200364
Philipp Maier1cb1e382017-11-02 17:16:04 +0100365DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
366 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
367 "rtp ip-probing",
368 RTP_STR "automatic rtp bind ip selection\n")
369{
370 g_cfg->net_ports.bind_addr_probe = true;
371 return CMD_SUCCESS;
372}
373
374DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
375 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
376 "no rtp ip-probing",
377 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
378{
379 g_cfg->net_ports.bind_addr_probe = false;
380 return CMD_SUCCESS;
381}
382
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200383DEFUN(cfg_mgcp_rtp_ip_dscp,
384 cfg_mgcp_rtp_ip_dscp_cmd,
385 "rtp ip-dscp <0-255>",
386 RTP_STR
387 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
388{
389 int dscp = atoi(argv[0]);
390 g_cfg->endp_dscp = dscp;
391 return CMD_SUCCESS;
392}
393
394ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200395 "rtp ip-tos <0-255>",
396 RTP_STR
397 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
398#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
399 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200400 cfg_mgcp_rtp_force_ptime_cmd,
401 "rtp force-ptime (10|20|40)",
402 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200403 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200404{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200405 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200406 return CMD_SUCCESS;
407}
408
409DEFUN(cfg_mgcp_no_rtp_force_ptime,
410 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200411 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200412{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200413 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200414 return CMD_SUCCESS;
415}
416
417DEFUN(cfg_mgcp_sdp_fmtp_extra,
418 cfg_mgcp_sdp_fmtp_extra_cmd,
419 "sdp audio fmtp-extra .NAME",
420 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
421 "Extra Information\n")
422{
423 char *txt = argv_concat(argv, argc, 0);
424 if (!txt)
425 return CMD_WARNING;
426
427 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
428 talloc_free(txt);
429 return CMD_SUCCESS;
430}
431
432DEFUN(cfg_mgcp_allow_transcoding,
433 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200434 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200435{
436 g_cfg->trunk.no_audio_transcoding = 0;
437 return CMD_SUCCESS;
438}
439
440DEFUN(cfg_mgcp_no_allow_transcoding,
441 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200442 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200443{
444 g_cfg->trunk.no_audio_transcoding = 1;
445 return CMD_SUCCESS;
446}
447
448#define SDP_STR "SDP File related options\n"
449#define AUDIO_STR "Audio payload options\n"
450DEFUN(cfg_mgcp_sdp_payload_number,
451 cfg_mgcp_sdp_payload_number_cmd,
452 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200453 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200454{
455 unsigned int payload = atoi(argv[0]);
456 g_cfg->trunk.audio_payload = payload;
457 return CMD_SUCCESS;
458}
459
Philipp Maier87bd9be2017-08-22 16:35:41 +0200460ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
461 cfg_mgcp_sdp_payload_number_cmd_old,
462 "sdp audio payload number <0-255>",
463 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200464
Philipp Maier87bd9be2017-08-22 16:35:41 +0200465 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200466 cfg_mgcp_sdp_payload_name_cmd,
467 "sdp audio-payload name NAME",
468 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
469{
470 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
471 return CMD_SUCCESS;
472}
473
474ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200475 "sdp audio payload name NAME",
476 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200477
Philipp Maier87bd9be2017-08-22 16:35:41 +0200478 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200479 cfg_mgcp_sdp_payload_send_ptime_cmd,
480 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200481 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200482{
483 g_cfg->trunk.audio_send_ptime = 1;
484 return CMD_SUCCESS;
485}
486
487DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
488 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
489 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200490 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200491{
492 g_cfg->trunk.audio_send_ptime = 0;
493 return CMD_SUCCESS;
494}
495
496DEFUN(cfg_mgcp_sdp_payload_send_name,
497 cfg_mgcp_sdp_payload_send_name_cmd,
498 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200499 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200500{
501 g_cfg->trunk.audio_send_name = 1;
502 return CMD_SUCCESS;
503}
504
505DEFUN(cfg_mgcp_no_sdp_payload_send_name,
506 cfg_mgcp_no_sdp_payload_send_name_cmd,
507 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200508 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200509{
510 g_cfg->trunk.audio_send_name = 0;
511 return CMD_SUCCESS;
512}
513
514DEFUN(cfg_mgcp_loop,
515 cfg_mgcp_loop_cmd,
516 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200517 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200518{
519 if (g_cfg->osmux) {
520 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
521 return CMD_WARNING;
522 }
523 g_cfg->trunk.audio_loop = atoi(argv[0]);
524 return CMD_SUCCESS;
525}
526
527DEFUN(cfg_mgcp_force_realloc,
528 cfg_mgcp_force_realloc_cmd,
529 "force-realloc (0|1)",
530 "Force endpoint reallocation when the endpoint is still seized\n"
531 "Don't force reallocation\n" "force reallocation\n")
532{
533 g_cfg->trunk.force_realloc = atoi(argv[0]);
534 return CMD_SUCCESS;
535}
536
Philipp Maier87bd9be2017-08-22 16:35:41 +0200537DEFUN(cfg_mgcp_rtp_accept_all,
538 cfg_mgcp_rtp_accept_all_cmd,
539 "rtp-accept-all (0|1)",
540 "Accept all RTP packets, even when the originating IP/Port does not match\n"
541 "enable filter\n" "disable filter\n")
542{
543 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
544 return CMD_SUCCESS;
545}
546
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200547DEFUN(cfg_mgcp_number_endp,
548 cfg_mgcp_number_endp_cmd,
549 "number endpoints <0-65534>",
550 "Number options\n" "Endpoints available\n" "Number endpoints\n")
551{
552 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100553 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200554 return CMD_SUCCESS;
555}
556
Philipp Maier87bd9be2017-08-22 16:35:41 +0200557DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200558{
559 g_cfg->trunk.omit_rtcp = 1;
560 return CMD_SUCCESS;
561}
562
563DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200564 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200565{
566 g_cfg->trunk.omit_rtcp = 0;
567 return CMD_SUCCESS;
568}
569
570DEFUN(cfg_mgcp_patch_rtp_ssrc,
571 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200572 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200573{
574 g_cfg->trunk.force_constant_ssrc = 1;
575 return CMD_SUCCESS;
576}
577
578DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
579 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200580 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200581{
582 g_cfg->trunk.force_constant_ssrc = 0;
583 return CMD_SUCCESS;
584}
585
586DEFUN(cfg_mgcp_patch_rtp_ts,
587 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200588 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200589{
590 g_cfg->trunk.force_aligned_timing = 1;
591 return CMD_SUCCESS;
592}
593
594DEFUN(cfg_mgcp_no_patch_rtp_ts,
595 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200596 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200597{
598 g_cfg->trunk.force_aligned_timing = 0;
599 return CMD_SUCCESS;
600}
601
602DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200603 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200604{
605 g_cfg->trunk.force_constant_ssrc = 0;
606 g_cfg->trunk.force_aligned_timing = 0;
607 return CMD_SUCCESS;
608}
609
610DEFUN(cfg_mgcp_rtp_keepalive,
611 cfg_mgcp_rtp_keepalive_cmd,
612 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200613 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200614{
615 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
616 return CMD_SUCCESS;
617}
618
619DEFUN(cfg_mgcp_rtp_keepalive_once,
620 cfg_mgcp_rtp_keepalive_once_cmd,
621 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200622 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200623{
624 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
625 return CMD_SUCCESS;
626}
627
628DEFUN(cfg_mgcp_no_rtp_keepalive,
629 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200630 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200631{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100632 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200633 return CMD_SUCCESS;
634}
635
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200636#define CALL_AGENT_STR "Callagent information\n"
637DEFUN(cfg_mgcp_agent_addr,
638 cfg_mgcp_agent_addr_cmd,
639 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200640 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200641{
642 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
643 return CMD_SUCCESS;
644}
645
646ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200647 "call agent ip A.B.C.D",
648 CALL_AGENT_STR CALL_AGENT_STR IP_STR
649 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200650
Philipp Maier87bd9be2017-08-22 16:35:41 +0200651 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
652 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200653{
654 struct mgcp_trunk_config *trunk;
655 int index = atoi(argv[0]);
656
657 trunk = mgcp_trunk_num(g_cfg, index);
658 if (!trunk)
659 trunk = mgcp_trunk_alloc(g_cfg, index);
660
661 if (!trunk) {
662 vty_out(vty, "%%Unable to allocate trunk %u.%s",
663 index, VTY_NEWLINE);
664 return CMD_WARNING;
665 }
666
667 vty->node = TRUNK_NODE;
668 vty->index = trunk;
669 return CMD_SUCCESS;
670}
671
672static int config_write_trunk(struct vty *vty)
673{
674 struct mgcp_trunk_config *trunk;
675
676 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
677 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
678 vty_out(vty, " sdp audio-payload number %d%s",
679 trunk->audio_payload, VTY_NEWLINE);
680 vty_out(vty, " sdp audio-payload name %s%s",
681 trunk->audio_name, VTY_NEWLINE);
682 vty_out(vty, " %ssdp audio-payload send-ptime%s",
683 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
684 vty_out(vty, " %ssdp audio-payload send-name%s",
685 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
686
687 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
688 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
689 else if (trunk->keepalive_interval)
690 vty_out(vty, " rtp keep-alive %d%s",
691 trunk->keepalive_interval, VTY_NEWLINE);
692 else
693 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200694 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200695 vty_out(vty, " force-realloc %d%s",
696 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200697 vty_out(vty, " rtp-accept-all %d%s",
698 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200699 if (trunk->omit_rtcp)
700 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
701 else
702 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
703 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
704 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200705 trunk->force_constant_ssrc ? "" : "no ",
706 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200707 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200708 trunk->force_aligned_timing ? "" : "no ",
709 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200710 } else
711 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
712 if (trunk->audio_fmtp_extra)
713 vty_out(vty, " sdp audio fmtp-extra %s%s",
714 trunk->audio_fmtp_extra, VTY_NEWLINE);
715 vty_out(vty, " %sallow-transcoding%s",
716 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
717 }
718
719 return CMD_SUCCESS;
720}
721
722DEFUN(cfg_trunk_sdp_fmtp_extra,
723 cfg_trunk_sdp_fmtp_extra_cmd,
724 "sdp audio fmtp-extra .NAME",
725 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
726 "Extra Information\n")
727{
728 struct mgcp_trunk_config *trunk = vty->index;
729 char *txt = argv_concat(argv, argc, 0);
730 if (!txt)
731 return CMD_WARNING;
732
733 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
734 talloc_free(txt);
735 return CMD_SUCCESS;
736}
737
738DEFUN(cfg_trunk_payload_number,
739 cfg_trunk_payload_number_cmd,
740 "sdp audio-payload number <0-255>",
741 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
742{
743 struct mgcp_trunk_config *trunk = vty->index;
744 unsigned int payload = atoi(argv[0]);
745
746 trunk->audio_payload = payload;
747 return CMD_SUCCESS;
748}
749
750ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200751 "sdp audio payload number <0-255>",
752 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200753
Philipp Maier87bd9be2017-08-22 16:35:41 +0200754 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200755 cfg_trunk_payload_name_cmd,
756 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200757 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200758{
759 struct mgcp_trunk_config *trunk = vty->index;
760
761 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
762 return CMD_SUCCESS;
763}
764
765ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200766 "sdp audio payload name NAME",
767 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200768
Philipp Maier87bd9be2017-08-22 16:35:41 +0200769 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200770 cfg_trunk_loop_cmd,
771 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200772 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200773{
774 struct mgcp_trunk_config *trunk = vty->index;
775
776 if (g_cfg->osmux) {
777 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
778 return CMD_WARNING;
779 }
780 trunk->audio_loop = atoi(argv[0]);
781 return CMD_SUCCESS;
782}
783
784DEFUN(cfg_trunk_sdp_payload_send_ptime,
785 cfg_trunk_sdp_payload_send_ptime_cmd,
786 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200787 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200788{
789 struct mgcp_trunk_config *trunk = vty->index;
790 trunk->audio_send_ptime = 1;
791 return CMD_SUCCESS;
792}
793
794DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
795 cfg_trunk_no_sdp_payload_send_ptime_cmd,
796 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200797 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200798{
799 struct mgcp_trunk_config *trunk = vty->index;
800 trunk->audio_send_ptime = 0;
801 return CMD_SUCCESS;
802}
803
804DEFUN(cfg_trunk_sdp_payload_send_name,
805 cfg_trunk_sdp_payload_send_name_cmd,
806 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200807 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200808{
809 struct mgcp_trunk_config *trunk = vty->index;
810 trunk->audio_send_name = 1;
811 return CMD_SUCCESS;
812}
813
814DEFUN(cfg_trunk_no_sdp_payload_send_name,
815 cfg_trunk_no_sdp_payload_send_name_cmd,
816 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200817 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200818{
819 struct mgcp_trunk_config *trunk = vty->index;
820 trunk->audio_send_name = 0;
821 return CMD_SUCCESS;
822}
823
Philipp Maier87bd9be2017-08-22 16:35:41 +0200824DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200825{
826 struct mgcp_trunk_config *trunk = vty->index;
827 trunk->omit_rtcp = 1;
828 return CMD_SUCCESS;
829}
830
831DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200832 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200833{
834 struct mgcp_trunk_config *trunk = vty->index;
835 trunk->omit_rtcp = 0;
836 return CMD_SUCCESS;
837}
838
839DEFUN(cfg_trunk_patch_rtp_ssrc,
840 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200841 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200842{
843 struct mgcp_trunk_config *trunk = vty->index;
844 trunk->force_constant_ssrc = 1;
845 return CMD_SUCCESS;
846}
847
848DEFUN(cfg_trunk_no_patch_rtp_ssrc,
849 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200850 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200851{
852 struct mgcp_trunk_config *trunk = vty->index;
853 trunk->force_constant_ssrc = 0;
854 return CMD_SUCCESS;
855}
856
857DEFUN(cfg_trunk_patch_rtp_ts,
858 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200859 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200860{
861 struct mgcp_trunk_config *trunk = vty->index;
862 trunk->force_aligned_timing = 1;
863 return CMD_SUCCESS;
864}
865
866DEFUN(cfg_trunk_no_patch_rtp_ts,
867 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200868 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200869{
870 struct mgcp_trunk_config *trunk = vty->index;
871 trunk->force_aligned_timing = 0;
872 return CMD_SUCCESS;
873}
874
875DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200876 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200877{
878 struct mgcp_trunk_config *trunk = vty->index;
879 trunk->force_constant_ssrc = 0;
880 trunk->force_aligned_timing = 0;
881 return CMD_SUCCESS;
882}
883
884DEFUN(cfg_trunk_rtp_keepalive,
885 cfg_trunk_rtp_keepalive_cmd,
886 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200887 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200888{
889 struct mgcp_trunk_config *trunk = vty->index;
890 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
891 return CMD_SUCCESS;
892}
893
894DEFUN(cfg_trunk_rtp_keepalive_once,
895 cfg_trunk_rtp_keepalive_once_cmd,
896 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200897 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200898{
899 struct mgcp_trunk_config *trunk = vty->index;
900 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
901 return CMD_SUCCESS;
902}
903
904DEFUN(cfg_trunk_no_rtp_keepalive,
905 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200906 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200907{
908 struct mgcp_trunk_config *trunk = vty->index;
909 mgcp_trunk_set_keepalive(trunk, 0);
910 return CMD_SUCCESS;
911}
912
913DEFUN(cfg_trunk_allow_transcoding,
914 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200915 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200916{
917 struct mgcp_trunk_config *trunk = vty->index;
918 trunk->no_audio_transcoding = 0;
919 return CMD_SUCCESS;
920}
921
922DEFUN(cfg_trunk_no_allow_transcoding,
923 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200924 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200925{
926 struct mgcp_trunk_config *trunk = vty->index;
927 trunk->no_audio_transcoding = 1;
928 return CMD_SUCCESS;
929}
930
Philipp Maier87bd9be2017-08-22 16:35:41 +0200931DEFUN(loop_conn,
932 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200933 "loop-endpoint <0-64> NAME (0|1)",
934 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200935 "The name in hex of the endpoint\n" "Disable the loop\n"
936 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200937{
938 struct mgcp_trunk_config *trunk;
939 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200940 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200941
942 trunk = find_trunk(g_cfg, atoi(argv[0]));
943 if (!trunk) {
944 vty_out(vty, "%%Trunk %d not found in the config.%s",
945 atoi(argv[0]), VTY_NEWLINE);
946 return CMD_WARNING;
947 }
948
949 if (!trunk->endpoints) {
950 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
951 trunk->trunk_nr, VTY_NEWLINE);
952 return CMD_WARNING;
953 }
954
955 int endp_no = strtoul(argv[1], NULL, 16);
956 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
957 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200958 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200959 return CMD_WARNING;
960 }
961
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200962 endp = &trunk->endpoints[endp_no];
963 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200964 llist_for_each_entry(conn, &endp->conns, entry) {
965 if (conn->type == MGCP_CONN_TYPE_RTP)
966 /* Handle it like a MDCX, switch on SSRC patching if enabled */
967 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
968 else {
969 /* FIXME: Introduce support for other connection (E1)
970 * types when implementation is available */
971 vty_out(vty, "%%Can't enable SSRC patching,"
972 "connection %s is not an RTP connection.%s",
973 mgcp_conn_dump(conn), VTY_NEWLINE);
974 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200975
Philipp Maier87bd9be2017-08-22 16:35:41 +0200976 if (loop)
977 conn->mode = MGCP_CONN_LOOPBACK;
978 else
979 conn->mode = conn->mode_orig;
980 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200981
982 return CMD_SUCCESS;
983}
984
Philipp Maier87bd9be2017-08-22 16:35:41 +0200985DEFUN(tap_rtp,
986 tap_rtp_cmd,
987 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200988 "Forward data on endpoint to a different system\n" "Trunk number\n"
989 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200990 "The connection id in hex\n"
991 "Forward incoming data\n"
992 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200993 "destination IP of the data\n" "destination port\n")
994{
995 struct mgcp_rtp_tap *tap;
996 struct mgcp_trunk_config *trunk;
997 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200998 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +0100999 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000
1001 trunk = find_trunk(g_cfg, atoi(argv[0]));
1002 if (!trunk) {
1003 vty_out(vty, "%%Trunk %d not found in the config.%s",
1004 atoi(argv[0]), VTY_NEWLINE);
1005 return CMD_WARNING;
1006 }
1007
1008 if (!trunk->endpoints) {
1009 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1010 trunk->trunk_nr, VTY_NEWLINE);
1011 return CMD_WARNING;
1012 }
1013
1014 int endp_no = strtoul(argv[1], NULL, 16);
1015 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1016 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001017 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001018 return CMD_WARNING;
1019 }
1020
1021 endp = &trunk->endpoints[endp_no];
1022
Philipp Maier01d24a32017-11-21 17:26:09 +01001023 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001024 conn = mgcp_conn_get_rtp(endp, conn_id);
1025 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001026 vty_out(vty, "Conn ID %s is invalid.%s",
1027 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001028 return CMD_WARNING;
1029 }
1030
1031 if (strcmp(argv[3], "in") == 0)
1032 tap = &conn->tap_in;
1033 else if (strcmp(argv[3], "out") == 0)
1034 tap = &conn->tap_out;
1035 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001036 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1037 return CMD_WARNING;
1038 }
1039
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001040 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001041 inet_aton(argv[4], &tap->forward.sin_addr);
1042 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001043 tap->enabled = 1;
1044 return CMD_SUCCESS;
1045}
1046
1047DEFUN(free_endp, free_endp_cmd,
1048 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001049 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001050{
1051 struct mgcp_trunk_config *trunk;
1052 struct mgcp_endpoint *endp;
1053
1054 trunk = find_trunk(g_cfg, atoi(argv[0]));
1055 if (!trunk) {
1056 vty_out(vty, "%%Trunk %d not found in the config.%s",
1057 atoi(argv[0]), VTY_NEWLINE);
1058 return CMD_WARNING;
1059 }
1060
1061 if (!trunk->endpoints) {
1062 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1063 trunk->trunk_nr, VTY_NEWLINE);
1064 return CMD_WARNING;
1065 }
1066
1067 int endp_no = strtoul(argv[1], NULL, 16);
1068 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1069 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001070 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001071 return CMD_WARNING;
1072 }
1073
1074 endp = &trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001075 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001076 return CMD_SUCCESS;
1077}
1078
1079DEFUN(reset_endp, reset_endp_cmd,
1080 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001081 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001082{
1083 struct mgcp_trunk_config *trunk;
1084 struct mgcp_endpoint *endp;
1085 int endp_no, rc;
1086
1087 trunk = find_trunk(g_cfg, atoi(argv[0]));
1088 if (!trunk) {
1089 vty_out(vty, "%%Trunk %d not found in the config.%s",
1090 atoi(argv[0]), VTY_NEWLINE);
1091 return CMD_WARNING;
1092 }
1093
1094 if (!trunk->endpoints) {
1095 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1096 trunk->trunk_nr, VTY_NEWLINE);
1097 return CMD_WARNING;
1098 }
1099
1100 endp_no = strtoul(argv[1], NULL, 16);
1101 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1102 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001103 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001104 return CMD_WARNING;
1105 }
1106
1107 endp = &trunk->endpoints[endp_no];
1108 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1109 if (rc < 0) {
1110 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1111 return CMD_WARNING;
1112 }
1113 return CMD_SUCCESS;
1114}
1115
1116DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001117 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001118{
1119 int rc;
1120
1121 rc = mgcp_send_reset_all(g_cfg);
1122 if (rc < 0) {
1123 vty_out(vty, "Error %d during endpoint reset.%s",
1124 rc, VTY_NEWLINE);
1125 return CMD_WARNING;
1126 }
1127 return CMD_SUCCESS;
1128}
1129
1130#define OSMUX_STR "RTP multiplexing\n"
1131DEFUN(cfg_mgcp_osmux,
1132 cfg_mgcp_osmux_cmd,
1133 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001134 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001135{
1136 if (strcmp(argv[0], "off") == 0) {
1137 g_cfg->osmux = OSMUX_USAGE_OFF;
1138 return CMD_SUCCESS;
1139 }
1140
Philipp Maier87bd9be2017-08-22 16:35:41 +02001141 /* Since OSMUX support is not finished, we do not
1142 * allow to turn it on yet. */
1143 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1144 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001145#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001146 if (strcmp(argv[0], "on") == 0)
1147 g_cfg->osmux = OSMUX_USAGE_ON;
1148 else if (strcmp(argv[0], "only") == 0)
1149 g_cfg->osmux = OSMUX_USAGE_ONLY;
1150
1151 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001152 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001153 return CMD_WARNING;
1154 }
1155
1156 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001157#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001158}
1159
1160DEFUN(cfg_mgcp_osmux_ip,
1161 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001162 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001163{
1164 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1165 return CMD_SUCCESS;
1166}
1167
1168DEFUN(cfg_mgcp_osmux_batch_factor,
1169 cfg_mgcp_osmux_batch_factor_cmd,
1170 "osmux batch-factor <1-8>",
1171 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1172{
1173 g_cfg->osmux_batch = atoi(argv[0]);
1174 return CMD_SUCCESS;
1175}
1176
1177DEFUN(cfg_mgcp_osmux_batch_size,
1178 cfg_mgcp_osmux_batch_size_cmd,
1179 "osmux batch-size <1-65535>",
1180 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1181{
1182 g_cfg->osmux_batch_size = atoi(argv[0]);
1183 return CMD_SUCCESS;
1184}
1185
1186DEFUN(cfg_mgcp_osmux_port,
1187 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001188 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001189{
1190 g_cfg->osmux_port = atoi(argv[0]);
1191 return CMD_SUCCESS;
1192}
1193
1194DEFUN(cfg_mgcp_osmux_dummy,
1195 cfg_mgcp_osmux_dummy_cmd,
1196 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001197 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1198 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001199{
1200 if (strcmp(argv[0], "on") == 0)
1201 g_cfg->osmux_dummy = 1;
1202 else if (strcmp(argv[0], "off") == 0)
1203 g_cfg->osmux_dummy = 0;
1204
1205 return CMD_SUCCESS;
1206}
1207
Philipp Maier12943ea2018-01-17 15:40:25 +01001208DEFUN(cfg_mgcp_domain,
1209 cfg_mgcp_domain_cmd,
1210 "domain NAME", "domain\n" "qualified domain name\n")
1211{
1212 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1213 return CMD_SUCCESS;
1214}
1215
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001216int mgcp_vty_init(void)
1217{
1218 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001219 install_element(ENABLE_NODE, &loop_conn_cmd);
1220 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001221 install_element(ENABLE_NODE, &free_endp_cmd);
1222 install_element(ENABLE_NODE, &reset_endp_cmd);
1223 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1224
1225 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1226 install_node(&mgcp_node, config_write_mgcp);
1227
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001228 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001229 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1230 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1231 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001232 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001233 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001234 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001235 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001236 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001237 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001238 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1239 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001240 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1241 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1242 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1243 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1244 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1245 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1246 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1247 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1248 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001249 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1250 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1251 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1252 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1253 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1254 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001255 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001256 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1257 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1258 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1259 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1260 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1261 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1262 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1263 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1264 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1265 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1266 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1267 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1268 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1269 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1270 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1271 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1272 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1273 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1274 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1275 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1276 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001277 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001278
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001279 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1280 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001281 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1282 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1283 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1284 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1285 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1286 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1287 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1288 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1289 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1290 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1291 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1292 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1293 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1294 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1295 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1296 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1297 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1298 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1299 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1300 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1301 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1302 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1303
1304 return 0;
1305}
1306
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001307int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1308 enum mgcp_role role)
1309{
1310 int rc;
1311 struct mgcp_trunk_config *trunk;
1312
1313 cfg->osmux_port = OSMUX_PORT;
1314 cfg->osmux_batch = 4;
1315 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1316
1317 g_cfg = cfg;
1318 rc = vty_read_config_file(config_file, NULL);
1319 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001320 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1321 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001322 return rc;
1323 }
1324
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001325 if (!g_cfg->source_addr) {
1326 fprintf(stderr, "You need to specify a bind address.\n");
1327 return -1;
1328 }
1329
Philipp Maier48454982017-11-10 16:46:41 +01001330 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001331 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001332 "Failed to initialize the virtual trunk (%d endpoints)\n",
1333 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001334 return -1;
1335 }
1336
1337 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001338 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001339 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001340 "Failed to initialize trunk %d (%d endpoints)\n",
1341 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001342 return -1;
1343 }
1344 }
1345 cfg->role = role;
1346
1347 return 0;
1348}