blob: 00af3bde7163df535203f6bbb73e81126bbea683 [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>
Philipp Maierbca0ef62018-07-09 17:20:51 +020033#include <inttypes.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020034
35#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
36#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
37#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
38
39static struct mgcp_config *g_cfg = NULL;
40
41static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
42{
43 struct mgcp_trunk_config *trunk;
44
45 if (nr == 0)
46 trunk = &cfg->trunk;
47 else
48 trunk = mgcp_trunk_num(cfg, nr);
49
50 return trunk;
51}
52
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020053struct cmd_node mgcp_node = {
54 MGCP_NODE,
55 "%s(config-mgcp)# ",
56 1,
57};
58
59struct cmd_node trunk_node = {
60 TRUNK_NODE,
61 "%s(config-mgcp-trunk)# ",
62 1,
63};
64
65static int config_write_mgcp(struct vty *vty)
66{
67 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maier12943ea2018-01-17 15:40:25 +010068 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020069 if (g_cfg->local_ip)
70 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020071 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
72 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Philipp Maierf1889d82017-11-08 14:59:39 +010073 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020074 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
75 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020076 if (g_cfg->net_ports.bind_addr)
Philipp Maierf1889d82017-11-08 14:59:39 +010077 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020078 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010079 if (g_cfg->net_ports.bind_addr_probe)
80 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
81 else
82 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020083 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
84 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
85 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
86 else if (g_cfg->trunk.keepalive_interval)
87 vty_out(vty, " rtp keep-alive %d%s",
88 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
89 else
90 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
91
92 if (g_cfg->trunk.omit_rtcp)
93 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
94 else
95 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020096 if (g_cfg->trunk.force_constant_ssrc
97 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020098 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020099 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
100 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200101 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200102 g_cfg->trunk.force_aligned_timing ? "" : "no ",
103 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200104 } else
105 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
106 if (g_cfg->trunk.audio_payload != -1)
107 vty_out(vty, " sdp audio-payload number %d%s",
108 g_cfg->trunk.audio_payload, VTY_NEWLINE);
109 if (g_cfg->trunk.audio_name)
110 vty_out(vty, " sdp audio-payload name %s%s",
111 g_cfg->trunk.audio_name, VTY_NEWLINE);
112 if (g_cfg->trunk.audio_fmtp_extra)
113 vty_out(vty, " sdp audio fmtp-extra %s%s",
114 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
115 vty_out(vty, " %ssdp audio-payload send-ptime%s",
116 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
117 vty_out(vty, " %ssdp audio-payload send-name%s",
118 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200119 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
120 vty_out(vty, " number endpoints %u%s",
Philipp Maierfcd06552017-11-10 17:32:22 +0100121 g_cfg->trunk.vty_number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200122 vty_out(vty, " %sallow-transcoding%s",
123 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
124 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200125 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
126 VTY_NEWLINE);
127 if (g_cfg->force_ptime > 0)
128 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
129 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200130
131 switch (g_cfg->osmux) {
132 case OSMUX_USAGE_ON:
133 vty_out(vty, " osmux on%s", VTY_NEWLINE);
134 break;
135 case OSMUX_USAGE_ONLY:
136 vty_out(vty, " osmux only%s", VTY_NEWLINE);
137 break;
138 case OSMUX_USAGE_OFF:
139 default:
140 vty_out(vty, " osmux off%s", VTY_NEWLINE);
141 break;
142 }
143 if (g_cfg->osmux) {
144 vty_out(vty, " osmux bind-ip %s%s",
145 g_cfg->osmux_addr, VTY_NEWLINE);
146 vty_out(vty, " osmux batch-factor %d%s",
147 g_cfg->osmux_batch, VTY_NEWLINE);
148 vty_out(vty, " osmux batch-size %u%s",
149 g_cfg->osmux_batch_size, VTY_NEWLINE);
150 vty_out(vty, " osmux port %u%s",
151 g_cfg->osmux_port, VTY_NEWLINE);
152 vty_out(vty, " osmux dummy %s%s",
153 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
154 }
155 return CMD_SUCCESS;
156}
157
Philipp Maiercede2a42018-07-03 14:14:21 +0200158static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200159{
Philipp Maiercede2a42018-07-03 14:14:21 +0200160 struct mgcp_rtp_state *state = &conn->state;
161 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200162 struct mgcp_rtp_codec *codec = end->codec;
Philipp Maiercede2a42018-07-03 14:14:21 +0200163 struct rate_ctr *dropped_packets;
164
165 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200166
167 vty_out(vty,
Philipp Maierbca0ef62018-07-09 17:20:51 +0200168 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
169 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200170 " Payload Type: %d Rate: %u Channels: %d %s"
171 " Frame Duration: %u Frame Denominator: %u%s"
172 " FPP: %d Packet Duration: %u%s"
173 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
174 " Output-Enabled: %d Force-PTIME: %d%s",
Philipp Maier9e1d1642018-05-09 16:26:34 +0200175 state->in_stream.err_ts_ctr->current,
176 state->out_stream.err_ts_ctr->current,
177 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200178 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200179 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200180 codec->frame_duration_num, codec->frame_duration_den,
181 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
182 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
183 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
184 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200185}
186
Philipp Maier87bd9be2017-08-22 16:35:41 +0200187static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
188 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200189{
190 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200191 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200192
193 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
194 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
195 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
196
197 if (!cfg->endpoints) {
198 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
199 return;
200 }
201
202 for (i = 1; i < cfg->number_endpoints; ++i) {
203 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200204
Philipp Maier87bd9be2017-08-22 16:35:41 +0200205 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
206
207 llist_for_each_entry(conn, &endp->conns, entry) {
208 vty_out(vty, " CONN: %s%s",
209 mgcp_conn_dump(conn), VTY_NEWLINE);
210
211 if (verbose) {
212 /* FIXME: Also add verbosity for other
213 * connection types (E1) as soon as
214 * the implementation is available */
215 if (conn->type == MGCP_CONN_TYPE_RTP) {
Philipp Maiercede2a42018-07-03 14:14:21 +0200216 dump_rtp_end(vty, &conn->u.rtp);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200217 }
218 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200219 }
220 }
221}
222
223DEFUN(show_mcgp, show_mgcp_cmd,
224 "show mgcp [stats]",
225 SHOW_STR
226 "Display information about the MGCP Media Gateway\n"
227 "Include Statistics\n")
228{
229 struct mgcp_trunk_config *trunk;
230 int show_stats = argc >= 1;
231
232 dump_trunk(vty, &g_cfg->trunk, show_stats);
233
234 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200235 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200236
237 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200238 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
239 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200240
241 return CMD_SUCCESS;
242}
243
Philipp Maier87bd9be2017-08-22 16:35:41 +0200244DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200245{
246 vty->node = MGCP_NODE;
247 return CMD_SUCCESS;
248}
249
250DEFUN(cfg_mgcp_local_ip,
251 cfg_mgcp_local_ip_cmd,
252 "local ip A.B.C.D",
253 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200254 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200255{
256 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
257 return CMD_SUCCESS;
258}
259
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200260#define BIND_STR "Listen/Bind related socket option\n"
261DEFUN(cfg_mgcp_bind_ip,
262 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200263 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200264{
265 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
266 return CMD_SUCCESS;
267}
268
269DEFUN(cfg_mgcp_bind_port,
270 cfg_mgcp_bind_port_cmd,
271 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200272 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200273{
274 unsigned int port = atoi(argv[0]);
275 g_cfg->source_port = port;
276 return CMD_SUCCESS;
277}
278
279DEFUN(cfg_mgcp_bind_early,
280 cfg_mgcp_bind_early_cmd,
281 "bind early (0|1)",
282 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200283 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200284{
285 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
286 return CMD_WARNING;
287}
288
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200289#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200290#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200291#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200292#define RANGE_START_STR "Start of the range of ports\n"
293#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200294
Philipp Maierf1889d82017-11-08 14:59:39 +0100295DEFUN(cfg_mgcp_rtp_port_range,
296 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200297 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200298 RTP_STR "Range of ports to use for the NET side\n"
299 RANGE_START_STR RANGE_END_STR)
300{
Philipp Maiera19547b2018-05-22 13:44:34 +0200301 int start;
302 int end;
303
304 start = atoi(argv[0]);
305 end = atoi(argv[1]);
306
307 if (end < start) {
308 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
309 end, start, VTY_NEWLINE);
310 return CMD_WARNING;
311 }
312
313 if (start & 1) {
314 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
315 start, start & 0xFFFE, VTY_NEWLINE);
316 start &= 0xFFFE;
317 }
318
319 if ((end & 1) == 0) {
320 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
321 end, end | 1, VTY_NEWLINE);
322 end |= 1;
323 }
324
325 g_cfg->net_ports.range_start = start;
326 g_cfg->net_ports.range_end = end;
327 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
328
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200329 return CMD_SUCCESS;
330}
Philipp Maierf1889d82017-11-08 14:59:39 +0100331ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
332 cfg_mgcp_rtp_net_range_cmd,
333 "rtp net-range <0-65534> <0-65534>",
334 RTP_STR "Range of ports to use for the NET side\n"
335 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200336
Philipp Maierf1889d82017-11-08 14:59:39 +0100337DEFUN(cfg_mgcp_rtp_bind_ip,
338 cfg_mgcp_rtp_bind_ip_cmd,
339 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200340 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
341{
342 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
343 return CMD_SUCCESS;
344}
Philipp Maierf1889d82017-11-08 14:59:39 +0100345ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
346 cfg_mgcp_rtp_net_bind_ip_cmd,
347 "rtp net-bind-ip A.B.C.D",
348 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200349
Philipp Maierf1889d82017-11-08 14:59:39 +0100350DEFUN(cfg_mgcp_rtp_no_bind_ip,
351 cfg_mgcp_rtp_no_bind_ip_cmd,
352 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200353 NO_STR RTP_STR "Bind endpoints facing the Network\n"
354 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200355{
356 talloc_free(g_cfg->net_ports.bind_addr);
357 g_cfg->net_ports.bind_addr = NULL;
358 return CMD_SUCCESS;
359}
Philipp Maierf1889d82017-11-08 14:59:39 +0100360ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
361 cfg_mgcp_rtp_no_net_bind_ip_cmd,
362 "no rtp net-bind-ip",
363 NO_STR RTP_STR "Bind endpoints facing the Network\n"
364 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200365
Philipp Maier1cb1e382017-11-02 17:16:04 +0100366DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
367 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
368 "rtp ip-probing",
369 RTP_STR "automatic rtp bind ip selection\n")
370{
371 g_cfg->net_ports.bind_addr_probe = true;
372 return CMD_SUCCESS;
373}
374
375DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
376 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
377 "no rtp ip-probing",
378 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
379{
380 g_cfg->net_ports.bind_addr_probe = false;
381 return CMD_SUCCESS;
382}
383
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200384DEFUN(cfg_mgcp_rtp_ip_dscp,
385 cfg_mgcp_rtp_ip_dscp_cmd,
386 "rtp ip-dscp <0-255>",
387 RTP_STR
388 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
389{
390 int dscp = atoi(argv[0]);
391 g_cfg->endp_dscp = dscp;
392 return CMD_SUCCESS;
393}
394
395ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200396 "rtp ip-tos <0-255>",
397 RTP_STR
398 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
399#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
400 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200401 cfg_mgcp_rtp_force_ptime_cmd,
402 "rtp force-ptime (10|20|40)",
403 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200404 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200405{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200406 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200407 return CMD_SUCCESS;
408}
409
410DEFUN(cfg_mgcp_no_rtp_force_ptime,
411 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200412 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200413{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200414 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200415 return CMD_SUCCESS;
416}
417
418DEFUN(cfg_mgcp_sdp_fmtp_extra,
419 cfg_mgcp_sdp_fmtp_extra_cmd,
420 "sdp audio fmtp-extra .NAME",
421 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
422 "Extra Information\n")
423{
424 char *txt = argv_concat(argv, argc, 0);
425 if (!txt)
426 return CMD_WARNING;
427
428 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
429 talloc_free(txt);
430 return CMD_SUCCESS;
431}
432
433DEFUN(cfg_mgcp_allow_transcoding,
434 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200435 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200436{
437 g_cfg->trunk.no_audio_transcoding = 0;
438 return CMD_SUCCESS;
439}
440
441DEFUN(cfg_mgcp_no_allow_transcoding,
442 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200443 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200444{
445 g_cfg->trunk.no_audio_transcoding = 1;
446 return CMD_SUCCESS;
447}
448
449#define SDP_STR "SDP File related options\n"
450#define AUDIO_STR "Audio payload options\n"
451DEFUN(cfg_mgcp_sdp_payload_number,
452 cfg_mgcp_sdp_payload_number_cmd,
453 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200454 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200455{
456 unsigned int payload = atoi(argv[0]);
457 g_cfg->trunk.audio_payload = payload;
458 return CMD_SUCCESS;
459}
460
Philipp Maier87bd9be2017-08-22 16:35:41 +0200461ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
462 cfg_mgcp_sdp_payload_number_cmd_old,
463 "sdp audio payload number <0-255>",
464 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200465
Philipp Maier87bd9be2017-08-22 16:35:41 +0200466 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200467 cfg_mgcp_sdp_payload_name_cmd,
468 "sdp audio-payload name NAME",
469 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
470{
471 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
472 return CMD_SUCCESS;
473}
474
475ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200476 "sdp audio payload name NAME",
477 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200478
Philipp Maier87bd9be2017-08-22 16:35:41 +0200479 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200480 cfg_mgcp_sdp_payload_send_ptime_cmd,
481 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200482 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200483{
484 g_cfg->trunk.audio_send_ptime = 1;
485 return CMD_SUCCESS;
486}
487
488DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
489 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
490 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200491 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200492{
493 g_cfg->trunk.audio_send_ptime = 0;
494 return CMD_SUCCESS;
495}
496
497DEFUN(cfg_mgcp_sdp_payload_send_name,
498 cfg_mgcp_sdp_payload_send_name_cmd,
499 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200500 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200501{
502 g_cfg->trunk.audio_send_name = 1;
503 return CMD_SUCCESS;
504}
505
506DEFUN(cfg_mgcp_no_sdp_payload_send_name,
507 cfg_mgcp_no_sdp_payload_send_name_cmd,
508 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200509 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200510{
511 g_cfg->trunk.audio_send_name = 0;
512 return CMD_SUCCESS;
513}
514
515DEFUN(cfg_mgcp_loop,
516 cfg_mgcp_loop_cmd,
517 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200518 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200519{
520 if (g_cfg->osmux) {
521 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
522 return CMD_WARNING;
523 }
524 g_cfg->trunk.audio_loop = atoi(argv[0]);
525 return CMD_SUCCESS;
526}
527
528DEFUN(cfg_mgcp_force_realloc,
529 cfg_mgcp_force_realloc_cmd,
530 "force-realloc (0|1)",
531 "Force endpoint reallocation when the endpoint is still seized\n"
532 "Don't force reallocation\n" "force reallocation\n")
533{
534 g_cfg->trunk.force_realloc = atoi(argv[0]);
535 return CMD_SUCCESS;
536}
537
Philipp Maier87bd9be2017-08-22 16:35:41 +0200538DEFUN(cfg_mgcp_rtp_accept_all,
539 cfg_mgcp_rtp_accept_all_cmd,
540 "rtp-accept-all (0|1)",
541 "Accept all RTP packets, even when the originating IP/Port does not match\n"
542 "enable filter\n" "disable filter\n")
543{
544 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
545 return CMD_SUCCESS;
546}
547
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200548DEFUN(cfg_mgcp_number_endp,
549 cfg_mgcp_number_endp_cmd,
550 "number endpoints <0-65534>",
551 "Number options\n" "Endpoints available\n" "Number endpoints\n")
552{
553 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100554 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200555 return CMD_SUCCESS;
556}
557
Philipp Maier87bd9be2017-08-22 16:35:41 +0200558DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200559{
560 g_cfg->trunk.omit_rtcp = 1;
561 return CMD_SUCCESS;
562}
563
564DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200565 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200566{
567 g_cfg->trunk.omit_rtcp = 0;
568 return CMD_SUCCESS;
569}
570
571DEFUN(cfg_mgcp_patch_rtp_ssrc,
572 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200573 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200574{
575 g_cfg->trunk.force_constant_ssrc = 1;
576 return CMD_SUCCESS;
577}
578
579DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
580 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200581 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200582{
583 g_cfg->trunk.force_constant_ssrc = 0;
584 return CMD_SUCCESS;
585}
586
587DEFUN(cfg_mgcp_patch_rtp_ts,
588 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200589 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200590{
591 g_cfg->trunk.force_aligned_timing = 1;
592 return CMD_SUCCESS;
593}
594
595DEFUN(cfg_mgcp_no_patch_rtp_ts,
596 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200597 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200598{
599 g_cfg->trunk.force_aligned_timing = 0;
600 return CMD_SUCCESS;
601}
602
603DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200604 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200605{
606 g_cfg->trunk.force_constant_ssrc = 0;
607 g_cfg->trunk.force_aligned_timing = 0;
608 return CMD_SUCCESS;
609}
610
611DEFUN(cfg_mgcp_rtp_keepalive,
612 cfg_mgcp_rtp_keepalive_cmd,
613 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200614 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200615{
616 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
617 return CMD_SUCCESS;
618}
619
620DEFUN(cfg_mgcp_rtp_keepalive_once,
621 cfg_mgcp_rtp_keepalive_once_cmd,
622 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200623 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200624{
625 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
626 return CMD_SUCCESS;
627}
628
629DEFUN(cfg_mgcp_no_rtp_keepalive,
630 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200631 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200632{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100633 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200634 return CMD_SUCCESS;
635}
636
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200637#define CALL_AGENT_STR "Callagent information\n"
638DEFUN(cfg_mgcp_agent_addr,
639 cfg_mgcp_agent_addr_cmd,
640 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200641 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200642{
643 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
644 return CMD_SUCCESS;
645}
646
647ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200648 "call agent ip A.B.C.D",
649 CALL_AGENT_STR CALL_AGENT_STR IP_STR
650 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200651
Philipp Maier87bd9be2017-08-22 16:35:41 +0200652 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
653 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200654{
655 struct mgcp_trunk_config *trunk;
656 int index = atoi(argv[0]);
657
658 trunk = mgcp_trunk_num(g_cfg, index);
659 if (!trunk)
660 trunk = mgcp_trunk_alloc(g_cfg, index);
661
662 if (!trunk) {
663 vty_out(vty, "%%Unable to allocate trunk %u.%s",
664 index, VTY_NEWLINE);
665 return CMD_WARNING;
666 }
667
668 vty->node = TRUNK_NODE;
669 vty->index = trunk;
670 return CMD_SUCCESS;
671}
672
673static int config_write_trunk(struct vty *vty)
674{
675 struct mgcp_trunk_config *trunk;
676
677 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
678 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
679 vty_out(vty, " sdp audio-payload number %d%s",
680 trunk->audio_payload, VTY_NEWLINE);
681 vty_out(vty, " sdp audio-payload name %s%s",
682 trunk->audio_name, VTY_NEWLINE);
683 vty_out(vty, " %ssdp audio-payload send-ptime%s",
684 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
685 vty_out(vty, " %ssdp audio-payload send-name%s",
686 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
687
688 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
689 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
690 else if (trunk->keepalive_interval)
691 vty_out(vty, " rtp keep-alive %d%s",
692 trunk->keepalive_interval, VTY_NEWLINE);
693 else
694 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200695 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200696 vty_out(vty, " force-realloc %d%s",
697 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200698 vty_out(vty, " rtp-accept-all %d%s",
699 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200700 if (trunk->omit_rtcp)
701 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
702 else
703 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
704 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
705 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200706 trunk->force_constant_ssrc ? "" : "no ",
707 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200708 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200709 trunk->force_aligned_timing ? "" : "no ",
710 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200711 } else
712 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
713 if (trunk->audio_fmtp_extra)
714 vty_out(vty, " sdp audio fmtp-extra %s%s",
715 trunk->audio_fmtp_extra, VTY_NEWLINE);
716 vty_out(vty, " %sallow-transcoding%s",
717 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
718 }
719
720 return CMD_SUCCESS;
721}
722
723DEFUN(cfg_trunk_sdp_fmtp_extra,
724 cfg_trunk_sdp_fmtp_extra_cmd,
725 "sdp audio fmtp-extra .NAME",
726 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
727 "Extra Information\n")
728{
729 struct mgcp_trunk_config *trunk = vty->index;
730 char *txt = argv_concat(argv, argc, 0);
731 if (!txt)
732 return CMD_WARNING;
733
734 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
735 talloc_free(txt);
736 return CMD_SUCCESS;
737}
738
739DEFUN(cfg_trunk_payload_number,
740 cfg_trunk_payload_number_cmd,
741 "sdp audio-payload number <0-255>",
742 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
743{
744 struct mgcp_trunk_config *trunk = vty->index;
745 unsigned int payload = atoi(argv[0]);
746
747 trunk->audio_payload = payload;
748 return CMD_SUCCESS;
749}
750
751ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200752 "sdp audio payload number <0-255>",
753 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200754
Philipp Maier87bd9be2017-08-22 16:35:41 +0200755 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200756 cfg_trunk_payload_name_cmd,
757 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200758 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200759{
760 struct mgcp_trunk_config *trunk = vty->index;
761
762 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
763 return CMD_SUCCESS;
764}
765
766ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200767 "sdp audio payload name NAME",
768 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200769
Philipp Maier87bd9be2017-08-22 16:35:41 +0200770 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200771 cfg_trunk_loop_cmd,
772 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200773 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200774{
775 struct mgcp_trunk_config *trunk = vty->index;
776
777 if (g_cfg->osmux) {
778 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
779 return CMD_WARNING;
780 }
781 trunk->audio_loop = atoi(argv[0]);
782 return CMD_SUCCESS;
783}
784
785DEFUN(cfg_trunk_sdp_payload_send_ptime,
786 cfg_trunk_sdp_payload_send_ptime_cmd,
787 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200788 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200789{
790 struct mgcp_trunk_config *trunk = vty->index;
791 trunk->audio_send_ptime = 1;
792 return CMD_SUCCESS;
793}
794
795DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
796 cfg_trunk_no_sdp_payload_send_ptime_cmd,
797 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200798 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200799{
800 struct mgcp_trunk_config *trunk = vty->index;
801 trunk->audio_send_ptime = 0;
802 return CMD_SUCCESS;
803}
804
805DEFUN(cfg_trunk_sdp_payload_send_name,
806 cfg_trunk_sdp_payload_send_name_cmd,
807 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200808 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200809{
810 struct mgcp_trunk_config *trunk = vty->index;
811 trunk->audio_send_name = 1;
812 return CMD_SUCCESS;
813}
814
815DEFUN(cfg_trunk_no_sdp_payload_send_name,
816 cfg_trunk_no_sdp_payload_send_name_cmd,
817 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200818 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200819{
820 struct mgcp_trunk_config *trunk = vty->index;
821 trunk->audio_send_name = 0;
822 return CMD_SUCCESS;
823}
824
Philipp Maier87bd9be2017-08-22 16:35:41 +0200825DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200826{
827 struct mgcp_trunk_config *trunk = vty->index;
828 trunk->omit_rtcp = 1;
829 return CMD_SUCCESS;
830}
831
832DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200833 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200834{
835 struct mgcp_trunk_config *trunk = vty->index;
836 trunk->omit_rtcp = 0;
837 return CMD_SUCCESS;
838}
839
840DEFUN(cfg_trunk_patch_rtp_ssrc,
841 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200842 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200843{
844 struct mgcp_trunk_config *trunk = vty->index;
845 trunk->force_constant_ssrc = 1;
846 return CMD_SUCCESS;
847}
848
849DEFUN(cfg_trunk_no_patch_rtp_ssrc,
850 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200851 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200852{
853 struct mgcp_trunk_config *trunk = vty->index;
854 trunk->force_constant_ssrc = 0;
855 return CMD_SUCCESS;
856}
857
858DEFUN(cfg_trunk_patch_rtp_ts,
859 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200860 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200861{
862 struct mgcp_trunk_config *trunk = vty->index;
863 trunk->force_aligned_timing = 1;
864 return CMD_SUCCESS;
865}
866
867DEFUN(cfg_trunk_no_patch_rtp_ts,
868 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200869 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200870{
871 struct mgcp_trunk_config *trunk = vty->index;
872 trunk->force_aligned_timing = 0;
873 return CMD_SUCCESS;
874}
875
876DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200877 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200878{
879 struct mgcp_trunk_config *trunk = vty->index;
880 trunk->force_constant_ssrc = 0;
881 trunk->force_aligned_timing = 0;
882 return CMD_SUCCESS;
883}
884
885DEFUN(cfg_trunk_rtp_keepalive,
886 cfg_trunk_rtp_keepalive_cmd,
887 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200888 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200889{
890 struct mgcp_trunk_config *trunk = vty->index;
891 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
892 return CMD_SUCCESS;
893}
894
895DEFUN(cfg_trunk_rtp_keepalive_once,
896 cfg_trunk_rtp_keepalive_once_cmd,
897 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200898 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200899{
900 struct mgcp_trunk_config *trunk = vty->index;
901 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
902 return CMD_SUCCESS;
903}
904
905DEFUN(cfg_trunk_no_rtp_keepalive,
906 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200907 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200908{
909 struct mgcp_trunk_config *trunk = vty->index;
910 mgcp_trunk_set_keepalive(trunk, 0);
911 return CMD_SUCCESS;
912}
913
914DEFUN(cfg_trunk_allow_transcoding,
915 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200916 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200917{
918 struct mgcp_trunk_config *trunk = vty->index;
919 trunk->no_audio_transcoding = 0;
920 return CMD_SUCCESS;
921}
922
923DEFUN(cfg_trunk_no_allow_transcoding,
924 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200925 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200926{
927 struct mgcp_trunk_config *trunk = vty->index;
928 trunk->no_audio_transcoding = 1;
929 return CMD_SUCCESS;
930}
931
Philipp Maier87bd9be2017-08-22 16:35:41 +0200932DEFUN(loop_conn,
933 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200934 "loop-endpoint <0-64> NAME (0|1)",
935 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200936 "The name in hex of the endpoint\n" "Disable the loop\n"
937 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200938{
939 struct mgcp_trunk_config *trunk;
940 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200941 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200942
943 trunk = find_trunk(g_cfg, atoi(argv[0]));
944 if (!trunk) {
945 vty_out(vty, "%%Trunk %d not found in the config.%s",
946 atoi(argv[0]), VTY_NEWLINE);
947 return CMD_WARNING;
948 }
949
950 if (!trunk->endpoints) {
951 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
952 trunk->trunk_nr, VTY_NEWLINE);
953 return CMD_WARNING;
954 }
955
956 int endp_no = strtoul(argv[1], NULL, 16);
957 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
958 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200959 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200960 return CMD_WARNING;
961 }
962
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200963 endp = &trunk->endpoints[endp_no];
964 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200965 llist_for_each_entry(conn, &endp->conns, entry) {
966 if (conn->type == MGCP_CONN_TYPE_RTP)
967 /* Handle it like a MDCX, switch on SSRC patching if enabled */
968 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
969 else {
970 /* FIXME: Introduce support for other connection (E1)
971 * types when implementation is available */
972 vty_out(vty, "%%Can't enable SSRC patching,"
973 "connection %s is not an RTP connection.%s",
974 mgcp_conn_dump(conn), VTY_NEWLINE);
975 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200976
Philipp Maier87bd9be2017-08-22 16:35:41 +0200977 if (loop)
978 conn->mode = MGCP_CONN_LOOPBACK;
979 else
980 conn->mode = conn->mode_orig;
981 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200982
983 return CMD_SUCCESS;
984}
985
Philipp Maier87bd9be2017-08-22 16:35:41 +0200986DEFUN(tap_rtp,
987 tap_rtp_cmd,
988 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200989 "Forward data on endpoint to a different system\n" "Trunk number\n"
990 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200991 "The connection id in hex\n"
992 "Forward incoming data\n"
993 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200994 "destination IP of the data\n" "destination port\n")
995{
996 struct mgcp_rtp_tap *tap;
997 struct mgcp_trunk_config *trunk;
998 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200999 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001000 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001001
1002 trunk = find_trunk(g_cfg, atoi(argv[0]));
1003 if (!trunk) {
1004 vty_out(vty, "%%Trunk %d not found in the config.%s",
1005 atoi(argv[0]), VTY_NEWLINE);
1006 return CMD_WARNING;
1007 }
1008
1009 if (!trunk->endpoints) {
1010 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1011 trunk->trunk_nr, VTY_NEWLINE);
1012 return CMD_WARNING;
1013 }
1014
1015 int endp_no = strtoul(argv[1], NULL, 16);
1016 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1017 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001018 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001019 return CMD_WARNING;
1020 }
1021
1022 endp = &trunk->endpoints[endp_no];
1023
Philipp Maier01d24a32017-11-21 17:26:09 +01001024 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001025 conn = mgcp_conn_get_rtp(endp, conn_id);
1026 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001027 vty_out(vty, "Conn ID %s is invalid.%s",
1028 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001029 return CMD_WARNING;
1030 }
1031
1032 if (strcmp(argv[3], "in") == 0)
1033 tap = &conn->tap_in;
1034 else if (strcmp(argv[3], "out") == 0)
1035 tap = &conn->tap_out;
1036 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001037 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1038 return CMD_WARNING;
1039 }
1040
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001041 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001042 inet_aton(argv[4], &tap->forward.sin_addr);
1043 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001044 tap->enabled = 1;
1045 return CMD_SUCCESS;
1046}
1047
1048DEFUN(free_endp, free_endp_cmd,
1049 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001050 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001051{
1052 struct mgcp_trunk_config *trunk;
1053 struct mgcp_endpoint *endp;
1054
1055 trunk = find_trunk(g_cfg, atoi(argv[0]));
1056 if (!trunk) {
1057 vty_out(vty, "%%Trunk %d not found in the config.%s",
1058 atoi(argv[0]), VTY_NEWLINE);
1059 return CMD_WARNING;
1060 }
1061
1062 if (!trunk->endpoints) {
1063 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1064 trunk->trunk_nr, VTY_NEWLINE);
1065 return CMD_WARNING;
1066 }
1067
1068 int endp_no = strtoul(argv[1], NULL, 16);
1069 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1070 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001071 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001072 return CMD_WARNING;
1073 }
1074
1075 endp = &trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001076 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001077 return CMD_SUCCESS;
1078}
1079
1080DEFUN(reset_endp, reset_endp_cmd,
1081 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001082 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001083{
1084 struct mgcp_trunk_config *trunk;
1085 struct mgcp_endpoint *endp;
1086 int endp_no, rc;
1087
1088 trunk = find_trunk(g_cfg, atoi(argv[0]));
1089 if (!trunk) {
1090 vty_out(vty, "%%Trunk %d not found in the config.%s",
1091 atoi(argv[0]), VTY_NEWLINE);
1092 return CMD_WARNING;
1093 }
1094
1095 if (!trunk->endpoints) {
1096 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1097 trunk->trunk_nr, VTY_NEWLINE);
1098 return CMD_WARNING;
1099 }
1100
1101 endp_no = strtoul(argv[1], NULL, 16);
1102 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1103 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001104 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001105 return CMD_WARNING;
1106 }
1107
1108 endp = &trunk->endpoints[endp_no];
1109 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1110 if (rc < 0) {
1111 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1112 return CMD_WARNING;
1113 }
1114 return CMD_SUCCESS;
1115}
1116
1117DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001118 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001119{
1120 int rc;
1121
1122 rc = mgcp_send_reset_all(g_cfg);
1123 if (rc < 0) {
1124 vty_out(vty, "Error %d during endpoint reset.%s",
1125 rc, VTY_NEWLINE);
1126 return CMD_WARNING;
1127 }
1128 return CMD_SUCCESS;
1129}
1130
1131#define OSMUX_STR "RTP multiplexing\n"
1132DEFUN(cfg_mgcp_osmux,
1133 cfg_mgcp_osmux_cmd,
1134 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001135 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001136{
1137 if (strcmp(argv[0], "off") == 0) {
1138 g_cfg->osmux = OSMUX_USAGE_OFF;
1139 return CMD_SUCCESS;
1140 }
1141
Philipp Maier87bd9be2017-08-22 16:35:41 +02001142 /* Since OSMUX support is not finished, we do not
1143 * allow to turn it on yet. */
1144 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1145 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001146#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001147 if (strcmp(argv[0], "on") == 0)
1148 g_cfg->osmux = OSMUX_USAGE_ON;
1149 else if (strcmp(argv[0], "only") == 0)
1150 g_cfg->osmux = OSMUX_USAGE_ONLY;
1151
1152 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001153 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001154 return CMD_WARNING;
1155 }
1156
1157 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001158#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001159}
1160
1161DEFUN(cfg_mgcp_osmux_ip,
1162 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001163 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001164{
1165 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1166 return CMD_SUCCESS;
1167}
1168
1169DEFUN(cfg_mgcp_osmux_batch_factor,
1170 cfg_mgcp_osmux_batch_factor_cmd,
1171 "osmux batch-factor <1-8>",
1172 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1173{
1174 g_cfg->osmux_batch = atoi(argv[0]);
1175 return CMD_SUCCESS;
1176}
1177
1178DEFUN(cfg_mgcp_osmux_batch_size,
1179 cfg_mgcp_osmux_batch_size_cmd,
1180 "osmux batch-size <1-65535>",
1181 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1182{
1183 g_cfg->osmux_batch_size = atoi(argv[0]);
1184 return CMD_SUCCESS;
1185}
1186
1187DEFUN(cfg_mgcp_osmux_port,
1188 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001189 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001190{
1191 g_cfg->osmux_port = atoi(argv[0]);
1192 return CMD_SUCCESS;
1193}
1194
1195DEFUN(cfg_mgcp_osmux_dummy,
1196 cfg_mgcp_osmux_dummy_cmd,
1197 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001198 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1199 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001200{
1201 if (strcmp(argv[0], "on") == 0)
1202 g_cfg->osmux_dummy = 1;
1203 else if (strcmp(argv[0], "off") == 0)
1204 g_cfg->osmux_dummy = 0;
1205
1206 return CMD_SUCCESS;
1207}
1208
Philipp Maier12943ea2018-01-17 15:40:25 +01001209DEFUN(cfg_mgcp_domain,
1210 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001211 "domain NAME",
1212 "Set the domain part expected in MGCP messages' endpoint names\n"
1213 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001214{
1215 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1216 return CMD_SUCCESS;
1217}
1218
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001219int mgcp_vty_init(void)
1220{
1221 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001222 install_element(ENABLE_NODE, &loop_conn_cmd);
1223 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001224 install_element(ENABLE_NODE, &free_endp_cmd);
1225 install_element(ENABLE_NODE, &reset_endp_cmd);
1226 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1227
1228 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1229 install_node(&mgcp_node, config_write_mgcp);
1230
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001231 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001232 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1233 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1234 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001235 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001236 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001237 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001238 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001239 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001240 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001241 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1242 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001243 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1244 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1245 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1246 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1247 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1248 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1249 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1250 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1251 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001252 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1253 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1254 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1255 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1256 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1257 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001258 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001259 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1260 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1261 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1262 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1263 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1264 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1265 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1266 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1267 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1268 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1269 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1270 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1271 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1272 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1273 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1274 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1275 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1276 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1277 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1278 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1279 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001280 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001281
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001282 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1283 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001284 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1285 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1286 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1287 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1288 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1289 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1290 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1291 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1292 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1293 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1294 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1295 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1296 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1297 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1298 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1299 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1300 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1301 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1302 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1303 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1304 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1305 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1306
1307 return 0;
1308}
1309
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001310int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1311 enum mgcp_role role)
1312{
1313 int rc;
1314 struct mgcp_trunk_config *trunk;
1315
1316 cfg->osmux_port = OSMUX_PORT;
1317 cfg->osmux_batch = 4;
1318 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1319
1320 g_cfg = cfg;
1321 rc = vty_read_config_file(config_file, NULL);
1322 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001323 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1324 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001325 return rc;
1326 }
1327
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001328 if (!g_cfg->source_addr) {
1329 fprintf(stderr, "You need to specify a bind address.\n");
1330 return -1;
1331 }
1332
Philipp Maier48454982017-11-10 16:46:41 +01001333 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001334 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001335 "Failed to initialize the virtual trunk (%d endpoints)\n",
1336 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001337 return -1;
1338 }
1339
1340 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001341 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001342 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001343 "Failed to initialize trunk %d (%d endpoints)\n",
1344 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001345 return -1;
1346 }
1347 }
1348 cfg->role = role;
1349
1350 return 0;
1351}