blob: 7043527c3d588e305cb6afc7b78094275f90aa25 [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);
Philipp Maier12943ea2018-01-17 15:40:25 +010066 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020067 if (g_cfg->local_ip)
68 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020069 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
70 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Philipp Maierf1889d82017-11-08 14:59:39 +010071 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020072 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
73 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020074 if (g_cfg->net_ports.bind_addr)
Philipp Maierf1889d82017-11-08 14:59:39 +010075 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020076 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010077 if (g_cfg->net_ports.bind_addr_probe)
78 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
79 else
80 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020081 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
82 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
83 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
84 else if (g_cfg->trunk.keepalive_interval)
85 vty_out(vty, " rtp keep-alive %d%s",
86 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
87 else
88 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
89
90 if (g_cfg->trunk.omit_rtcp)
91 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
92 else
93 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020094 if (g_cfg->trunk.force_constant_ssrc
95 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020096 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020097 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
98 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020099 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200100 g_cfg->trunk.force_aligned_timing ? "" : "no ",
101 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200102 } else
103 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
104 if (g_cfg->trunk.audio_payload != -1)
105 vty_out(vty, " sdp audio-payload number %d%s",
106 g_cfg->trunk.audio_payload, VTY_NEWLINE);
107 if (g_cfg->trunk.audio_name)
108 vty_out(vty, " sdp audio-payload name %s%s",
109 g_cfg->trunk.audio_name, VTY_NEWLINE);
110 if (g_cfg->trunk.audio_fmtp_extra)
111 vty_out(vty, " sdp audio fmtp-extra %s%s",
112 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
113 vty_out(vty, " %ssdp audio-payload send-ptime%s",
114 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
115 vty_out(vty, " %ssdp audio-payload send-name%s",
116 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200117 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
118 vty_out(vty, " number endpoints %u%s",
Philipp Maierfcd06552017-11-10 17:32:22 +0100119 g_cfg->trunk.vty_number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200120 vty_out(vty, " %sallow-transcoding%s",
121 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
122 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200123 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
124 VTY_NEWLINE);
125 if (g_cfg->force_ptime > 0)
126 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
127 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200128
129 switch (g_cfg->osmux) {
130 case OSMUX_USAGE_ON:
131 vty_out(vty, " osmux on%s", VTY_NEWLINE);
132 break;
133 case OSMUX_USAGE_ONLY:
134 vty_out(vty, " osmux only%s", VTY_NEWLINE);
135 break;
136 case OSMUX_USAGE_OFF:
137 default:
138 vty_out(vty, " osmux off%s", VTY_NEWLINE);
139 break;
140 }
141 if (g_cfg->osmux) {
142 vty_out(vty, " osmux bind-ip %s%s",
143 g_cfg->osmux_addr, VTY_NEWLINE);
144 vty_out(vty, " osmux batch-factor %d%s",
145 g_cfg->osmux_batch, VTY_NEWLINE);
146 vty_out(vty, " osmux batch-size %u%s",
147 g_cfg->osmux_batch_size, VTY_NEWLINE);
148 vty_out(vty, " osmux port %u%s",
149 g_cfg->osmux_port, VTY_NEWLINE);
150 vty_out(vty, " osmux dummy %s%s",
151 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
152 }
153 return CMD_SUCCESS;
154}
155
Philipp Maier87bd9be2017-08-22 16:35:41 +0200156static void dump_rtp_end(struct vty *vty, struct mgcp_rtp_state *state,
157 struct mgcp_rtp_end *end)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200158{
159 struct mgcp_rtp_codec *codec = &end->codec;
160
161 vty_out(vty,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200162 " Timestamp Errs: %d->%d%s"
163 " Dropped Packets: %d%s"
164 " Payload Type: %d Rate: %u Channels: %d %s"
165 " Frame Duration: %u Frame Denominator: %u%s"
166 " FPP: %d Packet Duration: %u%s"
167 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
168 " Output-Enabled: %d Force-PTIME: %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200169 state->in_stream.err_ts_counter,
170 state->out_stream.err_ts_counter, VTY_NEWLINE,
Harald Weltea0ac30f2017-12-25 09:52:30 +0100171 end->stats.dropped_packets, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200172 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200173 codec->frame_duration_num, codec->frame_duration_den,
174 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
175 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
176 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
177 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200178}
179
Philipp Maier87bd9be2017-08-22 16:35:41 +0200180static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
181 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200182{
183 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200184 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200185
186 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
187 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
188 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
189
190 if (!cfg->endpoints) {
191 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
192 return;
193 }
194
195 for (i = 1; i < cfg->number_endpoints; ++i) {
196 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200197
Philipp Maier87bd9be2017-08-22 16:35:41 +0200198 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
199
200 llist_for_each_entry(conn, &endp->conns, entry) {
201 vty_out(vty, " CONN: %s%s",
202 mgcp_conn_dump(conn), VTY_NEWLINE);
203
204 if (verbose) {
205 /* FIXME: Also add verbosity for other
206 * connection types (E1) as soon as
207 * the implementation is available */
208 if (conn->type == MGCP_CONN_TYPE_RTP) {
209 dump_rtp_end(vty, &conn->u.rtp.state,
210 &conn->u.rtp.end);
211 }
212 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200213 }
214 }
215}
216
217DEFUN(show_mcgp, show_mgcp_cmd,
218 "show mgcp [stats]",
219 SHOW_STR
220 "Display information about the MGCP Media Gateway\n"
221 "Include Statistics\n")
222{
223 struct mgcp_trunk_config *trunk;
224 int show_stats = argc >= 1;
225
226 dump_trunk(vty, &g_cfg->trunk, show_stats);
227
228 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200229 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200230
231 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200232 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
233 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200234
235 return CMD_SUCCESS;
236}
237
Philipp Maier87bd9be2017-08-22 16:35:41 +0200238DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200239{
240 vty->node = MGCP_NODE;
241 return CMD_SUCCESS;
242}
243
244DEFUN(cfg_mgcp_local_ip,
245 cfg_mgcp_local_ip_cmd,
246 "local ip A.B.C.D",
247 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200248 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200249{
250 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
251 return CMD_SUCCESS;
252}
253
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200254#define BIND_STR "Listen/Bind related socket option\n"
255DEFUN(cfg_mgcp_bind_ip,
256 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200257 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200258{
259 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
260 return CMD_SUCCESS;
261}
262
263DEFUN(cfg_mgcp_bind_port,
264 cfg_mgcp_bind_port_cmd,
265 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200266 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200267{
268 unsigned int port = atoi(argv[0]);
269 g_cfg->source_port = port;
270 return CMD_SUCCESS;
271}
272
273DEFUN(cfg_mgcp_bind_early,
274 cfg_mgcp_bind_early_cmd,
275 "bind early (0|1)",
276 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200277 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200278{
279 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
280 return CMD_WARNING;
281}
282
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200283static void parse_range(struct mgcp_port_range *range, const char **argv)
284{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200285 range->range_start = atoi(argv[0]);
286 range->range_end = atoi(argv[1]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200287 range->last_port = g_cfg->net_ports.range_start;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200288}
289
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200290#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200291#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200292#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200293#define RANGE_START_STR "Start of the range of ports\n"
294#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200295
Philipp Maierf1889d82017-11-08 14:59:39 +0100296DEFUN(cfg_mgcp_rtp_port_range,
297 cfg_mgcp_rtp_port_range_cmd,
298 "rtp port-range <0-65534> <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200299 RTP_STR "Range of ports to use for the NET side\n"
300 RANGE_START_STR RANGE_END_STR)
301{
302 parse_range(&g_cfg->net_ports, argv);
303 return CMD_SUCCESS;
304}
Philipp Maierf1889d82017-11-08 14:59:39 +0100305ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
306 cfg_mgcp_rtp_net_range_cmd,
307 "rtp net-range <0-65534> <0-65534>",
308 RTP_STR "Range of ports to use for the NET side\n"
309 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200310
Philipp Maierf1889d82017-11-08 14:59:39 +0100311DEFUN(cfg_mgcp_rtp_bind_ip,
312 cfg_mgcp_rtp_bind_ip_cmd,
313 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200314 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
315{
316 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
317 return CMD_SUCCESS;
318}
Philipp Maierf1889d82017-11-08 14:59:39 +0100319ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
320 cfg_mgcp_rtp_net_bind_ip_cmd,
321 "rtp net-bind-ip A.B.C.D",
322 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200323
Philipp Maierf1889d82017-11-08 14:59:39 +0100324DEFUN(cfg_mgcp_rtp_no_bind_ip,
325 cfg_mgcp_rtp_no_bind_ip_cmd,
326 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200327 NO_STR RTP_STR "Bind endpoints facing the Network\n"
328 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200329{
330 talloc_free(g_cfg->net_ports.bind_addr);
331 g_cfg->net_ports.bind_addr = NULL;
332 return CMD_SUCCESS;
333}
Philipp Maierf1889d82017-11-08 14:59:39 +0100334ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
335 cfg_mgcp_rtp_no_net_bind_ip_cmd,
336 "no rtp net-bind-ip",
337 NO_STR RTP_STR "Bind endpoints facing the Network\n"
338 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200339
Philipp Maier1cb1e382017-11-02 17:16:04 +0100340DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
341 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
342 "rtp ip-probing",
343 RTP_STR "automatic rtp bind ip selection\n")
344{
345 g_cfg->net_ports.bind_addr_probe = true;
346 return CMD_SUCCESS;
347}
348
349DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
350 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
351 "no rtp ip-probing",
352 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
353{
354 g_cfg->net_ports.bind_addr_probe = false;
355 return CMD_SUCCESS;
356}
357
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200358DEFUN(cfg_mgcp_rtp_ip_dscp,
359 cfg_mgcp_rtp_ip_dscp_cmd,
360 "rtp ip-dscp <0-255>",
361 RTP_STR
362 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
363{
364 int dscp = atoi(argv[0]);
365 g_cfg->endp_dscp = dscp;
366 return CMD_SUCCESS;
367}
368
369ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200370 "rtp ip-tos <0-255>",
371 RTP_STR
372 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
373#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
374 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200375 cfg_mgcp_rtp_force_ptime_cmd,
376 "rtp force-ptime (10|20|40)",
377 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200378 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200379{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200380 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200381 return CMD_SUCCESS;
382}
383
384DEFUN(cfg_mgcp_no_rtp_force_ptime,
385 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200386 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200387{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200388 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200389 return CMD_SUCCESS;
390}
391
392DEFUN(cfg_mgcp_sdp_fmtp_extra,
393 cfg_mgcp_sdp_fmtp_extra_cmd,
394 "sdp audio fmtp-extra .NAME",
395 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
396 "Extra Information\n")
397{
398 char *txt = argv_concat(argv, argc, 0);
399 if (!txt)
400 return CMD_WARNING;
401
402 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
403 talloc_free(txt);
404 return CMD_SUCCESS;
405}
406
407DEFUN(cfg_mgcp_allow_transcoding,
408 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200409 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200410{
411 g_cfg->trunk.no_audio_transcoding = 0;
412 return CMD_SUCCESS;
413}
414
415DEFUN(cfg_mgcp_no_allow_transcoding,
416 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200417 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200418{
419 g_cfg->trunk.no_audio_transcoding = 1;
420 return CMD_SUCCESS;
421}
422
423#define SDP_STR "SDP File related options\n"
424#define AUDIO_STR "Audio payload options\n"
425DEFUN(cfg_mgcp_sdp_payload_number,
426 cfg_mgcp_sdp_payload_number_cmd,
427 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200428 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200429{
430 unsigned int payload = atoi(argv[0]);
431 g_cfg->trunk.audio_payload = payload;
432 return CMD_SUCCESS;
433}
434
Philipp Maier87bd9be2017-08-22 16:35:41 +0200435ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
436 cfg_mgcp_sdp_payload_number_cmd_old,
437 "sdp audio payload number <0-255>",
438 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200439
Philipp Maier87bd9be2017-08-22 16:35:41 +0200440 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200441 cfg_mgcp_sdp_payload_name_cmd,
442 "sdp audio-payload name NAME",
443 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
444{
445 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
446 return CMD_SUCCESS;
447}
448
449ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200450 "sdp audio payload name NAME",
451 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200452
Philipp Maier87bd9be2017-08-22 16:35:41 +0200453 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200454 cfg_mgcp_sdp_payload_send_ptime_cmd,
455 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200456 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200457{
458 g_cfg->trunk.audio_send_ptime = 1;
459 return CMD_SUCCESS;
460}
461
462DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
463 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
464 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200465 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200466{
467 g_cfg->trunk.audio_send_ptime = 0;
468 return CMD_SUCCESS;
469}
470
471DEFUN(cfg_mgcp_sdp_payload_send_name,
472 cfg_mgcp_sdp_payload_send_name_cmd,
473 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200474 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200475{
476 g_cfg->trunk.audio_send_name = 1;
477 return CMD_SUCCESS;
478}
479
480DEFUN(cfg_mgcp_no_sdp_payload_send_name,
481 cfg_mgcp_no_sdp_payload_send_name_cmd,
482 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200483 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200484{
485 g_cfg->trunk.audio_send_name = 0;
486 return CMD_SUCCESS;
487}
488
489DEFUN(cfg_mgcp_loop,
490 cfg_mgcp_loop_cmd,
491 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200492 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200493{
494 if (g_cfg->osmux) {
495 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
496 return CMD_WARNING;
497 }
498 g_cfg->trunk.audio_loop = atoi(argv[0]);
499 return CMD_SUCCESS;
500}
501
502DEFUN(cfg_mgcp_force_realloc,
503 cfg_mgcp_force_realloc_cmd,
504 "force-realloc (0|1)",
505 "Force endpoint reallocation when the endpoint is still seized\n"
506 "Don't force reallocation\n" "force reallocation\n")
507{
508 g_cfg->trunk.force_realloc = atoi(argv[0]);
509 return CMD_SUCCESS;
510}
511
Philipp Maier87bd9be2017-08-22 16:35:41 +0200512DEFUN(cfg_mgcp_rtp_accept_all,
513 cfg_mgcp_rtp_accept_all_cmd,
514 "rtp-accept-all (0|1)",
515 "Accept all RTP packets, even when the originating IP/Port does not match\n"
516 "enable filter\n" "disable filter\n")
517{
518 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
519 return CMD_SUCCESS;
520}
521
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200522DEFUN(cfg_mgcp_number_endp,
523 cfg_mgcp_number_endp_cmd,
524 "number endpoints <0-65534>",
525 "Number options\n" "Endpoints available\n" "Number endpoints\n")
526{
527 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100528 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200529 return CMD_SUCCESS;
530}
531
Philipp Maier87bd9be2017-08-22 16:35:41 +0200532DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200533{
534 g_cfg->trunk.omit_rtcp = 1;
535 return CMD_SUCCESS;
536}
537
538DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200539 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200540{
541 g_cfg->trunk.omit_rtcp = 0;
542 return CMD_SUCCESS;
543}
544
545DEFUN(cfg_mgcp_patch_rtp_ssrc,
546 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200547 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200548{
549 g_cfg->trunk.force_constant_ssrc = 1;
550 return CMD_SUCCESS;
551}
552
553DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
554 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200555 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200556{
557 g_cfg->trunk.force_constant_ssrc = 0;
558 return CMD_SUCCESS;
559}
560
561DEFUN(cfg_mgcp_patch_rtp_ts,
562 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200563 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200564{
565 g_cfg->trunk.force_aligned_timing = 1;
566 return CMD_SUCCESS;
567}
568
569DEFUN(cfg_mgcp_no_patch_rtp_ts,
570 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200571 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200572{
573 g_cfg->trunk.force_aligned_timing = 0;
574 return CMD_SUCCESS;
575}
576
577DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200578 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200579{
580 g_cfg->trunk.force_constant_ssrc = 0;
581 g_cfg->trunk.force_aligned_timing = 0;
582 return CMD_SUCCESS;
583}
584
585DEFUN(cfg_mgcp_rtp_keepalive,
586 cfg_mgcp_rtp_keepalive_cmd,
587 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200588 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200589{
590 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
591 return CMD_SUCCESS;
592}
593
594DEFUN(cfg_mgcp_rtp_keepalive_once,
595 cfg_mgcp_rtp_keepalive_once_cmd,
596 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200597 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200598{
599 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
600 return CMD_SUCCESS;
601}
602
603DEFUN(cfg_mgcp_no_rtp_keepalive,
604 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200605 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200606{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100607 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200608 return CMD_SUCCESS;
609}
610
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200611#define CALL_AGENT_STR "Callagent information\n"
612DEFUN(cfg_mgcp_agent_addr,
613 cfg_mgcp_agent_addr_cmd,
614 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200615 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200616{
617 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
618 return CMD_SUCCESS;
619}
620
621ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200622 "call agent ip A.B.C.D",
623 CALL_AGENT_STR CALL_AGENT_STR IP_STR
624 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200625
Philipp Maier87bd9be2017-08-22 16:35:41 +0200626 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
627 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200628{
629 struct mgcp_trunk_config *trunk;
630 int index = atoi(argv[0]);
631
632 trunk = mgcp_trunk_num(g_cfg, index);
633 if (!trunk)
634 trunk = mgcp_trunk_alloc(g_cfg, index);
635
636 if (!trunk) {
637 vty_out(vty, "%%Unable to allocate trunk %u.%s",
638 index, VTY_NEWLINE);
639 return CMD_WARNING;
640 }
641
642 vty->node = TRUNK_NODE;
643 vty->index = trunk;
644 return CMD_SUCCESS;
645}
646
647static int config_write_trunk(struct vty *vty)
648{
649 struct mgcp_trunk_config *trunk;
650
651 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
652 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
653 vty_out(vty, " sdp audio-payload number %d%s",
654 trunk->audio_payload, VTY_NEWLINE);
655 vty_out(vty, " sdp audio-payload name %s%s",
656 trunk->audio_name, VTY_NEWLINE);
657 vty_out(vty, " %ssdp audio-payload send-ptime%s",
658 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
659 vty_out(vty, " %ssdp audio-payload send-name%s",
660 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
661
662 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
663 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
664 else if (trunk->keepalive_interval)
665 vty_out(vty, " rtp keep-alive %d%s",
666 trunk->keepalive_interval, VTY_NEWLINE);
667 else
668 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200669 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200670 vty_out(vty, " force-realloc %d%s",
671 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200672 vty_out(vty, " rtp-accept-all %d%s",
673 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200674 if (trunk->omit_rtcp)
675 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
676 else
677 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
678 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
679 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200680 trunk->force_constant_ssrc ? "" : "no ",
681 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200682 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200683 trunk->force_aligned_timing ? "" : "no ",
684 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200685 } else
686 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
687 if (trunk->audio_fmtp_extra)
688 vty_out(vty, " sdp audio fmtp-extra %s%s",
689 trunk->audio_fmtp_extra, VTY_NEWLINE);
690 vty_out(vty, " %sallow-transcoding%s",
691 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
692 }
693
694 return CMD_SUCCESS;
695}
696
697DEFUN(cfg_trunk_sdp_fmtp_extra,
698 cfg_trunk_sdp_fmtp_extra_cmd,
699 "sdp audio fmtp-extra .NAME",
700 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
701 "Extra Information\n")
702{
703 struct mgcp_trunk_config *trunk = vty->index;
704 char *txt = argv_concat(argv, argc, 0);
705 if (!txt)
706 return CMD_WARNING;
707
708 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
709 talloc_free(txt);
710 return CMD_SUCCESS;
711}
712
713DEFUN(cfg_trunk_payload_number,
714 cfg_trunk_payload_number_cmd,
715 "sdp audio-payload number <0-255>",
716 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
717{
718 struct mgcp_trunk_config *trunk = vty->index;
719 unsigned int payload = atoi(argv[0]);
720
721 trunk->audio_payload = payload;
722 return CMD_SUCCESS;
723}
724
725ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200726 "sdp audio payload number <0-255>",
727 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200728
Philipp Maier87bd9be2017-08-22 16:35:41 +0200729 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730 cfg_trunk_payload_name_cmd,
731 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200732 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200733{
734 struct mgcp_trunk_config *trunk = vty->index;
735
736 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
737 return CMD_SUCCESS;
738}
739
740ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200741 "sdp audio payload name NAME",
742 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200743
Philipp Maier87bd9be2017-08-22 16:35:41 +0200744 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200745 cfg_trunk_loop_cmd,
746 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200747 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200748{
749 struct mgcp_trunk_config *trunk = vty->index;
750
751 if (g_cfg->osmux) {
752 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
753 return CMD_WARNING;
754 }
755 trunk->audio_loop = atoi(argv[0]);
756 return CMD_SUCCESS;
757}
758
759DEFUN(cfg_trunk_sdp_payload_send_ptime,
760 cfg_trunk_sdp_payload_send_ptime_cmd,
761 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200762 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200763{
764 struct mgcp_trunk_config *trunk = vty->index;
765 trunk->audio_send_ptime = 1;
766 return CMD_SUCCESS;
767}
768
769DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
770 cfg_trunk_no_sdp_payload_send_ptime_cmd,
771 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200772 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200773{
774 struct mgcp_trunk_config *trunk = vty->index;
775 trunk->audio_send_ptime = 0;
776 return CMD_SUCCESS;
777}
778
779DEFUN(cfg_trunk_sdp_payload_send_name,
780 cfg_trunk_sdp_payload_send_name_cmd,
781 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200782 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200783{
784 struct mgcp_trunk_config *trunk = vty->index;
785 trunk->audio_send_name = 1;
786 return CMD_SUCCESS;
787}
788
789DEFUN(cfg_trunk_no_sdp_payload_send_name,
790 cfg_trunk_no_sdp_payload_send_name_cmd,
791 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200792 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200793{
794 struct mgcp_trunk_config *trunk = vty->index;
795 trunk->audio_send_name = 0;
796 return CMD_SUCCESS;
797}
798
Philipp Maier87bd9be2017-08-22 16:35:41 +0200799DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200800{
801 struct mgcp_trunk_config *trunk = vty->index;
802 trunk->omit_rtcp = 1;
803 return CMD_SUCCESS;
804}
805
806DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200807 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200808{
809 struct mgcp_trunk_config *trunk = vty->index;
810 trunk->omit_rtcp = 0;
811 return CMD_SUCCESS;
812}
813
814DEFUN(cfg_trunk_patch_rtp_ssrc,
815 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200816 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200817{
818 struct mgcp_trunk_config *trunk = vty->index;
819 trunk->force_constant_ssrc = 1;
820 return CMD_SUCCESS;
821}
822
823DEFUN(cfg_trunk_no_patch_rtp_ssrc,
824 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200825 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200826{
827 struct mgcp_trunk_config *trunk = vty->index;
828 trunk->force_constant_ssrc = 0;
829 return CMD_SUCCESS;
830}
831
832DEFUN(cfg_trunk_patch_rtp_ts,
833 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200834 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200835{
836 struct mgcp_trunk_config *trunk = vty->index;
837 trunk->force_aligned_timing = 1;
838 return CMD_SUCCESS;
839}
840
841DEFUN(cfg_trunk_no_patch_rtp_ts,
842 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200843 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200844{
845 struct mgcp_trunk_config *trunk = vty->index;
846 trunk->force_aligned_timing = 0;
847 return CMD_SUCCESS;
848}
849
850DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200851 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200852{
853 struct mgcp_trunk_config *trunk = vty->index;
854 trunk->force_constant_ssrc = 0;
855 trunk->force_aligned_timing = 0;
856 return CMD_SUCCESS;
857}
858
859DEFUN(cfg_trunk_rtp_keepalive,
860 cfg_trunk_rtp_keepalive_cmd,
861 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200862 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200863{
864 struct mgcp_trunk_config *trunk = vty->index;
865 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
866 return CMD_SUCCESS;
867}
868
869DEFUN(cfg_trunk_rtp_keepalive_once,
870 cfg_trunk_rtp_keepalive_once_cmd,
871 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200872 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200873{
874 struct mgcp_trunk_config *trunk = vty->index;
875 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
876 return CMD_SUCCESS;
877}
878
879DEFUN(cfg_trunk_no_rtp_keepalive,
880 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200881 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200882{
883 struct mgcp_trunk_config *trunk = vty->index;
884 mgcp_trunk_set_keepalive(trunk, 0);
885 return CMD_SUCCESS;
886}
887
888DEFUN(cfg_trunk_allow_transcoding,
889 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200890 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200891{
892 struct mgcp_trunk_config *trunk = vty->index;
893 trunk->no_audio_transcoding = 0;
894 return CMD_SUCCESS;
895}
896
897DEFUN(cfg_trunk_no_allow_transcoding,
898 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200899 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200900{
901 struct mgcp_trunk_config *trunk = vty->index;
902 trunk->no_audio_transcoding = 1;
903 return CMD_SUCCESS;
904}
905
Philipp Maier87bd9be2017-08-22 16:35:41 +0200906DEFUN(loop_conn,
907 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200908 "loop-endpoint <0-64> NAME (0|1)",
909 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200910 "The name in hex of the endpoint\n" "Disable the loop\n"
911 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200912{
913 struct mgcp_trunk_config *trunk;
914 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200915 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200916
917 trunk = find_trunk(g_cfg, atoi(argv[0]));
918 if (!trunk) {
919 vty_out(vty, "%%Trunk %d not found in the config.%s",
920 atoi(argv[0]), VTY_NEWLINE);
921 return CMD_WARNING;
922 }
923
924 if (!trunk->endpoints) {
925 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
926 trunk->trunk_nr, VTY_NEWLINE);
927 return CMD_WARNING;
928 }
929
930 int endp_no = strtoul(argv[1], NULL, 16);
931 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
932 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200933 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200934 return CMD_WARNING;
935 }
936
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200937 endp = &trunk->endpoints[endp_no];
938 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200939 llist_for_each_entry(conn, &endp->conns, entry) {
940 if (conn->type == MGCP_CONN_TYPE_RTP)
941 /* Handle it like a MDCX, switch on SSRC patching if enabled */
942 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
943 else {
944 /* FIXME: Introduce support for other connection (E1)
945 * types when implementation is available */
946 vty_out(vty, "%%Can't enable SSRC patching,"
947 "connection %s is not an RTP connection.%s",
948 mgcp_conn_dump(conn), VTY_NEWLINE);
949 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200950
Philipp Maier87bd9be2017-08-22 16:35:41 +0200951 if (loop)
952 conn->mode = MGCP_CONN_LOOPBACK;
953 else
954 conn->mode = conn->mode_orig;
955 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200956
957 return CMD_SUCCESS;
958}
959
Philipp Maier87bd9be2017-08-22 16:35:41 +0200960DEFUN(tap_rtp,
961 tap_rtp_cmd,
962 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200963 "Forward data on endpoint to a different system\n" "Trunk number\n"
964 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200965 "The connection id in hex\n"
966 "Forward incoming data\n"
967 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200968 "destination IP of the data\n" "destination port\n")
969{
970 struct mgcp_rtp_tap *tap;
971 struct mgcp_trunk_config *trunk;
972 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200973 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +0100974 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200975
976 trunk = find_trunk(g_cfg, atoi(argv[0]));
977 if (!trunk) {
978 vty_out(vty, "%%Trunk %d not found in the config.%s",
979 atoi(argv[0]), VTY_NEWLINE);
980 return CMD_WARNING;
981 }
982
983 if (!trunk->endpoints) {
984 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
985 trunk->trunk_nr, VTY_NEWLINE);
986 return CMD_WARNING;
987 }
988
989 int endp_no = strtoul(argv[1], NULL, 16);
990 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
991 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200992 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200993 return CMD_WARNING;
994 }
995
996 endp = &trunk->endpoints[endp_no];
997
Philipp Maier01d24a32017-11-21 17:26:09 +0100998 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +0200999 conn = mgcp_conn_get_rtp(endp, conn_id);
1000 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001001 vty_out(vty, "Conn ID %s is invalid.%s",
1002 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001003 return CMD_WARNING;
1004 }
1005
1006 if (strcmp(argv[3], "in") == 0)
1007 tap = &conn->tap_in;
1008 else if (strcmp(argv[3], "out") == 0)
1009 tap = &conn->tap_out;
1010 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001011 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1012 return CMD_WARNING;
1013 }
1014
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001015 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001016 inet_aton(argv[4], &tap->forward.sin_addr);
1017 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001018 tap->enabled = 1;
1019 return CMD_SUCCESS;
1020}
1021
1022DEFUN(free_endp, free_endp_cmd,
1023 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001024 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001025{
1026 struct mgcp_trunk_config *trunk;
1027 struct mgcp_endpoint *endp;
1028
1029 trunk = find_trunk(g_cfg, atoi(argv[0]));
1030 if (!trunk) {
1031 vty_out(vty, "%%Trunk %d not found in the config.%s",
1032 atoi(argv[0]), VTY_NEWLINE);
1033 return CMD_WARNING;
1034 }
1035
1036 if (!trunk->endpoints) {
1037 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1038 trunk->trunk_nr, VTY_NEWLINE);
1039 return CMD_WARNING;
1040 }
1041
1042 int endp_no = strtoul(argv[1], NULL, 16);
1043 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1044 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001045 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001046 return CMD_WARNING;
1047 }
1048
1049 endp = &trunk->endpoints[endp_no];
1050 mgcp_release_endp(endp);
1051 return CMD_SUCCESS;
1052}
1053
1054DEFUN(reset_endp, reset_endp_cmd,
1055 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001056 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001057{
1058 struct mgcp_trunk_config *trunk;
1059 struct mgcp_endpoint *endp;
1060 int endp_no, rc;
1061
1062 trunk = find_trunk(g_cfg, atoi(argv[0]));
1063 if (!trunk) {
1064 vty_out(vty, "%%Trunk %d not found in the config.%s",
1065 atoi(argv[0]), VTY_NEWLINE);
1066 return CMD_WARNING;
1067 }
1068
1069 if (!trunk->endpoints) {
1070 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1071 trunk->trunk_nr, VTY_NEWLINE);
1072 return CMD_WARNING;
1073 }
1074
1075 endp_no = strtoul(argv[1], NULL, 16);
1076 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1077 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001078 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001079 return CMD_WARNING;
1080 }
1081
1082 endp = &trunk->endpoints[endp_no];
1083 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1084 if (rc < 0) {
1085 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1086 return CMD_WARNING;
1087 }
1088 return CMD_SUCCESS;
1089}
1090
1091DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001092 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001093{
1094 int rc;
1095
1096 rc = mgcp_send_reset_all(g_cfg);
1097 if (rc < 0) {
1098 vty_out(vty, "Error %d during endpoint reset.%s",
1099 rc, VTY_NEWLINE);
1100 return CMD_WARNING;
1101 }
1102 return CMD_SUCCESS;
1103}
1104
1105#define OSMUX_STR "RTP multiplexing\n"
1106DEFUN(cfg_mgcp_osmux,
1107 cfg_mgcp_osmux_cmd,
1108 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001109 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001110{
1111 if (strcmp(argv[0], "off") == 0) {
1112 g_cfg->osmux = OSMUX_USAGE_OFF;
1113 return CMD_SUCCESS;
1114 }
1115
Philipp Maier87bd9be2017-08-22 16:35:41 +02001116 /* Since OSMUX support is not finished, we do not
1117 * allow to turn it on yet. */
1118 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1119 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001120#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001121 if (strcmp(argv[0], "on") == 0)
1122 g_cfg->osmux = OSMUX_USAGE_ON;
1123 else if (strcmp(argv[0], "only") == 0)
1124 g_cfg->osmux = OSMUX_USAGE_ONLY;
1125
1126 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001127 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001128 return CMD_WARNING;
1129 }
1130
1131 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001132#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001133}
1134
1135DEFUN(cfg_mgcp_osmux_ip,
1136 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001137 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001138{
1139 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1140 return CMD_SUCCESS;
1141}
1142
1143DEFUN(cfg_mgcp_osmux_batch_factor,
1144 cfg_mgcp_osmux_batch_factor_cmd,
1145 "osmux batch-factor <1-8>",
1146 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1147{
1148 g_cfg->osmux_batch = atoi(argv[0]);
1149 return CMD_SUCCESS;
1150}
1151
1152DEFUN(cfg_mgcp_osmux_batch_size,
1153 cfg_mgcp_osmux_batch_size_cmd,
1154 "osmux batch-size <1-65535>",
1155 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1156{
1157 g_cfg->osmux_batch_size = atoi(argv[0]);
1158 return CMD_SUCCESS;
1159}
1160
1161DEFUN(cfg_mgcp_osmux_port,
1162 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001163 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001164{
1165 g_cfg->osmux_port = atoi(argv[0]);
1166 return CMD_SUCCESS;
1167}
1168
1169DEFUN(cfg_mgcp_osmux_dummy,
1170 cfg_mgcp_osmux_dummy_cmd,
1171 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001172 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1173 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001174{
1175 if (strcmp(argv[0], "on") == 0)
1176 g_cfg->osmux_dummy = 1;
1177 else if (strcmp(argv[0], "off") == 0)
1178 g_cfg->osmux_dummy = 0;
1179
1180 return CMD_SUCCESS;
1181}
1182
Philipp Maier12943ea2018-01-17 15:40:25 +01001183DEFUN(cfg_mgcp_domain,
1184 cfg_mgcp_domain_cmd,
1185 "domain NAME", "domain\n" "qualified domain name\n")
1186{
1187 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1188 return CMD_SUCCESS;
1189}
1190
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001191int mgcp_vty_init(void)
1192{
1193 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001194 install_element(ENABLE_NODE, &loop_conn_cmd);
1195 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001196 install_element(ENABLE_NODE, &free_endp_cmd);
1197 install_element(ENABLE_NODE, &reset_endp_cmd);
1198 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1199
1200 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1201 install_node(&mgcp_node, config_write_mgcp);
1202
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001203 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001204 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1205 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1206 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001207 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001208 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001209 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001210 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001211 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001212 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001213 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1214 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001215 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1216 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1217 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1218 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1219 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1220 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1221 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1222 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1223 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001224 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1225 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1226 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1227 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1228 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1229 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001230 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001231 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1232 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1233 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1234 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1235 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1236 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1237 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1238 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1239 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1240 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1241 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1242 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1243 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1244 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1245 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1246 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1247 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1248 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1249 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1250 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1251 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001252 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001253
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001254 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1255 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001256 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1257 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1258 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1259 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1260 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1261 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1262 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1263 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1264 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1265 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1266 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1267 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1268 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1269 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1270 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1271 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1272 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1273 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1274 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1275 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1276 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1277 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1278
1279 return 0;
1280}
1281
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001282int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1283 enum mgcp_role role)
1284{
1285 int rc;
1286 struct mgcp_trunk_config *trunk;
1287
1288 cfg->osmux_port = OSMUX_PORT;
1289 cfg->osmux_batch = 4;
1290 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1291
1292 g_cfg = cfg;
1293 rc = vty_read_config_file(config_file, NULL);
1294 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001295 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1296 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001297 return rc;
1298 }
1299
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001300 if (!g_cfg->source_addr) {
1301 fprintf(stderr, "You need to specify a bind address.\n");
1302 return -1;
1303 }
1304
Philipp Maier48454982017-11-10 16:46:41 +01001305 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001306 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001307 "Failed to initialize the virtual trunk (%d endpoints)\n",
1308 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001309 return -1;
1310 }
1311
1312 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001313 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001314 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001315 "Failed to initialize trunk %d (%d endpoints)\n",
1316 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001317 return -1;
1318 }
1319 }
1320 cfg->role = role;
1321
1322 return 0;
1323}