blob: e9383915bcbb6df9e842aa708c0f51d227deedc0 [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>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020030
31#include <string.h>
32
33#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
34#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
35#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
36
37static struct mgcp_config *g_cfg = NULL;
38
39static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
40{
41 struct mgcp_trunk_config *trunk;
42
43 if (nr == 0)
44 trunk = &cfg->trunk;
45 else
46 trunk = mgcp_trunk_num(cfg, nr);
47
48 return trunk;
49}
50
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020051struct cmd_node mgcp_node = {
52 MGCP_NODE,
53 "%s(config-mgcp)# ",
54 1,
55};
56
57struct cmd_node trunk_node = {
58 TRUNK_NODE,
59 "%s(config-mgcp-trunk)# ",
60 1,
61};
62
63static int config_write_mgcp(struct vty *vty)
64{
65 vty_out(vty, "mgcp%s", VTY_NEWLINE);
66 if (g_cfg->local_ip)
67 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020068 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
69 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Philipp Maierf1889d82017-11-08 14:59:39 +010070 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020071 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
72 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020073 if (g_cfg->net_ports.bind_addr)
Philipp Maierf1889d82017-11-08 14:59:39 +010074 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020075 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010076 if (g_cfg->net_ports.bind_addr_probe)
77 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
78 else
79 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020080 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
81 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
82 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
83 else if (g_cfg->trunk.keepalive_interval)
84 vty_out(vty, " rtp keep-alive %d%s",
85 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
86 else
87 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
88
89 if (g_cfg->trunk.omit_rtcp)
90 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
91 else
92 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020093 if (g_cfg->trunk.force_constant_ssrc
94 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020095 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020096 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
97 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020098 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020099 g_cfg->trunk.force_aligned_timing ? "" : "no ",
100 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200101 } else
102 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
103 if (g_cfg->trunk.audio_payload != -1)
104 vty_out(vty, " sdp audio-payload number %d%s",
105 g_cfg->trunk.audio_payload, VTY_NEWLINE);
106 if (g_cfg->trunk.audio_name)
107 vty_out(vty, " sdp audio-payload name %s%s",
108 g_cfg->trunk.audio_name, VTY_NEWLINE);
109 if (g_cfg->trunk.audio_fmtp_extra)
110 vty_out(vty, " sdp audio fmtp-extra %s%s",
111 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
112 vty_out(vty, " %ssdp audio-payload send-ptime%s",
113 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
114 vty_out(vty, " %ssdp audio-payload send-name%s",
115 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200116 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
117 vty_out(vty, " number endpoints %u%s",
Philipp Maierfcd06552017-11-10 17:32:22 +0100118 g_cfg->trunk.vty_number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200119 vty_out(vty, " %sallow-transcoding%s",
120 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
121 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200122 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
123 VTY_NEWLINE);
124 if (g_cfg->force_ptime > 0)
125 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
126 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200127
128 switch (g_cfg->osmux) {
129 case OSMUX_USAGE_ON:
130 vty_out(vty, " osmux on%s", VTY_NEWLINE);
131 break;
132 case OSMUX_USAGE_ONLY:
133 vty_out(vty, " osmux only%s", VTY_NEWLINE);
134 break;
135 case OSMUX_USAGE_OFF:
136 default:
137 vty_out(vty, " osmux off%s", VTY_NEWLINE);
138 break;
139 }
140 if (g_cfg->osmux) {
141 vty_out(vty, " osmux bind-ip %s%s",
142 g_cfg->osmux_addr, VTY_NEWLINE);
143 vty_out(vty, " osmux batch-factor %d%s",
144 g_cfg->osmux_batch, VTY_NEWLINE);
145 vty_out(vty, " osmux batch-size %u%s",
146 g_cfg->osmux_batch_size, VTY_NEWLINE);
147 vty_out(vty, " osmux port %u%s",
148 g_cfg->osmux_port, VTY_NEWLINE);
149 vty_out(vty, " osmux dummy %s%s",
150 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
151 }
152 return CMD_SUCCESS;
153}
154
Philipp Maier87bd9be2017-08-22 16:35:41 +0200155static void dump_rtp_end(struct vty *vty, struct mgcp_rtp_state *state,
156 struct mgcp_rtp_end *end)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200157{
158 struct mgcp_rtp_codec *codec = &end->codec;
159
160 vty_out(vty,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200161 " Timestamp Errs: %d->%d%s"
162 " Dropped Packets: %d%s"
163 " Payload Type: %d Rate: %u Channels: %d %s"
164 " Frame Duration: %u Frame Denominator: %u%s"
165 " FPP: %d Packet Duration: %u%s"
166 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
167 " Output-Enabled: %d Force-PTIME: %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200168 state->in_stream.err_ts_counter,
169 state->out_stream.err_ts_counter, VTY_NEWLINE,
170 end->dropped_packets, VTY_NEWLINE,
171 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200172 codec->frame_duration_num, codec->frame_duration_den,
173 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
174 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
175 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
176 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200177}
178
Philipp Maier87bd9be2017-08-22 16:35:41 +0200179static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
180 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200181{
182 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200183 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200184
185 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
186 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
187 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
188
189 if (!cfg->endpoints) {
190 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
191 return;
192 }
193
194 for (i = 1; i < cfg->number_endpoints; ++i) {
195 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200196
Philipp Maier87bd9be2017-08-22 16:35:41 +0200197 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
198
199 llist_for_each_entry(conn, &endp->conns, entry) {
200 vty_out(vty, " CONN: %s%s",
201 mgcp_conn_dump(conn), VTY_NEWLINE);
202
203 if (verbose) {
204 /* FIXME: Also add verbosity for other
205 * connection types (E1) as soon as
206 * the implementation is available */
207 if (conn->type == MGCP_CONN_TYPE_RTP) {
208 dump_rtp_end(vty, &conn->u.rtp.state,
209 &conn->u.rtp.end);
210 }
211 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200212 }
213 }
214}
215
216DEFUN(show_mcgp, show_mgcp_cmd,
217 "show mgcp [stats]",
218 SHOW_STR
219 "Display information about the MGCP Media Gateway\n"
220 "Include Statistics\n")
221{
222 struct mgcp_trunk_config *trunk;
223 int show_stats = argc >= 1;
224
225 dump_trunk(vty, &g_cfg->trunk, show_stats);
226
227 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200228 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200229
230 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200231 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
232 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200233
234 return CMD_SUCCESS;
235}
236
Philipp Maier87bd9be2017-08-22 16:35:41 +0200237DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200238{
239 vty->node = MGCP_NODE;
240 return CMD_SUCCESS;
241}
242
243DEFUN(cfg_mgcp_local_ip,
244 cfg_mgcp_local_ip_cmd,
245 "local ip A.B.C.D",
246 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200247 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200248{
249 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
250 return CMD_SUCCESS;
251}
252
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200253#define BIND_STR "Listen/Bind related socket option\n"
254DEFUN(cfg_mgcp_bind_ip,
255 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200256 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200257{
258 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
259 return CMD_SUCCESS;
260}
261
262DEFUN(cfg_mgcp_bind_port,
263 cfg_mgcp_bind_port_cmd,
264 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200265 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200266{
267 unsigned int port = atoi(argv[0]);
268 g_cfg->source_port = port;
269 return CMD_SUCCESS;
270}
271
272DEFUN(cfg_mgcp_bind_early,
273 cfg_mgcp_bind_early_cmd,
274 "bind early (0|1)",
275 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200276 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200277{
278 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
279 return CMD_WARNING;
280}
281
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200282static void parse_range(struct mgcp_port_range *range, const char **argv)
283{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200284 range->range_start = atoi(argv[0]);
285 range->range_end = atoi(argv[1]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200286 range->last_port = g_cfg->net_ports.range_start;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200287}
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,
297 "rtp port-range <0-65534> <0-65534>",
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{
301 parse_range(&g_cfg->net_ports, argv);
302 return CMD_SUCCESS;
303}
Philipp Maierf1889d82017-11-08 14:59:39 +0100304ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
305 cfg_mgcp_rtp_net_range_cmd,
306 "rtp net-range <0-65534> <0-65534>",
307 RTP_STR "Range of ports to use for the NET side\n"
308 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200309
Philipp Maierf1889d82017-11-08 14:59:39 +0100310DEFUN(cfg_mgcp_rtp_bind_ip,
311 cfg_mgcp_rtp_bind_ip_cmd,
312 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200313 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
314{
315 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
316 return CMD_SUCCESS;
317}
Philipp Maierf1889d82017-11-08 14:59:39 +0100318ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
319 cfg_mgcp_rtp_net_bind_ip_cmd,
320 "rtp net-bind-ip A.B.C.D",
321 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200322
Philipp Maierf1889d82017-11-08 14:59:39 +0100323DEFUN(cfg_mgcp_rtp_no_bind_ip,
324 cfg_mgcp_rtp_no_bind_ip_cmd,
325 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200326 NO_STR RTP_STR "Bind endpoints facing the Network\n"
327 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200328{
329 talloc_free(g_cfg->net_ports.bind_addr);
330 g_cfg->net_ports.bind_addr = NULL;
331 return CMD_SUCCESS;
332}
Philipp Maierf1889d82017-11-08 14:59:39 +0100333ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
334 cfg_mgcp_rtp_no_net_bind_ip_cmd,
335 "no rtp net-bind-ip",
336 NO_STR RTP_STR "Bind endpoints facing the Network\n"
337 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200338
Philipp Maier1cb1e382017-11-02 17:16:04 +0100339DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
340 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
341 "rtp ip-probing",
342 RTP_STR "automatic rtp bind ip selection\n")
343{
344 g_cfg->net_ports.bind_addr_probe = true;
345 return CMD_SUCCESS;
346}
347
348DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
349 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
350 "no rtp ip-probing",
351 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
352{
353 g_cfg->net_ports.bind_addr_probe = false;
354 return CMD_SUCCESS;
355}
356
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200357DEFUN(cfg_mgcp_rtp_ip_dscp,
358 cfg_mgcp_rtp_ip_dscp_cmd,
359 "rtp ip-dscp <0-255>",
360 RTP_STR
361 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
362{
363 int dscp = atoi(argv[0]);
364 g_cfg->endp_dscp = dscp;
365 return CMD_SUCCESS;
366}
367
368ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200369 "rtp ip-tos <0-255>",
370 RTP_STR
371 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
372#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
373 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200374 cfg_mgcp_rtp_force_ptime_cmd,
375 "rtp force-ptime (10|20|40)",
376 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200377 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200378{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200379 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200380 return CMD_SUCCESS;
381}
382
383DEFUN(cfg_mgcp_no_rtp_force_ptime,
384 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200385 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200386{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200387 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200388 return CMD_SUCCESS;
389}
390
391DEFUN(cfg_mgcp_sdp_fmtp_extra,
392 cfg_mgcp_sdp_fmtp_extra_cmd,
393 "sdp audio fmtp-extra .NAME",
394 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
395 "Extra Information\n")
396{
397 char *txt = argv_concat(argv, argc, 0);
398 if (!txt)
399 return CMD_WARNING;
400
401 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
402 talloc_free(txt);
403 return CMD_SUCCESS;
404}
405
406DEFUN(cfg_mgcp_allow_transcoding,
407 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200408 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200409{
410 g_cfg->trunk.no_audio_transcoding = 0;
411 return CMD_SUCCESS;
412}
413
414DEFUN(cfg_mgcp_no_allow_transcoding,
415 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200416 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200417{
418 g_cfg->trunk.no_audio_transcoding = 1;
419 return CMD_SUCCESS;
420}
421
422#define SDP_STR "SDP File related options\n"
423#define AUDIO_STR "Audio payload options\n"
424DEFUN(cfg_mgcp_sdp_payload_number,
425 cfg_mgcp_sdp_payload_number_cmd,
426 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200427 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200428{
429 unsigned int payload = atoi(argv[0]);
430 g_cfg->trunk.audio_payload = payload;
431 return CMD_SUCCESS;
432}
433
Philipp Maier87bd9be2017-08-22 16:35:41 +0200434ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
435 cfg_mgcp_sdp_payload_number_cmd_old,
436 "sdp audio payload number <0-255>",
437 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200438
Philipp Maier87bd9be2017-08-22 16:35:41 +0200439 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200440 cfg_mgcp_sdp_payload_name_cmd,
441 "sdp audio-payload name NAME",
442 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
443{
444 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
445 return CMD_SUCCESS;
446}
447
448ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200449 "sdp audio payload name NAME",
450 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200451
Philipp Maier87bd9be2017-08-22 16:35:41 +0200452 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200453 cfg_mgcp_sdp_payload_send_ptime_cmd,
454 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200455 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200456{
457 g_cfg->trunk.audio_send_ptime = 1;
458 return CMD_SUCCESS;
459}
460
461DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
462 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
463 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200464 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200465{
466 g_cfg->trunk.audio_send_ptime = 0;
467 return CMD_SUCCESS;
468}
469
470DEFUN(cfg_mgcp_sdp_payload_send_name,
471 cfg_mgcp_sdp_payload_send_name_cmd,
472 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200473 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200474{
475 g_cfg->trunk.audio_send_name = 1;
476 return CMD_SUCCESS;
477}
478
479DEFUN(cfg_mgcp_no_sdp_payload_send_name,
480 cfg_mgcp_no_sdp_payload_send_name_cmd,
481 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200482 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200483{
484 g_cfg->trunk.audio_send_name = 0;
485 return CMD_SUCCESS;
486}
487
488DEFUN(cfg_mgcp_loop,
489 cfg_mgcp_loop_cmd,
490 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200491 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200492{
493 if (g_cfg->osmux) {
494 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
495 return CMD_WARNING;
496 }
497 g_cfg->trunk.audio_loop = atoi(argv[0]);
498 return CMD_SUCCESS;
499}
500
501DEFUN(cfg_mgcp_force_realloc,
502 cfg_mgcp_force_realloc_cmd,
503 "force-realloc (0|1)",
504 "Force endpoint reallocation when the endpoint is still seized\n"
505 "Don't force reallocation\n" "force reallocation\n")
506{
507 g_cfg->trunk.force_realloc = atoi(argv[0]);
508 return CMD_SUCCESS;
509}
510
Philipp Maier87bd9be2017-08-22 16:35:41 +0200511DEFUN(cfg_mgcp_rtp_accept_all,
512 cfg_mgcp_rtp_accept_all_cmd,
513 "rtp-accept-all (0|1)",
514 "Accept all RTP packets, even when the originating IP/Port does not match\n"
515 "enable filter\n" "disable filter\n")
516{
517 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
518 return CMD_SUCCESS;
519}
520
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200521DEFUN(cfg_mgcp_number_endp,
522 cfg_mgcp_number_endp_cmd,
523 "number endpoints <0-65534>",
524 "Number options\n" "Endpoints available\n" "Number endpoints\n")
525{
526 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100527 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200528 return CMD_SUCCESS;
529}
530
Philipp Maier87bd9be2017-08-22 16:35:41 +0200531DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200532{
533 g_cfg->trunk.omit_rtcp = 1;
534 return CMD_SUCCESS;
535}
536
537DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200538 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200539{
540 g_cfg->trunk.omit_rtcp = 0;
541 return CMD_SUCCESS;
542}
543
544DEFUN(cfg_mgcp_patch_rtp_ssrc,
545 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200546 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200547{
548 g_cfg->trunk.force_constant_ssrc = 1;
549 return CMD_SUCCESS;
550}
551
552DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
553 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200554 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200555{
556 g_cfg->trunk.force_constant_ssrc = 0;
557 return CMD_SUCCESS;
558}
559
560DEFUN(cfg_mgcp_patch_rtp_ts,
561 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200562 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200563{
564 g_cfg->trunk.force_aligned_timing = 1;
565 return CMD_SUCCESS;
566}
567
568DEFUN(cfg_mgcp_no_patch_rtp_ts,
569 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200570 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200571{
572 g_cfg->trunk.force_aligned_timing = 0;
573 return CMD_SUCCESS;
574}
575
576DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200577 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200578{
579 g_cfg->trunk.force_constant_ssrc = 0;
580 g_cfg->trunk.force_aligned_timing = 0;
581 return CMD_SUCCESS;
582}
583
584DEFUN(cfg_mgcp_rtp_keepalive,
585 cfg_mgcp_rtp_keepalive_cmd,
586 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200587 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200588{
589 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
590 return CMD_SUCCESS;
591}
592
593DEFUN(cfg_mgcp_rtp_keepalive_once,
594 cfg_mgcp_rtp_keepalive_once_cmd,
595 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200596 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200597{
598 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
599 return CMD_SUCCESS;
600}
601
602DEFUN(cfg_mgcp_no_rtp_keepalive,
603 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200604 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200605{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100606 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200607 return CMD_SUCCESS;
608}
609
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200610#define CALL_AGENT_STR "Callagent information\n"
611DEFUN(cfg_mgcp_agent_addr,
612 cfg_mgcp_agent_addr_cmd,
613 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200614 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200615{
616 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
617 return CMD_SUCCESS;
618}
619
620ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200621 "call agent ip A.B.C.D",
622 CALL_AGENT_STR CALL_AGENT_STR IP_STR
623 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200624
Philipp Maier87bd9be2017-08-22 16:35:41 +0200625 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
626 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200627{
628 struct mgcp_trunk_config *trunk;
629 int index = atoi(argv[0]);
630
631 trunk = mgcp_trunk_num(g_cfg, index);
632 if (!trunk)
633 trunk = mgcp_trunk_alloc(g_cfg, index);
634
635 if (!trunk) {
636 vty_out(vty, "%%Unable to allocate trunk %u.%s",
637 index, VTY_NEWLINE);
638 return CMD_WARNING;
639 }
640
641 vty->node = TRUNK_NODE;
642 vty->index = trunk;
643 return CMD_SUCCESS;
644}
645
646static int config_write_trunk(struct vty *vty)
647{
648 struct mgcp_trunk_config *trunk;
649
650 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
651 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
652 vty_out(vty, " sdp audio-payload number %d%s",
653 trunk->audio_payload, VTY_NEWLINE);
654 vty_out(vty, " sdp audio-payload name %s%s",
655 trunk->audio_name, VTY_NEWLINE);
656 vty_out(vty, " %ssdp audio-payload send-ptime%s",
657 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
658 vty_out(vty, " %ssdp audio-payload send-name%s",
659 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
660
661 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
662 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
663 else if (trunk->keepalive_interval)
664 vty_out(vty, " rtp keep-alive %d%s",
665 trunk->keepalive_interval, VTY_NEWLINE);
666 else
667 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200668 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200669 vty_out(vty, " force-realloc %d%s",
670 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200671 vty_out(vty, " rtp-accept-all %d%s",
672 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200673 if (trunk->omit_rtcp)
674 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
675 else
676 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
677 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
678 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200679 trunk->force_constant_ssrc ? "" : "no ",
680 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200681 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200682 trunk->force_aligned_timing ? "" : "no ",
683 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200684 } else
685 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
686 if (trunk->audio_fmtp_extra)
687 vty_out(vty, " sdp audio fmtp-extra %s%s",
688 trunk->audio_fmtp_extra, VTY_NEWLINE);
689 vty_out(vty, " %sallow-transcoding%s",
690 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
691 }
692
693 return CMD_SUCCESS;
694}
695
696DEFUN(cfg_trunk_sdp_fmtp_extra,
697 cfg_trunk_sdp_fmtp_extra_cmd,
698 "sdp audio fmtp-extra .NAME",
699 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
700 "Extra Information\n")
701{
702 struct mgcp_trunk_config *trunk = vty->index;
703 char *txt = argv_concat(argv, argc, 0);
704 if (!txt)
705 return CMD_WARNING;
706
707 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
708 talloc_free(txt);
709 return CMD_SUCCESS;
710}
711
712DEFUN(cfg_trunk_payload_number,
713 cfg_trunk_payload_number_cmd,
714 "sdp audio-payload number <0-255>",
715 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
716{
717 struct mgcp_trunk_config *trunk = vty->index;
718 unsigned int payload = atoi(argv[0]);
719
720 trunk->audio_payload = payload;
721 return CMD_SUCCESS;
722}
723
724ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200725 "sdp audio payload number <0-255>",
726 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200727
Philipp Maier87bd9be2017-08-22 16:35:41 +0200728 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200729 cfg_trunk_payload_name_cmd,
730 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200731 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200732{
733 struct mgcp_trunk_config *trunk = vty->index;
734
735 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
736 return CMD_SUCCESS;
737}
738
739ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200740 "sdp audio payload name NAME",
741 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200742
Philipp Maier87bd9be2017-08-22 16:35:41 +0200743 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200744 cfg_trunk_loop_cmd,
745 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200746 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200747{
748 struct mgcp_trunk_config *trunk = vty->index;
749
750 if (g_cfg->osmux) {
751 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
752 return CMD_WARNING;
753 }
754 trunk->audio_loop = atoi(argv[0]);
755 return CMD_SUCCESS;
756}
757
758DEFUN(cfg_trunk_sdp_payload_send_ptime,
759 cfg_trunk_sdp_payload_send_ptime_cmd,
760 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200761 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200762{
763 struct mgcp_trunk_config *trunk = vty->index;
764 trunk->audio_send_ptime = 1;
765 return CMD_SUCCESS;
766}
767
768DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
769 cfg_trunk_no_sdp_payload_send_ptime_cmd,
770 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200771 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200772{
773 struct mgcp_trunk_config *trunk = vty->index;
774 trunk->audio_send_ptime = 0;
775 return CMD_SUCCESS;
776}
777
778DEFUN(cfg_trunk_sdp_payload_send_name,
779 cfg_trunk_sdp_payload_send_name_cmd,
780 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200781 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200782{
783 struct mgcp_trunk_config *trunk = vty->index;
784 trunk->audio_send_name = 1;
785 return CMD_SUCCESS;
786}
787
788DEFUN(cfg_trunk_no_sdp_payload_send_name,
789 cfg_trunk_no_sdp_payload_send_name_cmd,
790 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200791 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200792{
793 struct mgcp_trunk_config *trunk = vty->index;
794 trunk->audio_send_name = 0;
795 return CMD_SUCCESS;
796}
797
Philipp Maier87bd9be2017-08-22 16:35:41 +0200798DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200799{
800 struct mgcp_trunk_config *trunk = vty->index;
801 trunk->omit_rtcp = 1;
802 return CMD_SUCCESS;
803}
804
805DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200806 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200807{
808 struct mgcp_trunk_config *trunk = vty->index;
809 trunk->omit_rtcp = 0;
810 return CMD_SUCCESS;
811}
812
813DEFUN(cfg_trunk_patch_rtp_ssrc,
814 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200815 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200816{
817 struct mgcp_trunk_config *trunk = vty->index;
818 trunk->force_constant_ssrc = 1;
819 return CMD_SUCCESS;
820}
821
822DEFUN(cfg_trunk_no_patch_rtp_ssrc,
823 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200824 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200825{
826 struct mgcp_trunk_config *trunk = vty->index;
827 trunk->force_constant_ssrc = 0;
828 return CMD_SUCCESS;
829}
830
831DEFUN(cfg_trunk_patch_rtp_ts,
832 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200833 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200834{
835 struct mgcp_trunk_config *trunk = vty->index;
836 trunk->force_aligned_timing = 1;
837 return CMD_SUCCESS;
838}
839
840DEFUN(cfg_trunk_no_patch_rtp_ts,
841 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200842 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200843{
844 struct mgcp_trunk_config *trunk = vty->index;
845 trunk->force_aligned_timing = 0;
846 return CMD_SUCCESS;
847}
848
849DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200850 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200851{
852 struct mgcp_trunk_config *trunk = vty->index;
853 trunk->force_constant_ssrc = 0;
854 trunk->force_aligned_timing = 0;
855 return CMD_SUCCESS;
856}
857
858DEFUN(cfg_trunk_rtp_keepalive,
859 cfg_trunk_rtp_keepalive_cmd,
860 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200861 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200862{
863 struct mgcp_trunk_config *trunk = vty->index;
864 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
865 return CMD_SUCCESS;
866}
867
868DEFUN(cfg_trunk_rtp_keepalive_once,
869 cfg_trunk_rtp_keepalive_once_cmd,
870 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200871 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200872{
873 struct mgcp_trunk_config *trunk = vty->index;
874 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
875 return CMD_SUCCESS;
876}
877
878DEFUN(cfg_trunk_no_rtp_keepalive,
879 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200880 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200881{
882 struct mgcp_trunk_config *trunk = vty->index;
883 mgcp_trunk_set_keepalive(trunk, 0);
884 return CMD_SUCCESS;
885}
886
887DEFUN(cfg_trunk_allow_transcoding,
888 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200889 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200890{
891 struct mgcp_trunk_config *trunk = vty->index;
892 trunk->no_audio_transcoding = 0;
893 return CMD_SUCCESS;
894}
895
896DEFUN(cfg_trunk_no_allow_transcoding,
897 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200898 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200899{
900 struct mgcp_trunk_config *trunk = vty->index;
901 trunk->no_audio_transcoding = 1;
902 return CMD_SUCCESS;
903}
904
Philipp Maier87bd9be2017-08-22 16:35:41 +0200905DEFUN(loop_conn,
906 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200907 "loop-endpoint <0-64> NAME (0|1)",
908 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200909 "The name in hex of the endpoint\n" "Disable the loop\n"
910 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200911{
912 struct mgcp_trunk_config *trunk;
913 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200914 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200915
916 trunk = find_trunk(g_cfg, atoi(argv[0]));
917 if (!trunk) {
918 vty_out(vty, "%%Trunk %d not found in the config.%s",
919 atoi(argv[0]), VTY_NEWLINE);
920 return CMD_WARNING;
921 }
922
923 if (!trunk->endpoints) {
924 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
925 trunk->trunk_nr, VTY_NEWLINE);
926 return CMD_WARNING;
927 }
928
929 int endp_no = strtoul(argv[1], NULL, 16);
930 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
931 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200932 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200933 return CMD_WARNING;
934 }
935
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200936 endp = &trunk->endpoints[endp_no];
937 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200938 llist_for_each_entry(conn, &endp->conns, entry) {
939 if (conn->type == MGCP_CONN_TYPE_RTP)
940 /* Handle it like a MDCX, switch on SSRC patching if enabled */
941 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
942 else {
943 /* FIXME: Introduce support for other connection (E1)
944 * types when implementation is available */
945 vty_out(vty, "%%Can't enable SSRC patching,"
946 "connection %s is not an RTP connection.%s",
947 mgcp_conn_dump(conn), VTY_NEWLINE);
948 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200949
Philipp Maier87bd9be2017-08-22 16:35:41 +0200950 if (loop)
951 conn->mode = MGCP_CONN_LOOPBACK;
952 else
953 conn->mode = conn->mode_orig;
954 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200955
956 return CMD_SUCCESS;
957}
958
Philipp Maier87bd9be2017-08-22 16:35:41 +0200959DEFUN(tap_rtp,
960 tap_rtp_cmd,
961 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200962 "Forward data on endpoint to a different system\n" "Trunk number\n"
963 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200964 "The connection id in hex\n"
965 "Forward incoming data\n"
966 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200967 "destination IP of the data\n" "destination port\n")
968{
969 struct mgcp_rtp_tap *tap;
970 struct mgcp_trunk_config *trunk;
971 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200972 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +0100973 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200974
975 trunk = find_trunk(g_cfg, atoi(argv[0]));
976 if (!trunk) {
977 vty_out(vty, "%%Trunk %d not found in the config.%s",
978 atoi(argv[0]), VTY_NEWLINE);
979 return CMD_WARNING;
980 }
981
982 if (!trunk->endpoints) {
983 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
984 trunk->trunk_nr, VTY_NEWLINE);
985 return CMD_WARNING;
986 }
987
988 int endp_no = strtoul(argv[1], NULL, 16);
989 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
990 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200991 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200992 return CMD_WARNING;
993 }
994
995 endp = &trunk->endpoints[endp_no];
996
Philipp Maier01d24a32017-11-21 17:26:09 +0100997 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +0200998 conn = mgcp_conn_get_rtp(endp, conn_id);
999 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001000 vty_out(vty, "Conn ID %s is invalid.%s",
1001 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001002 return CMD_WARNING;
1003 }
1004
1005 if (strcmp(argv[3], "in") == 0)
1006 tap = &conn->tap_in;
1007 else if (strcmp(argv[3], "out") == 0)
1008 tap = &conn->tap_out;
1009 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001010 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1011 return CMD_WARNING;
1012 }
1013
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001014 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001015 inet_aton(argv[4], &tap->forward.sin_addr);
1016 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001017 tap->enabled = 1;
1018 return CMD_SUCCESS;
1019}
1020
1021DEFUN(free_endp, free_endp_cmd,
1022 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001023 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001024{
1025 struct mgcp_trunk_config *trunk;
1026 struct mgcp_endpoint *endp;
1027
1028 trunk = find_trunk(g_cfg, atoi(argv[0]));
1029 if (!trunk) {
1030 vty_out(vty, "%%Trunk %d not found in the config.%s",
1031 atoi(argv[0]), VTY_NEWLINE);
1032 return CMD_WARNING;
1033 }
1034
1035 if (!trunk->endpoints) {
1036 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1037 trunk->trunk_nr, VTY_NEWLINE);
1038 return CMD_WARNING;
1039 }
1040
1041 int endp_no = strtoul(argv[1], NULL, 16);
1042 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1043 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001044 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001045 return CMD_WARNING;
1046 }
1047
1048 endp = &trunk->endpoints[endp_no];
1049 mgcp_release_endp(endp);
1050 return CMD_SUCCESS;
1051}
1052
1053DEFUN(reset_endp, reset_endp_cmd,
1054 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001055 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001056{
1057 struct mgcp_trunk_config *trunk;
1058 struct mgcp_endpoint *endp;
1059 int endp_no, rc;
1060
1061 trunk = find_trunk(g_cfg, atoi(argv[0]));
1062 if (!trunk) {
1063 vty_out(vty, "%%Trunk %d not found in the config.%s",
1064 atoi(argv[0]), VTY_NEWLINE);
1065 return CMD_WARNING;
1066 }
1067
1068 if (!trunk->endpoints) {
1069 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1070 trunk->trunk_nr, VTY_NEWLINE);
1071 return CMD_WARNING;
1072 }
1073
1074 endp_no = strtoul(argv[1], NULL, 16);
1075 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1076 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001077 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001078 return CMD_WARNING;
1079 }
1080
1081 endp = &trunk->endpoints[endp_no];
1082 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1083 if (rc < 0) {
1084 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1085 return CMD_WARNING;
1086 }
1087 return CMD_SUCCESS;
1088}
1089
1090DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001091 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001092{
1093 int rc;
1094
1095 rc = mgcp_send_reset_all(g_cfg);
1096 if (rc < 0) {
1097 vty_out(vty, "Error %d during endpoint reset.%s",
1098 rc, VTY_NEWLINE);
1099 return CMD_WARNING;
1100 }
1101 return CMD_SUCCESS;
1102}
1103
1104#define OSMUX_STR "RTP multiplexing\n"
1105DEFUN(cfg_mgcp_osmux,
1106 cfg_mgcp_osmux_cmd,
1107 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001108 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001109{
1110 if (strcmp(argv[0], "off") == 0) {
1111 g_cfg->osmux = OSMUX_USAGE_OFF;
1112 return CMD_SUCCESS;
1113 }
1114
Philipp Maier87bd9be2017-08-22 16:35:41 +02001115 /* Since OSMUX support is not finished, we do not
1116 * allow to turn it on yet. */
1117 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1118 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001119#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001120 if (strcmp(argv[0], "on") == 0)
1121 g_cfg->osmux = OSMUX_USAGE_ON;
1122 else if (strcmp(argv[0], "only") == 0)
1123 g_cfg->osmux = OSMUX_USAGE_ONLY;
1124
1125 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001126 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001127 return CMD_WARNING;
1128 }
1129
1130 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001131#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001132}
1133
1134DEFUN(cfg_mgcp_osmux_ip,
1135 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001136 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001137{
1138 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1139 return CMD_SUCCESS;
1140}
1141
1142DEFUN(cfg_mgcp_osmux_batch_factor,
1143 cfg_mgcp_osmux_batch_factor_cmd,
1144 "osmux batch-factor <1-8>",
1145 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1146{
1147 g_cfg->osmux_batch = atoi(argv[0]);
1148 return CMD_SUCCESS;
1149}
1150
1151DEFUN(cfg_mgcp_osmux_batch_size,
1152 cfg_mgcp_osmux_batch_size_cmd,
1153 "osmux batch-size <1-65535>",
1154 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1155{
1156 g_cfg->osmux_batch_size = atoi(argv[0]);
1157 return CMD_SUCCESS;
1158}
1159
1160DEFUN(cfg_mgcp_osmux_port,
1161 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001162 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001163{
1164 g_cfg->osmux_port = atoi(argv[0]);
1165 return CMD_SUCCESS;
1166}
1167
1168DEFUN(cfg_mgcp_osmux_dummy,
1169 cfg_mgcp_osmux_dummy_cmd,
1170 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001171 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1172 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001173{
1174 if (strcmp(argv[0], "on") == 0)
1175 g_cfg->osmux_dummy = 1;
1176 else if (strcmp(argv[0], "off") == 0)
1177 g_cfg->osmux_dummy = 0;
1178
1179 return CMD_SUCCESS;
1180}
1181
1182int mgcp_vty_init(void)
1183{
1184 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001185 install_element(ENABLE_NODE, &loop_conn_cmd);
1186 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001187 install_element(ENABLE_NODE, &free_endp_cmd);
1188 install_element(ENABLE_NODE, &reset_endp_cmd);
1189 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1190
1191 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1192 install_node(&mgcp_node, config_write_mgcp);
1193
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001194 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001195 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1196 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1197 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001198 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001199 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001200 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001201 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001202 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001203 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001204 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1205 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001206 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1207 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1208 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1209 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1210 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1211 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1212 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1213 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1214 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001215 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1216 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1217 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1218 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1219 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1220 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001221 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001222 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1223 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1224 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1225 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1226 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1227 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1228 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1229 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1230 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1231 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1232 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1233 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1234 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1235 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1236 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1237 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1238 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1239 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1240 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1241 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1242 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
1243
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001244 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1245 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001246 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1247 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1248 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1249 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1250 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1251 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1252 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1253 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1254 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1255 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1256 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1257 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1258 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1259 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1260 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1261 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1262 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1263 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1264 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1265 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1266 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1267 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1268
1269 return 0;
1270}
1271
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001272int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1273 enum mgcp_role role)
1274{
1275 int rc;
1276 struct mgcp_trunk_config *trunk;
1277
1278 cfg->osmux_port = OSMUX_PORT;
1279 cfg->osmux_batch = 4;
1280 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1281
1282 g_cfg = cfg;
1283 rc = vty_read_config_file(config_file, NULL);
1284 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001285 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1286 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001287 return rc;
1288 }
1289
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001290 if (!g_cfg->source_addr) {
1291 fprintf(stderr, "You need to specify a bind address.\n");
1292 return -1;
1293 }
1294
Philipp Maier48454982017-11-10 16:46:41 +01001295 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001296 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001297 "Failed to initialize the virtual trunk (%d endpoints)\n",
1298 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001299 return -1;
1300 }
1301
1302 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001303 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001304 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001305 "Failed to initialize trunk %d (%d endpoints)\n",
1306 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001307 return -1;
1308 }
1309 }
1310 cfg->role = role;
1311
1312 return 0;
1313}