blob: 14ecd177d92d6e1d12a0d8d05e3f18ed97b9dbb5 [file] [log] [blame]
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
5 * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
6 * (C) 2009-2011 by On-Waves
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020024#include <osmocom/core/talloc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020025#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020026#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020027#include <osmocom/mgcp/mgcp_internal.h>
28#include <osmocom/mgcp/vty.h>
29#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010030#include <osmocom/mgcp/mgcp_endp.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020031
32#include <string.h>
33
34#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
35#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
36#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
37
38static struct mgcp_config *g_cfg = NULL;
39
40static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
41{
42 struct mgcp_trunk_config *trunk;
43
44 if (nr == 0)
45 trunk = &cfg->trunk;
46 else
47 trunk = mgcp_trunk_num(cfg, nr);
48
49 return trunk;
50}
51
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020052struct cmd_node mgcp_node = {
53 MGCP_NODE,
54 "%s(config-mgcp)# ",
55 1,
56};
57
58struct cmd_node trunk_node = {
59 TRUNK_NODE,
60 "%s(config-mgcp-trunk)# ",
61 1,
62};
63
64static int config_write_mgcp(struct vty *vty)
65{
66 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maier12943ea2018-01-17 15:40:25 +010067 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020068 if (g_cfg->local_ip)
69 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020070 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
71 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Philipp Maierf1889d82017-11-08 14:59:39 +010072 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020073 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
74 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020075 if (g_cfg->net_ports.bind_addr)
Philipp Maierf1889d82017-11-08 14:59:39 +010076 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020077 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010078 if (g_cfg->net_ports.bind_addr_probe)
79 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
80 else
81 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020082 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
83 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
84 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
85 else if (g_cfg->trunk.keepalive_interval)
86 vty_out(vty, " rtp keep-alive %d%s",
87 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
88 else
89 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
90
91 if (g_cfg->trunk.omit_rtcp)
92 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
93 else
94 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020095 if (g_cfg->trunk.force_constant_ssrc
96 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020097 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020098 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
99 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200100 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200101 g_cfg->trunk.force_aligned_timing ? "" : "no ",
102 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200103 } else
104 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
105 if (g_cfg->trunk.audio_payload != -1)
106 vty_out(vty, " sdp audio-payload number %d%s",
107 g_cfg->trunk.audio_payload, VTY_NEWLINE);
108 if (g_cfg->trunk.audio_name)
109 vty_out(vty, " sdp audio-payload name %s%s",
110 g_cfg->trunk.audio_name, VTY_NEWLINE);
111 if (g_cfg->trunk.audio_fmtp_extra)
112 vty_out(vty, " sdp audio fmtp-extra %s%s",
113 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
114 vty_out(vty, " %ssdp audio-payload send-ptime%s",
115 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
116 vty_out(vty, " %ssdp audio-payload send-name%s",
117 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200118 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
119 vty_out(vty, " number endpoints %u%s",
Philipp Maierfcd06552017-11-10 17:32:22 +0100120 g_cfg->trunk.vty_number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200121 vty_out(vty, " %sallow-transcoding%s",
122 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
123 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200124 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
125 VTY_NEWLINE);
126 if (g_cfg->force_ptime > 0)
127 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
128 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200129
130 switch (g_cfg->osmux) {
131 case OSMUX_USAGE_ON:
132 vty_out(vty, " osmux on%s", VTY_NEWLINE);
133 break;
134 case OSMUX_USAGE_ONLY:
135 vty_out(vty, " osmux only%s", VTY_NEWLINE);
136 break;
137 case OSMUX_USAGE_OFF:
138 default:
139 vty_out(vty, " osmux off%s", VTY_NEWLINE);
140 break;
141 }
142 if (g_cfg->osmux) {
143 vty_out(vty, " osmux bind-ip %s%s",
144 g_cfg->osmux_addr, VTY_NEWLINE);
145 vty_out(vty, " osmux batch-factor %d%s",
146 g_cfg->osmux_batch, VTY_NEWLINE);
147 vty_out(vty, " osmux batch-size %u%s",
148 g_cfg->osmux_batch_size, VTY_NEWLINE);
149 vty_out(vty, " osmux port %u%s",
150 g_cfg->osmux_port, VTY_NEWLINE);
151 vty_out(vty, " osmux dummy %s%s",
152 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
153 }
154 return CMD_SUCCESS;
155}
156
Philipp Maier87bd9be2017-08-22 16:35:41 +0200157static void dump_rtp_end(struct vty *vty, struct mgcp_rtp_state *state,
158 struct mgcp_rtp_end *end)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200159{
160 struct mgcp_rtp_codec *codec = &end->codec;
161
162 vty_out(vty,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200163 " Timestamp Errs: %d->%d%s"
164 " Dropped Packets: %d%s"
165 " Payload Type: %d Rate: %u Channels: %d %s"
166 " Frame Duration: %u Frame Denominator: %u%s"
167 " FPP: %d Packet Duration: %u%s"
168 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
169 " Output-Enabled: %d Force-PTIME: %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200170 state->in_stream.err_ts_counter,
171 state->out_stream.err_ts_counter, VTY_NEWLINE,
Harald Weltea0ac30f2017-12-25 09:52:30 +0100172 end->stats.dropped_packets, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200173 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200174 codec->frame_duration_num, codec->frame_duration_den,
175 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
176 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
177 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
178 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200179}
180
Philipp Maier87bd9be2017-08-22 16:35:41 +0200181static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
182 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200183{
184 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200185 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200186
187 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
188 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
189 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
190
191 if (!cfg->endpoints) {
192 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
193 return;
194 }
195
196 for (i = 1; i < cfg->number_endpoints; ++i) {
197 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200198
Philipp Maier87bd9be2017-08-22 16:35:41 +0200199 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
200
201 llist_for_each_entry(conn, &endp->conns, entry) {
202 vty_out(vty, " CONN: %s%s",
203 mgcp_conn_dump(conn), VTY_NEWLINE);
204
205 if (verbose) {
206 /* FIXME: Also add verbosity for other
207 * connection types (E1) as soon as
208 * the implementation is available */
209 if (conn->type == MGCP_CONN_TYPE_RTP) {
210 dump_rtp_end(vty, &conn->u.rtp.state,
211 &conn->u.rtp.end);
212 }
213 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200214 }
215 }
216}
217
218DEFUN(show_mcgp, show_mgcp_cmd,
219 "show mgcp [stats]",
220 SHOW_STR
221 "Display information about the MGCP Media Gateway\n"
222 "Include Statistics\n")
223{
224 struct mgcp_trunk_config *trunk;
225 int show_stats = argc >= 1;
226
227 dump_trunk(vty, &g_cfg->trunk, show_stats);
228
229 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200230 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200231
232 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200233 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
234 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200235
236 return CMD_SUCCESS;
237}
238
Philipp Maier87bd9be2017-08-22 16:35:41 +0200239DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200240{
241 vty->node = MGCP_NODE;
242 return CMD_SUCCESS;
243}
244
245DEFUN(cfg_mgcp_local_ip,
246 cfg_mgcp_local_ip_cmd,
247 "local ip A.B.C.D",
248 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200249 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200250{
251 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
252 return CMD_SUCCESS;
253}
254
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200255#define BIND_STR "Listen/Bind related socket option\n"
256DEFUN(cfg_mgcp_bind_ip,
257 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200258 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200259{
260 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
261 return CMD_SUCCESS;
262}
263
264DEFUN(cfg_mgcp_bind_port,
265 cfg_mgcp_bind_port_cmd,
266 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200267 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200268{
269 unsigned int port = atoi(argv[0]);
270 g_cfg->source_port = port;
271 return CMD_SUCCESS;
272}
273
274DEFUN(cfg_mgcp_bind_early,
275 cfg_mgcp_bind_early_cmd,
276 "bind early (0|1)",
277 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200278 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200279{
280 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
281 return CMD_WARNING;
282}
283
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200284static void parse_range(struct mgcp_port_range *range, const char **argv)
285{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200286 range->range_start = atoi(argv[0]);
287 range->range_end = atoi(argv[1]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200288 range->last_port = g_cfg->net_ports.range_start;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200289}
290
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200291#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200292#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200293#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200294#define RANGE_START_STR "Start of the range of ports\n"
295#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200296
Philipp Maierf1889d82017-11-08 14:59:39 +0100297DEFUN(cfg_mgcp_rtp_port_range,
298 cfg_mgcp_rtp_port_range_cmd,
299 "rtp port-range <0-65534> <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200300 RTP_STR "Range of ports to use for the NET side\n"
301 RANGE_START_STR RANGE_END_STR)
302{
303 parse_range(&g_cfg->net_ports, argv);
304 return CMD_SUCCESS;
305}
Philipp Maierf1889d82017-11-08 14:59:39 +0100306ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
307 cfg_mgcp_rtp_net_range_cmd,
308 "rtp net-range <0-65534> <0-65534>",
309 RTP_STR "Range of ports to use for the NET side\n"
310 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200311
Philipp Maierf1889d82017-11-08 14:59:39 +0100312DEFUN(cfg_mgcp_rtp_bind_ip,
313 cfg_mgcp_rtp_bind_ip_cmd,
314 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200315 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
316{
317 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
318 return CMD_SUCCESS;
319}
Philipp Maierf1889d82017-11-08 14:59:39 +0100320ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
321 cfg_mgcp_rtp_net_bind_ip_cmd,
322 "rtp net-bind-ip A.B.C.D",
323 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200324
Philipp Maierf1889d82017-11-08 14:59:39 +0100325DEFUN(cfg_mgcp_rtp_no_bind_ip,
326 cfg_mgcp_rtp_no_bind_ip_cmd,
327 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200328 NO_STR RTP_STR "Bind endpoints facing the Network\n"
329 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200330{
331 talloc_free(g_cfg->net_ports.bind_addr);
332 g_cfg->net_ports.bind_addr = NULL;
333 return CMD_SUCCESS;
334}
Philipp Maierf1889d82017-11-08 14:59:39 +0100335ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
336 cfg_mgcp_rtp_no_net_bind_ip_cmd,
337 "no rtp net-bind-ip",
338 NO_STR RTP_STR "Bind endpoints facing the Network\n"
339 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200340
Philipp Maier1cb1e382017-11-02 17:16:04 +0100341DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
342 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
343 "rtp ip-probing",
344 RTP_STR "automatic rtp bind ip selection\n")
345{
346 g_cfg->net_ports.bind_addr_probe = true;
347 return CMD_SUCCESS;
348}
349
350DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
351 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
352 "no rtp ip-probing",
353 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
354{
355 g_cfg->net_ports.bind_addr_probe = false;
356 return CMD_SUCCESS;
357}
358
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200359DEFUN(cfg_mgcp_rtp_ip_dscp,
360 cfg_mgcp_rtp_ip_dscp_cmd,
361 "rtp ip-dscp <0-255>",
362 RTP_STR
363 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
364{
365 int dscp = atoi(argv[0]);
366 g_cfg->endp_dscp = dscp;
367 return CMD_SUCCESS;
368}
369
370ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200371 "rtp ip-tos <0-255>",
372 RTP_STR
373 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
374#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
375 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200376 cfg_mgcp_rtp_force_ptime_cmd,
377 "rtp force-ptime (10|20|40)",
378 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200379 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200380{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200381 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200382 return CMD_SUCCESS;
383}
384
385DEFUN(cfg_mgcp_no_rtp_force_ptime,
386 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200387 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200388{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200389 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200390 return CMD_SUCCESS;
391}
392
393DEFUN(cfg_mgcp_sdp_fmtp_extra,
394 cfg_mgcp_sdp_fmtp_extra_cmd,
395 "sdp audio fmtp-extra .NAME",
396 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
397 "Extra Information\n")
398{
399 char *txt = argv_concat(argv, argc, 0);
400 if (!txt)
401 return CMD_WARNING;
402
403 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
404 talloc_free(txt);
405 return CMD_SUCCESS;
406}
407
408DEFUN(cfg_mgcp_allow_transcoding,
409 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200410 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200411{
412 g_cfg->trunk.no_audio_transcoding = 0;
413 return CMD_SUCCESS;
414}
415
416DEFUN(cfg_mgcp_no_allow_transcoding,
417 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200418 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200419{
420 g_cfg->trunk.no_audio_transcoding = 1;
421 return CMD_SUCCESS;
422}
423
424#define SDP_STR "SDP File related options\n"
425#define AUDIO_STR "Audio payload options\n"
426DEFUN(cfg_mgcp_sdp_payload_number,
427 cfg_mgcp_sdp_payload_number_cmd,
428 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200429 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200430{
431 unsigned int payload = atoi(argv[0]);
432 g_cfg->trunk.audio_payload = payload;
433 return CMD_SUCCESS;
434}
435
Philipp Maier87bd9be2017-08-22 16:35:41 +0200436ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
437 cfg_mgcp_sdp_payload_number_cmd_old,
438 "sdp audio payload number <0-255>",
439 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200440
Philipp Maier87bd9be2017-08-22 16:35:41 +0200441 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200442 cfg_mgcp_sdp_payload_name_cmd,
443 "sdp audio-payload name NAME",
444 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
445{
446 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
447 return CMD_SUCCESS;
448}
449
450ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200451 "sdp audio payload name NAME",
452 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200453
Philipp Maier87bd9be2017-08-22 16:35:41 +0200454 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200455 cfg_mgcp_sdp_payload_send_ptime_cmd,
456 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200457 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200458{
459 g_cfg->trunk.audio_send_ptime = 1;
460 return CMD_SUCCESS;
461}
462
463DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
464 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
465 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200466 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200467{
468 g_cfg->trunk.audio_send_ptime = 0;
469 return CMD_SUCCESS;
470}
471
472DEFUN(cfg_mgcp_sdp_payload_send_name,
473 cfg_mgcp_sdp_payload_send_name_cmd,
474 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200475 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200476{
477 g_cfg->trunk.audio_send_name = 1;
478 return CMD_SUCCESS;
479}
480
481DEFUN(cfg_mgcp_no_sdp_payload_send_name,
482 cfg_mgcp_no_sdp_payload_send_name_cmd,
483 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200484 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200485{
486 g_cfg->trunk.audio_send_name = 0;
487 return CMD_SUCCESS;
488}
489
490DEFUN(cfg_mgcp_loop,
491 cfg_mgcp_loop_cmd,
492 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200493 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200494{
495 if (g_cfg->osmux) {
496 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
497 return CMD_WARNING;
498 }
499 g_cfg->trunk.audio_loop = atoi(argv[0]);
500 return CMD_SUCCESS;
501}
502
503DEFUN(cfg_mgcp_force_realloc,
504 cfg_mgcp_force_realloc_cmd,
505 "force-realloc (0|1)",
506 "Force endpoint reallocation when the endpoint is still seized\n"
507 "Don't force reallocation\n" "force reallocation\n")
508{
509 g_cfg->trunk.force_realloc = atoi(argv[0]);
510 return CMD_SUCCESS;
511}
512
Philipp Maier87bd9be2017-08-22 16:35:41 +0200513DEFUN(cfg_mgcp_rtp_accept_all,
514 cfg_mgcp_rtp_accept_all_cmd,
515 "rtp-accept-all (0|1)",
516 "Accept all RTP packets, even when the originating IP/Port does not match\n"
517 "enable filter\n" "disable filter\n")
518{
519 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
520 return CMD_SUCCESS;
521}
522
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200523DEFUN(cfg_mgcp_number_endp,
524 cfg_mgcp_number_endp_cmd,
525 "number endpoints <0-65534>",
526 "Number options\n" "Endpoints available\n" "Number endpoints\n")
527{
528 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100529 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200530 return CMD_SUCCESS;
531}
532
Philipp Maier87bd9be2017-08-22 16:35:41 +0200533DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200534{
535 g_cfg->trunk.omit_rtcp = 1;
536 return CMD_SUCCESS;
537}
538
539DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200540 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200541{
542 g_cfg->trunk.omit_rtcp = 0;
543 return CMD_SUCCESS;
544}
545
546DEFUN(cfg_mgcp_patch_rtp_ssrc,
547 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200548 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200549{
550 g_cfg->trunk.force_constant_ssrc = 1;
551 return CMD_SUCCESS;
552}
553
554DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
555 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200556 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200557{
558 g_cfg->trunk.force_constant_ssrc = 0;
559 return CMD_SUCCESS;
560}
561
562DEFUN(cfg_mgcp_patch_rtp_ts,
563 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200564 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200565{
566 g_cfg->trunk.force_aligned_timing = 1;
567 return CMD_SUCCESS;
568}
569
570DEFUN(cfg_mgcp_no_patch_rtp_ts,
571 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200572 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200573{
574 g_cfg->trunk.force_aligned_timing = 0;
575 return CMD_SUCCESS;
576}
577
578DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200579 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200580{
581 g_cfg->trunk.force_constant_ssrc = 0;
582 g_cfg->trunk.force_aligned_timing = 0;
583 return CMD_SUCCESS;
584}
585
586DEFUN(cfg_mgcp_rtp_keepalive,
587 cfg_mgcp_rtp_keepalive_cmd,
588 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200589 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200590{
591 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
592 return CMD_SUCCESS;
593}
594
595DEFUN(cfg_mgcp_rtp_keepalive_once,
596 cfg_mgcp_rtp_keepalive_once_cmd,
597 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200598 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200599{
600 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
601 return CMD_SUCCESS;
602}
603
604DEFUN(cfg_mgcp_no_rtp_keepalive,
605 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200606 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200607{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100608 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200609 return CMD_SUCCESS;
610}
611
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200612#define CALL_AGENT_STR "Callagent information\n"
613DEFUN(cfg_mgcp_agent_addr,
614 cfg_mgcp_agent_addr_cmd,
615 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200616 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200617{
618 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
619 return CMD_SUCCESS;
620}
621
622ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200623 "call agent ip A.B.C.D",
624 CALL_AGENT_STR CALL_AGENT_STR IP_STR
625 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200626
Philipp Maier87bd9be2017-08-22 16:35:41 +0200627 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
628 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200629{
630 struct mgcp_trunk_config *trunk;
631 int index = atoi(argv[0]);
632
633 trunk = mgcp_trunk_num(g_cfg, index);
634 if (!trunk)
635 trunk = mgcp_trunk_alloc(g_cfg, index);
636
637 if (!trunk) {
638 vty_out(vty, "%%Unable to allocate trunk %u.%s",
639 index, VTY_NEWLINE);
640 return CMD_WARNING;
641 }
642
643 vty->node = TRUNK_NODE;
644 vty->index = trunk;
645 return CMD_SUCCESS;
646}
647
648static int config_write_trunk(struct vty *vty)
649{
650 struct mgcp_trunk_config *trunk;
651
652 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
653 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
654 vty_out(vty, " sdp audio-payload number %d%s",
655 trunk->audio_payload, VTY_NEWLINE);
656 vty_out(vty, " sdp audio-payload name %s%s",
657 trunk->audio_name, VTY_NEWLINE);
658 vty_out(vty, " %ssdp audio-payload send-ptime%s",
659 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
660 vty_out(vty, " %ssdp audio-payload send-name%s",
661 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
662
663 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
664 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
665 else if (trunk->keepalive_interval)
666 vty_out(vty, " rtp keep-alive %d%s",
667 trunk->keepalive_interval, VTY_NEWLINE);
668 else
669 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200670 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200671 vty_out(vty, " force-realloc %d%s",
672 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200673 vty_out(vty, " rtp-accept-all %d%s",
674 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200675 if (trunk->omit_rtcp)
676 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
677 else
678 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
679 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
680 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200681 trunk->force_constant_ssrc ? "" : "no ",
682 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200683 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200684 trunk->force_aligned_timing ? "" : "no ",
685 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200686 } else
687 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
688 if (trunk->audio_fmtp_extra)
689 vty_out(vty, " sdp audio fmtp-extra %s%s",
690 trunk->audio_fmtp_extra, VTY_NEWLINE);
691 vty_out(vty, " %sallow-transcoding%s",
692 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
693 }
694
695 return CMD_SUCCESS;
696}
697
698DEFUN(cfg_trunk_sdp_fmtp_extra,
699 cfg_trunk_sdp_fmtp_extra_cmd,
700 "sdp audio fmtp-extra .NAME",
701 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
702 "Extra Information\n")
703{
704 struct mgcp_trunk_config *trunk = vty->index;
705 char *txt = argv_concat(argv, argc, 0);
706 if (!txt)
707 return CMD_WARNING;
708
709 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
710 talloc_free(txt);
711 return CMD_SUCCESS;
712}
713
714DEFUN(cfg_trunk_payload_number,
715 cfg_trunk_payload_number_cmd,
716 "sdp audio-payload number <0-255>",
717 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
718{
719 struct mgcp_trunk_config *trunk = vty->index;
720 unsigned int payload = atoi(argv[0]);
721
722 trunk->audio_payload = payload;
723 return CMD_SUCCESS;
724}
725
726ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200727 "sdp audio payload number <0-255>",
728 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200729
Philipp Maier87bd9be2017-08-22 16:35:41 +0200730 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200731 cfg_trunk_payload_name_cmd,
732 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200733 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200734{
735 struct mgcp_trunk_config *trunk = vty->index;
736
737 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
738 return CMD_SUCCESS;
739}
740
741ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200742 "sdp audio payload name NAME",
743 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200744
Philipp Maier87bd9be2017-08-22 16:35:41 +0200745 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200746 cfg_trunk_loop_cmd,
747 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200748 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200749{
750 struct mgcp_trunk_config *trunk = vty->index;
751
752 if (g_cfg->osmux) {
753 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
754 return CMD_WARNING;
755 }
756 trunk->audio_loop = atoi(argv[0]);
757 return CMD_SUCCESS;
758}
759
760DEFUN(cfg_trunk_sdp_payload_send_ptime,
761 cfg_trunk_sdp_payload_send_ptime_cmd,
762 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200763 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200764{
765 struct mgcp_trunk_config *trunk = vty->index;
766 trunk->audio_send_ptime = 1;
767 return CMD_SUCCESS;
768}
769
770DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
771 cfg_trunk_no_sdp_payload_send_ptime_cmd,
772 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200773 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200774{
775 struct mgcp_trunk_config *trunk = vty->index;
776 trunk->audio_send_ptime = 0;
777 return CMD_SUCCESS;
778}
779
780DEFUN(cfg_trunk_sdp_payload_send_name,
781 cfg_trunk_sdp_payload_send_name_cmd,
782 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200783 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200784{
785 struct mgcp_trunk_config *trunk = vty->index;
786 trunk->audio_send_name = 1;
787 return CMD_SUCCESS;
788}
789
790DEFUN(cfg_trunk_no_sdp_payload_send_name,
791 cfg_trunk_no_sdp_payload_send_name_cmd,
792 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200793 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200794{
795 struct mgcp_trunk_config *trunk = vty->index;
796 trunk->audio_send_name = 0;
797 return CMD_SUCCESS;
798}
799
Philipp Maier87bd9be2017-08-22 16:35:41 +0200800DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200801{
802 struct mgcp_trunk_config *trunk = vty->index;
803 trunk->omit_rtcp = 1;
804 return CMD_SUCCESS;
805}
806
807DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200808 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200809{
810 struct mgcp_trunk_config *trunk = vty->index;
811 trunk->omit_rtcp = 0;
812 return CMD_SUCCESS;
813}
814
815DEFUN(cfg_trunk_patch_rtp_ssrc,
816 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200817 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200818{
819 struct mgcp_trunk_config *trunk = vty->index;
820 trunk->force_constant_ssrc = 1;
821 return CMD_SUCCESS;
822}
823
824DEFUN(cfg_trunk_no_patch_rtp_ssrc,
825 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200826 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200827{
828 struct mgcp_trunk_config *trunk = vty->index;
829 trunk->force_constant_ssrc = 0;
830 return CMD_SUCCESS;
831}
832
833DEFUN(cfg_trunk_patch_rtp_ts,
834 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200835 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200836{
837 struct mgcp_trunk_config *trunk = vty->index;
838 trunk->force_aligned_timing = 1;
839 return CMD_SUCCESS;
840}
841
842DEFUN(cfg_trunk_no_patch_rtp_ts,
843 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200844 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200845{
846 struct mgcp_trunk_config *trunk = vty->index;
847 trunk->force_aligned_timing = 0;
848 return CMD_SUCCESS;
849}
850
851DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200852 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200853{
854 struct mgcp_trunk_config *trunk = vty->index;
855 trunk->force_constant_ssrc = 0;
856 trunk->force_aligned_timing = 0;
857 return CMD_SUCCESS;
858}
859
860DEFUN(cfg_trunk_rtp_keepalive,
861 cfg_trunk_rtp_keepalive_cmd,
862 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200863 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200864{
865 struct mgcp_trunk_config *trunk = vty->index;
866 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
867 return CMD_SUCCESS;
868}
869
870DEFUN(cfg_trunk_rtp_keepalive_once,
871 cfg_trunk_rtp_keepalive_once_cmd,
872 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200873 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200874{
875 struct mgcp_trunk_config *trunk = vty->index;
876 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
877 return CMD_SUCCESS;
878}
879
880DEFUN(cfg_trunk_no_rtp_keepalive,
881 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200882 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200883{
884 struct mgcp_trunk_config *trunk = vty->index;
885 mgcp_trunk_set_keepalive(trunk, 0);
886 return CMD_SUCCESS;
887}
888
889DEFUN(cfg_trunk_allow_transcoding,
890 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200891 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200892{
893 struct mgcp_trunk_config *trunk = vty->index;
894 trunk->no_audio_transcoding = 0;
895 return CMD_SUCCESS;
896}
897
898DEFUN(cfg_trunk_no_allow_transcoding,
899 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200900 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200901{
902 struct mgcp_trunk_config *trunk = vty->index;
903 trunk->no_audio_transcoding = 1;
904 return CMD_SUCCESS;
905}
906
Philipp Maier87bd9be2017-08-22 16:35:41 +0200907DEFUN(loop_conn,
908 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200909 "loop-endpoint <0-64> NAME (0|1)",
910 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200911 "The name in hex of the endpoint\n" "Disable the loop\n"
912 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200913{
914 struct mgcp_trunk_config *trunk;
915 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200916 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200917
918 trunk = find_trunk(g_cfg, atoi(argv[0]));
919 if (!trunk) {
920 vty_out(vty, "%%Trunk %d not found in the config.%s",
921 atoi(argv[0]), VTY_NEWLINE);
922 return CMD_WARNING;
923 }
924
925 if (!trunk->endpoints) {
926 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
927 trunk->trunk_nr, VTY_NEWLINE);
928 return CMD_WARNING;
929 }
930
931 int endp_no = strtoul(argv[1], NULL, 16);
932 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
933 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200934 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200935 return CMD_WARNING;
936 }
937
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200938 endp = &trunk->endpoints[endp_no];
939 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200940 llist_for_each_entry(conn, &endp->conns, entry) {
941 if (conn->type == MGCP_CONN_TYPE_RTP)
942 /* Handle it like a MDCX, switch on SSRC patching if enabled */
943 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
944 else {
945 /* FIXME: Introduce support for other connection (E1)
946 * types when implementation is available */
947 vty_out(vty, "%%Can't enable SSRC patching,"
948 "connection %s is not an RTP connection.%s",
949 mgcp_conn_dump(conn), VTY_NEWLINE);
950 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200951
Philipp Maier87bd9be2017-08-22 16:35:41 +0200952 if (loop)
953 conn->mode = MGCP_CONN_LOOPBACK;
954 else
955 conn->mode = conn->mode_orig;
956 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200957
958 return CMD_SUCCESS;
959}
960
Philipp Maier87bd9be2017-08-22 16:35:41 +0200961DEFUN(tap_rtp,
962 tap_rtp_cmd,
963 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200964 "Forward data on endpoint to a different system\n" "Trunk number\n"
965 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200966 "The connection id in hex\n"
967 "Forward incoming data\n"
968 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200969 "destination IP of the data\n" "destination port\n")
970{
971 struct mgcp_rtp_tap *tap;
972 struct mgcp_trunk_config *trunk;
973 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200974 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +0100975 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200976
977 trunk = find_trunk(g_cfg, atoi(argv[0]));
978 if (!trunk) {
979 vty_out(vty, "%%Trunk %d not found in the config.%s",
980 atoi(argv[0]), VTY_NEWLINE);
981 return CMD_WARNING;
982 }
983
984 if (!trunk->endpoints) {
985 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
986 trunk->trunk_nr, VTY_NEWLINE);
987 return CMD_WARNING;
988 }
989
990 int endp_no = strtoul(argv[1], NULL, 16);
991 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
992 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200993 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200994 return CMD_WARNING;
995 }
996
997 endp = &trunk->endpoints[endp_no];
998
Philipp Maier01d24a32017-11-21 17:26:09 +0100999 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001000 conn = mgcp_conn_get_rtp(endp, conn_id);
1001 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001002 vty_out(vty, "Conn ID %s is invalid.%s",
1003 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001004 return CMD_WARNING;
1005 }
1006
1007 if (strcmp(argv[3], "in") == 0)
1008 tap = &conn->tap_in;
1009 else if (strcmp(argv[3], "out") == 0)
1010 tap = &conn->tap_out;
1011 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001012 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1013 return CMD_WARNING;
1014 }
1015
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001016 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001017 inet_aton(argv[4], &tap->forward.sin_addr);
1018 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001019 tap->enabled = 1;
1020 return CMD_SUCCESS;
1021}
1022
1023DEFUN(free_endp, free_endp_cmd,
1024 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001025 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001026{
1027 struct mgcp_trunk_config *trunk;
1028 struct mgcp_endpoint *endp;
1029
1030 trunk = find_trunk(g_cfg, atoi(argv[0]));
1031 if (!trunk) {
1032 vty_out(vty, "%%Trunk %d not found in the config.%s",
1033 atoi(argv[0]), VTY_NEWLINE);
1034 return CMD_WARNING;
1035 }
1036
1037 if (!trunk->endpoints) {
1038 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1039 trunk->trunk_nr, VTY_NEWLINE);
1040 return CMD_WARNING;
1041 }
1042
1043 int endp_no = strtoul(argv[1], NULL, 16);
1044 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1045 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001046 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001047 return CMD_WARNING;
1048 }
1049
1050 endp = &trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001051 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001052 return CMD_SUCCESS;
1053}
1054
1055DEFUN(reset_endp, reset_endp_cmd,
1056 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001057 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001058{
1059 struct mgcp_trunk_config *trunk;
1060 struct mgcp_endpoint *endp;
1061 int endp_no, rc;
1062
1063 trunk = find_trunk(g_cfg, atoi(argv[0]));
1064 if (!trunk) {
1065 vty_out(vty, "%%Trunk %d not found in the config.%s",
1066 atoi(argv[0]), VTY_NEWLINE);
1067 return CMD_WARNING;
1068 }
1069
1070 if (!trunk->endpoints) {
1071 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1072 trunk->trunk_nr, VTY_NEWLINE);
1073 return CMD_WARNING;
1074 }
1075
1076 endp_no = strtoul(argv[1], NULL, 16);
1077 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1078 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001079 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001080 return CMD_WARNING;
1081 }
1082
1083 endp = &trunk->endpoints[endp_no];
1084 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1085 if (rc < 0) {
1086 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1087 return CMD_WARNING;
1088 }
1089 return CMD_SUCCESS;
1090}
1091
1092DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001093 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001094{
1095 int rc;
1096
1097 rc = mgcp_send_reset_all(g_cfg);
1098 if (rc < 0) {
1099 vty_out(vty, "Error %d during endpoint reset.%s",
1100 rc, VTY_NEWLINE);
1101 return CMD_WARNING;
1102 }
1103 return CMD_SUCCESS;
1104}
1105
1106#define OSMUX_STR "RTP multiplexing\n"
1107DEFUN(cfg_mgcp_osmux,
1108 cfg_mgcp_osmux_cmd,
1109 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001110 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001111{
1112 if (strcmp(argv[0], "off") == 0) {
1113 g_cfg->osmux = OSMUX_USAGE_OFF;
1114 return CMD_SUCCESS;
1115 }
1116
Philipp Maier87bd9be2017-08-22 16:35:41 +02001117 /* Since OSMUX support is not finished, we do not
1118 * allow to turn it on yet. */
1119 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1120 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001121#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001122 if (strcmp(argv[0], "on") == 0)
1123 g_cfg->osmux = OSMUX_USAGE_ON;
1124 else if (strcmp(argv[0], "only") == 0)
1125 g_cfg->osmux = OSMUX_USAGE_ONLY;
1126
1127 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001128 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001129 return CMD_WARNING;
1130 }
1131
1132 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001133#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001134}
1135
1136DEFUN(cfg_mgcp_osmux_ip,
1137 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001138 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001139{
1140 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1141 return CMD_SUCCESS;
1142}
1143
1144DEFUN(cfg_mgcp_osmux_batch_factor,
1145 cfg_mgcp_osmux_batch_factor_cmd,
1146 "osmux batch-factor <1-8>",
1147 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1148{
1149 g_cfg->osmux_batch = atoi(argv[0]);
1150 return CMD_SUCCESS;
1151}
1152
1153DEFUN(cfg_mgcp_osmux_batch_size,
1154 cfg_mgcp_osmux_batch_size_cmd,
1155 "osmux batch-size <1-65535>",
1156 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1157{
1158 g_cfg->osmux_batch_size = atoi(argv[0]);
1159 return CMD_SUCCESS;
1160}
1161
1162DEFUN(cfg_mgcp_osmux_port,
1163 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001164 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001165{
1166 g_cfg->osmux_port = atoi(argv[0]);
1167 return CMD_SUCCESS;
1168}
1169
1170DEFUN(cfg_mgcp_osmux_dummy,
1171 cfg_mgcp_osmux_dummy_cmd,
1172 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001173 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1174 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001175{
1176 if (strcmp(argv[0], "on") == 0)
1177 g_cfg->osmux_dummy = 1;
1178 else if (strcmp(argv[0], "off") == 0)
1179 g_cfg->osmux_dummy = 0;
1180
1181 return CMD_SUCCESS;
1182}
1183
Philipp Maier12943ea2018-01-17 15:40:25 +01001184DEFUN(cfg_mgcp_domain,
1185 cfg_mgcp_domain_cmd,
1186 "domain NAME", "domain\n" "qualified domain name\n")
1187{
1188 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1189 return CMD_SUCCESS;
1190}
1191
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001192int mgcp_vty_init(void)
1193{
1194 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001195 install_element(ENABLE_NODE, &loop_conn_cmd);
1196 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001197 install_element(ENABLE_NODE, &free_endp_cmd);
1198 install_element(ENABLE_NODE, &reset_endp_cmd);
1199 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1200
1201 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1202 install_node(&mgcp_node, config_write_mgcp);
1203
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001204 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001205 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1206 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1207 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001208 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001209 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001210 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001211 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001212 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001213 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001214 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1215 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001216 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1217 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1218 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1219 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1220 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1221 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1222 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1223 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1224 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001225 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1226 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1227 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1228 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1229 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1230 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001231 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001232 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1233 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1234 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1235 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1236 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1237 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1238 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1239 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1240 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1241 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1242 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1243 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1244 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1245 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1246 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1247 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1248 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1249 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1250 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1251 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1252 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001253 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001254
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001255 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1256 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001257 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1258 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1259 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1260 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1261 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1262 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1263 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1264 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1265 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1266 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1267 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1268 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1269 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1270 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1271 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1272 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1273 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1274 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1275 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1276 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1277 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1278 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1279
1280 return 0;
1281}
1282
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001283int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1284 enum mgcp_role role)
1285{
1286 int rc;
1287 struct mgcp_trunk_config *trunk;
1288
1289 cfg->osmux_port = OSMUX_PORT;
1290 cfg->osmux_batch = 4;
1291 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1292
1293 g_cfg = cfg;
1294 rc = vty_read_config_file(config_file, NULL);
1295 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001296 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1297 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001298 return rc;
1299 }
1300
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001301 if (!g_cfg->source_addr) {
1302 fprintf(stderr, "You need to specify a bind address.\n");
1303 return -1;
1304 }
1305
Philipp Maier48454982017-11-10 16:46:41 +01001306 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001307 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001308 "Failed to initialize the virtual trunk (%d endpoints)\n",
1309 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001310 return -1;
1311 }
1312
1313 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001314 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001315 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001316 "Failed to initialize trunk %d (%d endpoints)\n",
1317 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001318 return -1;
1319 }
1320 }
1321 cfg->role = role;
1322
1323 return 0;
1324}