blob: 392a1762c7a1aa6707221e6bc5e86f5b45853023 [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,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200163 " Timestamp Errs: %lu->%lu%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200164 " 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",
Philipp Maier9e1d1642018-05-09 16:26:34 +0200170 state->in_stream.err_ts_ctr->current,
171 state->out_stream.err_ts_ctr->current,
172 VTY_NEWLINE,
Harald Weltea0ac30f2017-12-25 09:52:30 +0100173 end->stats.dropped_packets, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200174 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200175 codec->frame_duration_num, codec->frame_duration_den,
176 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
177 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
178 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
179 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200180}
181
Philipp Maier87bd9be2017-08-22 16:35:41 +0200182static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
183 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200184{
185 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200186 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200187
188 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
189 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
190 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
191
192 if (!cfg->endpoints) {
193 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
194 return;
195 }
196
197 for (i = 1; i < cfg->number_endpoints; ++i) {
198 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200199
Philipp Maier87bd9be2017-08-22 16:35:41 +0200200 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
201
202 llist_for_each_entry(conn, &endp->conns, entry) {
203 vty_out(vty, " CONN: %s%s",
204 mgcp_conn_dump(conn), VTY_NEWLINE);
205
206 if (verbose) {
207 /* FIXME: Also add verbosity for other
208 * connection types (E1) as soon as
209 * the implementation is available */
210 if (conn->type == MGCP_CONN_TYPE_RTP) {
211 dump_rtp_end(vty, &conn->u.rtp.state,
212 &conn->u.rtp.end);
213 }
214 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200215 }
216 }
217}
218
219DEFUN(show_mcgp, show_mgcp_cmd,
220 "show mgcp [stats]",
221 SHOW_STR
222 "Display information about the MGCP Media Gateway\n"
223 "Include Statistics\n")
224{
225 struct mgcp_trunk_config *trunk;
226 int show_stats = argc >= 1;
227
228 dump_trunk(vty, &g_cfg->trunk, show_stats);
229
230 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200231 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200232
233 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200234 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
235 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200236
237 return CMD_SUCCESS;
238}
239
Philipp Maier87bd9be2017-08-22 16:35:41 +0200240DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200241{
242 vty->node = MGCP_NODE;
243 return CMD_SUCCESS;
244}
245
246DEFUN(cfg_mgcp_local_ip,
247 cfg_mgcp_local_ip_cmd,
248 "local ip A.B.C.D",
249 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200250 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200251{
252 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
253 return CMD_SUCCESS;
254}
255
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200256#define BIND_STR "Listen/Bind related socket option\n"
257DEFUN(cfg_mgcp_bind_ip,
258 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200259 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200260{
261 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
262 return CMD_SUCCESS;
263}
264
265DEFUN(cfg_mgcp_bind_port,
266 cfg_mgcp_bind_port_cmd,
267 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200268 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200269{
270 unsigned int port = atoi(argv[0]);
271 g_cfg->source_port = port;
272 return CMD_SUCCESS;
273}
274
275DEFUN(cfg_mgcp_bind_early,
276 cfg_mgcp_bind_early_cmd,
277 "bind early (0|1)",
278 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200279 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200280{
281 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
282 return CMD_WARNING;
283}
284
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200285static void parse_range(struct mgcp_port_range *range, const char **argv)
286{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200287 range->range_start = atoi(argv[0]);
288 range->range_end = atoi(argv[1]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200289 range->last_port = g_cfg->net_ports.range_start;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200290}
291
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200292#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200293#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200294#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200295#define RANGE_START_STR "Start of the range of ports\n"
296#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200297
Philipp Maierf1889d82017-11-08 14:59:39 +0100298DEFUN(cfg_mgcp_rtp_port_range,
299 cfg_mgcp_rtp_port_range_cmd,
300 "rtp port-range <0-65534> <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200301 RTP_STR "Range of ports to use for the NET side\n"
302 RANGE_START_STR RANGE_END_STR)
303{
304 parse_range(&g_cfg->net_ports, argv);
305 return CMD_SUCCESS;
306}
Philipp Maierf1889d82017-11-08 14:59:39 +0100307ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
308 cfg_mgcp_rtp_net_range_cmd,
309 "rtp net-range <0-65534> <0-65534>",
310 RTP_STR "Range of ports to use for the NET side\n"
311 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200312
Philipp Maierf1889d82017-11-08 14:59:39 +0100313DEFUN(cfg_mgcp_rtp_bind_ip,
314 cfg_mgcp_rtp_bind_ip_cmd,
315 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200316 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
317{
318 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
319 return CMD_SUCCESS;
320}
Philipp Maierf1889d82017-11-08 14:59:39 +0100321ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
322 cfg_mgcp_rtp_net_bind_ip_cmd,
323 "rtp net-bind-ip A.B.C.D",
324 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200325
Philipp Maierf1889d82017-11-08 14:59:39 +0100326DEFUN(cfg_mgcp_rtp_no_bind_ip,
327 cfg_mgcp_rtp_no_bind_ip_cmd,
328 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200329 NO_STR RTP_STR "Bind endpoints facing the Network\n"
330 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200331{
332 talloc_free(g_cfg->net_ports.bind_addr);
333 g_cfg->net_ports.bind_addr = NULL;
334 return CMD_SUCCESS;
335}
Philipp Maierf1889d82017-11-08 14:59:39 +0100336ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
337 cfg_mgcp_rtp_no_net_bind_ip_cmd,
338 "no rtp net-bind-ip",
339 NO_STR RTP_STR "Bind endpoints facing the Network\n"
340 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200341
Philipp Maier1cb1e382017-11-02 17:16:04 +0100342DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
343 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
344 "rtp ip-probing",
345 RTP_STR "automatic rtp bind ip selection\n")
346{
347 g_cfg->net_ports.bind_addr_probe = true;
348 return CMD_SUCCESS;
349}
350
351DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
352 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
353 "no rtp ip-probing",
354 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
355{
356 g_cfg->net_ports.bind_addr_probe = false;
357 return CMD_SUCCESS;
358}
359
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200360DEFUN(cfg_mgcp_rtp_ip_dscp,
361 cfg_mgcp_rtp_ip_dscp_cmd,
362 "rtp ip-dscp <0-255>",
363 RTP_STR
364 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
365{
366 int dscp = atoi(argv[0]);
367 g_cfg->endp_dscp = dscp;
368 return CMD_SUCCESS;
369}
370
371ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200372 "rtp ip-tos <0-255>",
373 RTP_STR
374 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
375#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
376 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200377 cfg_mgcp_rtp_force_ptime_cmd,
378 "rtp force-ptime (10|20|40)",
379 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200380 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200381{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200382 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200383 return CMD_SUCCESS;
384}
385
386DEFUN(cfg_mgcp_no_rtp_force_ptime,
387 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200388 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200389{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200390 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200391 return CMD_SUCCESS;
392}
393
394DEFUN(cfg_mgcp_sdp_fmtp_extra,
395 cfg_mgcp_sdp_fmtp_extra_cmd,
396 "sdp audio fmtp-extra .NAME",
397 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
398 "Extra Information\n")
399{
400 char *txt = argv_concat(argv, argc, 0);
401 if (!txt)
402 return CMD_WARNING;
403
404 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
405 talloc_free(txt);
406 return CMD_SUCCESS;
407}
408
409DEFUN(cfg_mgcp_allow_transcoding,
410 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200411 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200412{
413 g_cfg->trunk.no_audio_transcoding = 0;
414 return CMD_SUCCESS;
415}
416
417DEFUN(cfg_mgcp_no_allow_transcoding,
418 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200419 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200420{
421 g_cfg->trunk.no_audio_transcoding = 1;
422 return CMD_SUCCESS;
423}
424
425#define SDP_STR "SDP File related options\n"
426#define AUDIO_STR "Audio payload options\n"
427DEFUN(cfg_mgcp_sdp_payload_number,
428 cfg_mgcp_sdp_payload_number_cmd,
429 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200430 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200431{
432 unsigned int payload = atoi(argv[0]);
433 g_cfg->trunk.audio_payload = payload;
434 return CMD_SUCCESS;
435}
436
Philipp Maier87bd9be2017-08-22 16:35:41 +0200437ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
438 cfg_mgcp_sdp_payload_number_cmd_old,
439 "sdp audio payload number <0-255>",
440 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200441
Philipp Maier87bd9be2017-08-22 16:35:41 +0200442 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200443 cfg_mgcp_sdp_payload_name_cmd,
444 "sdp audio-payload name NAME",
445 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
446{
447 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
448 return CMD_SUCCESS;
449}
450
451ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200452 "sdp audio payload name NAME",
453 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200454
Philipp Maier87bd9be2017-08-22 16:35:41 +0200455 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200456 cfg_mgcp_sdp_payload_send_ptime_cmd,
457 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200458 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200459{
460 g_cfg->trunk.audio_send_ptime = 1;
461 return CMD_SUCCESS;
462}
463
464DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
465 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
466 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200467 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200468{
469 g_cfg->trunk.audio_send_ptime = 0;
470 return CMD_SUCCESS;
471}
472
473DEFUN(cfg_mgcp_sdp_payload_send_name,
474 cfg_mgcp_sdp_payload_send_name_cmd,
475 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200476 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200477{
478 g_cfg->trunk.audio_send_name = 1;
479 return CMD_SUCCESS;
480}
481
482DEFUN(cfg_mgcp_no_sdp_payload_send_name,
483 cfg_mgcp_no_sdp_payload_send_name_cmd,
484 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200485 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200486{
487 g_cfg->trunk.audio_send_name = 0;
488 return CMD_SUCCESS;
489}
490
491DEFUN(cfg_mgcp_loop,
492 cfg_mgcp_loop_cmd,
493 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200494 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200495{
496 if (g_cfg->osmux) {
497 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
498 return CMD_WARNING;
499 }
500 g_cfg->trunk.audio_loop = atoi(argv[0]);
501 return CMD_SUCCESS;
502}
503
504DEFUN(cfg_mgcp_force_realloc,
505 cfg_mgcp_force_realloc_cmd,
506 "force-realloc (0|1)",
507 "Force endpoint reallocation when the endpoint is still seized\n"
508 "Don't force reallocation\n" "force reallocation\n")
509{
510 g_cfg->trunk.force_realloc = atoi(argv[0]);
511 return CMD_SUCCESS;
512}
513
Philipp Maier87bd9be2017-08-22 16:35:41 +0200514DEFUN(cfg_mgcp_rtp_accept_all,
515 cfg_mgcp_rtp_accept_all_cmd,
516 "rtp-accept-all (0|1)",
517 "Accept all RTP packets, even when the originating IP/Port does not match\n"
518 "enable filter\n" "disable filter\n")
519{
520 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
521 return CMD_SUCCESS;
522}
523
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200524DEFUN(cfg_mgcp_number_endp,
525 cfg_mgcp_number_endp_cmd,
526 "number endpoints <0-65534>",
527 "Number options\n" "Endpoints available\n" "Number endpoints\n")
528{
529 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100530 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200531 return CMD_SUCCESS;
532}
533
Philipp Maier87bd9be2017-08-22 16:35:41 +0200534DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200535{
536 g_cfg->trunk.omit_rtcp = 1;
537 return CMD_SUCCESS;
538}
539
540DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200541 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200542{
543 g_cfg->trunk.omit_rtcp = 0;
544 return CMD_SUCCESS;
545}
546
547DEFUN(cfg_mgcp_patch_rtp_ssrc,
548 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200549 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200550{
551 g_cfg->trunk.force_constant_ssrc = 1;
552 return CMD_SUCCESS;
553}
554
555DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
556 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200557 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200558{
559 g_cfg->trunk.force_constant_ssrc = 0;
560 return CMD_SUCCESS;
561}
562
563DEFUN(cfg_mgcp_patch_rtp_ts,
564 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200565 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200566{
567 g_cfg->trunk.force_aligned_timing = 1;
568 return CMD_SUCCESS;
569}
570
571DEFUN(cfg_mgcp_no_patch_rtp_ts,
572 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200573 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200574{
575 g_cfg->trunk.force_aligned_timing = 0;
576 return CMD_SUCCESS;
577}
578
579DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200580 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200581{
582 g_cfg->trunk.force_constant_ssrc = 0;
583 g_cfg->trunk.force_aligned_timing = 0;
584 return CMD_SUCCESS;
585}
586
587DEFUN(cfg_mgcp_rtp_keepalive,
588 cfg_mgcp_rtp_keepalive_cmd,
589 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200590 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200591{
592 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
593 return CMD_SUCCESS;
594}
595
596DEFUN(cfg_mgcp_rtp_keepalive_once,
597 cfg_mgcp_rtp_keepalive_once_cmd,
598 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200599 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200600{
601 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
602 return CMD_SUCCESS;
603}
604
605DEFUN(cfg_mgcp_no_rtp_keepalive,
606 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200607 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200608{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100609 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200610 return CMD_SUCCESS;
611}
612
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200613#define CALL_AGENT_STR "Callagent information\n"
614DEFUN(cfg_mgcp_agent_addr,
615 cfg_mgcp_agent_addr_cmd,
616 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200617 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200618{
619 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
620 return CMD_SUCCESS;
621}
622
623ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200624 "call agent ip A.B.C.D",
625 CALL_AGENT_STR CALL_AGENT_STR IP_STR
626 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200627
Philipp Maier87bd9be2017-08-22 16:35:41 +0200628 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
629 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200630{
631 struct mgcp_trunk_config *trunk;
632 int index = atoi(argv[0]);
633
634 trunk = mgcp_trunk_num(g_cfg, index);
635 if (!trunk)
636 trunk = mgcp_trunk_alloc(g_cfg, index);
637
638 if (!trunk) {
639 vty_out(vty, "%%Unable to allocate trunk %u.%s",
640 index, VTY_NEWLINE);
641 return CMD_WARNING;
642 }
643
644 vty->node = TRUNK_NODE;
645 vty->index = trunk;
646 return CMD_SUCCESS;
647}
648
649static int config_write_trunk(struct vty *vty)
650{
651 struct mgcp_trunk_config *trunk;
652
653 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
654 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
655 vty_out(vty, " sdp audio-payload number %d%s",
656 trunk->audio_payload, VTY_NEWLINE);
657 vty_out(vty, " sdp audio-payload name %s%s",
658 trunk->audio_name, VTY_NEWLINE);
659 vty_out(vty, " %ssdp audio-payload send-ptime%s",
660 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
661 vty_out(vty, " %ssdp audio-payload send-name%s",
662 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
663
664 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
665 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
666 else if (trunk->keepalive_interval)
667 vty_out(vty, " rtp keep-alive %d%s",
668 trunk->keepalive_interval, VTY_NEWLINE);
669 else
670 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200671 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200672 vty_out(vty, " force-realloc %d%s",
673 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200674 vty_out(vty, " rtp-accept-all %d%s",
675 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200676 if (trunk->omit_rtcp)
677 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
678 else
679 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
680 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
681 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200682 trunk->force_constant_ssrc ? "" : "no ",
683 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200684 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200685 trunk->force_aligned_timing ? "" : "no ",
686 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200687 } else
688 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
689 if (trunk->audio_fmtp_extra)
690 vty_out(vty, " sdp audio fmtp-extra %s%s",
691 trunk->audio_fmtp_extra, VTY_NEWLINE);
692 vty_out(vty, " %sallow-transcoding%s",
693 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
694 }
695
696 return CMD_SUCCESS;
697}
698
699DEFUN(cfg_trunk_sdp_fmtp_extra,
700 cfg_trunk_sdp_fmtp_extra_cmd,
701 "sdp audio fmtp-extra .NAME",
702 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
703 "Extra Information\n")
704{
705 struct mgcp_trunk_config *trunk = vty->index;
706 char *txt = argv_concat(argv, argc, 0);
707 if (!txt)
708 return CMD_WARNING;
709
710 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
711 talloc_free(txt);
712 return CMD_SUCCESS;
713}
714
715DEFUN(cfg_trunk_payload_number,
716 cfg_trunk_payload_number_cmd,
717 "sdp audio-payload number <0-255>",
718 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
719{
720 struct mgcp_trunk_config *trunk = vty->index;
721 unsigned int payload = atoi(argv[0]);
722
723 trunk->audio_payload = payload;
724 return CMD_SUCCESS;
725}
726
727ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200728 "sdp audio payload number <0-255>",
729 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730
Philipp Maier87bd9be2017-08-22 16:35:41 +0200731 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200732 cfg_trunk_payload_name_cmd,
733 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200734 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200735{
736 struct mgcp_trunk_config *trunk = vty->index;
737
738 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
739 return CMD_SUCCESS;
740}
741
742ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200743 "sdp audio payload name NAME",
744 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200745
Philipp Maier87bd9be2017-08-22 16:35:41 +0200746 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200747 cfg_trunk_loop_cmd,
748 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200749 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200750{
751 struct mgcp_trunk_config *trunk = vty->index;
752
753 if (g_cfg->osmux) {
754 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
755 return CMD_WARNING;
756 }
757 trunk->audio_loop = atoi(argv[0]);
758 return CMD_SUCCESS;
759}
760
761DEFUN(cfg_trunk_sdp_payload_send_ptime,
762 cfg_trunk_sdp_payload_send_ptime_cmd,
763 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200764 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200765{
766 struct mgcp_trunk_config *trunk = vty->index;
767 trunk->audio_send_ptime = 1;
768 return CMD_SUCCESS;
769}
770
771DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
772 cfg_trunk_no_sdp_payload_send_ptime_cmd,
773 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200774 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200775{
776 struct mgcp_trunk_config *trunk = vty->index;
777 trunk->audio_send_ptime = 0;
778 return CMD_SUCCESS;
779}
780
781DEFUN(cfg_trunk_sdp_payload_send_name,
782 cfg_trunk_sdp_payload_send_name_cmd,
783 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200784 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200785{
786 struct mgcp_trunk_config *trunk = vty->index;
787 trunk->audio_send_name = 1;
788 return CMD_SUCCESS;
789}
790
791DEFUN(cfg_trunk_no_sdp_payload_send_name,
792 cfg_trunk_no_sdp_payload_send_name_cmd,
793 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200794 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200795{
796 struct mgcp_trunk_config *trunk = vty->index;
797 trunk->audio_send_name = 0;
798 return CMD_SUCCESS;
799}
800
Philipp Maier87bd9be2017-08-22 16:35:41 +0200801DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200802{
803 struct mgcp_trunk_config *trunk = vty->index;
804 trunk->omit_rtcp = 1;
805 return CMD_SUCCESS;
806}
807
808DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200809 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200810{
811 struct mgcp_trunk_config *trunk = vty->index;
812 trunk->omit_rtcp = 0;
813 return CMD_SUCCESS;
814}
815
816DEFUN(cfg_trunk_patch_rtp_ssrc,
817 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200818 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200819{
820 struct mgcp_trunk_config *trunk = vty->index;
821 trunk->force_constant_ssrc = 1;
822 return CMD_SUCCESS;
823}
824
825DEFUN(cfg_trunk_no_patch_rtp_ssrc,
826 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200827 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200828{
829 struct mgcp_trunk_config *trunk = vty->index;
830 trunk->force_constant_ssrc = 0;
831 return CMD_SUCCESS;
832}
833
834DEFUN(cfg_trunk_patch_rtp_ts,
835 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200836 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200837{
838 struct mgcp_trunk_config *trunk = vty->index;
839 trunk->force_aligned_timing = 1;
840 return CMD_SUCCESS;
841}
842
843DEFUN(cfg_trunk_no_patch_rtp_ts,
844 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200845 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200846{
847 struct mgcp_trunk_config *trunk = vty->index;
848 trunk->force_aligned_timing = 0;
849 return CMD_SUCCESS;
850}
851
852DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200853 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200854{
855 struct mgcp_trunk_config *trunk = vty->index;
856 trunk->force_constant_ssrc = 0;
857 trunk->force_aligned_timing = 0;
858 return CMD_SUCCESS;
859}
860
861DEFUN(cfg_trunk_rtp_keepalive,
862 cfg_trunk_rtp_keepalive_cmd,
863 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200864 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200865{
866 struct mgcp_trunk_config *trunk = vty->index;
867 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
868 return CMD_SUCCESS;
869}
870
871DEFUN(cfg_trunk_rtp_keepalive_once,
872 cfg_trunk_rtp_keepalive_once_cmd,
873 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200874 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200875{
876 struct mgcp_trunk_config *trunk = vty->index;
877 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
878 return CMD_SUCCESS;
879}
880
881DEFUN(cfg_trunk_no_rtp_keepalive,
882 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200883 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200884{
885 struct mgcp_trunk_config *trunk = vty->index;
886 mgcp_trunk_set_keepalive(trunk, 0);
887 return CMD_SUCCESS;
888}
889
890DEFUN(cfg_trunk_allow_transcoding,
891 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200892 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200893{
894 struct mgcp_trunk_config *trunk = vty->index;
895 trunk->no_audio_transcoding = 0;
896 return CMD_SUCCESS;
897}
898
899DEFUN(cfg_trunk_no_allow_transcoding,
900 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200901 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200902{
903 struct mgcp_trunk_config *trunk = vty->index;
904 trunk->no_audio_transcoding = 1;
905 return CMD_SUCCESS;
906}
907
Philipp Maier87bd9be2017-08-22 16:35:41 +0200908DEFUN(loop_conn,
909 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200910 "loop-endpoint <0-64> NAME (0|1)",
911 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200912 "The name in hex of the endpoint\n" "Disable the loop\n"
913 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200914{
915 struct mgcp_trunk_config *trunk;
916 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200917 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200918
919 trunk = find_trunk(g_cfg, atoi(argv[0]));
920 if (!trunk) {
921 vty_out(vty, "%%Trunk %d not found in the config.%s",
922 atoi(argv[0]), VTY_NEWLINE);
923 return CMD_WARNING;
924 }
925
926 if (!trunk->endpoints) {
927 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
928 trunk->trunk_nr, VTY_NEWLINE);
929 return CMD_WARNING;
930 }
931
932 int endp_no = strtoul(argv[1], NULL, 16);
933 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
934 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200935 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200936 return CMD_WARNING;
937 }
938
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200939 endp = &trunk->endpoints[endp_no];
940 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200941 llist_for_each_entry(conn, &endp->conns, entry) {
942 if (conn->type == MGCP_CONN_TYPE_RTP)
943 /* Handle it like a MDCX, switch on SSRC patching if enabled */
944 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
945 else {
946 /* FIXME: Introduce support for other connection (E1)
947 * types when implementation is available */
948 vty_out(vty, "%%Can't enable SSRC patching,"
949 "connection %s is not an RTP connection.%s",
950 mgcp_conn_dump(conn), VTY_NEWLINE);
951 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200952
Philipp Maier87bd9be2017-08-22 16:35:41 +0200953 if (loop)
954 conn->mode = MGCP_CONN_LOOPBACK;
955 else
956 conn->mode = conn->mode_orig;
957 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200958
959 return CMD_SUCCESS;
960}
961
Philipp Maier87bd9be2017-08-22 16:35:41 +0200962DEFUN(tap_rtp,
963 tap_rtp_cmd,
964 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200965 "Forward data on endpoint to a different system\n" "Trunk number\n"
966 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200967 "The connection id in hex\n"
968 "Forward incoming data\n"
969 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200970 "destination IP of the data\n" "destination port\n")
971{
972 struct mgcp_rtp_tap *tap;
973 struct mgcp_trunk_config *trunk;
974 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200975 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +0100976 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200977
978 trunk = find_trunk(g_cfg, atoi(argv[0]));
979 if (!trunk) {
980 vty_out(vty, "%%Trunk %d not found in the config.%s",
981 atoi(argv[0]), VTY_NEWLINE);
982 return CMD_WARNING;
983 }
984
985 if (!trunk->endpoints) {
986 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
987 trunk->trunk_nr, VTY_NEWLINE);
988 return CMD_WARNING;
989 }
990
991 int endp_no = strtoul(argv[1], NULL, 16);
992 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
993 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200994 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200995 return CMD_WARNING;
996 }
997
998 endp = &trunk->endpoints[endp_no];
999
Philipp Maier01d24a32017-11-21 17:26:09 +01001000 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001001 conn = mgcp_conn_get_rtp(endp, conn_id);
1002 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001003 vty_out(vty, "Conn ID %s is invalid.%s",
1004 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001005 return CMD_WARNING;
1006 }
1007
1008 if (strcmp(argv[3], "in") == 0)
1009 tap = &conn->tap_in;
1010 else if (strcmp(argv[3], "out") == 0)
1011 tap = &conn->tap_out;
1012 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001013 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1014 return CMD_WARNING;
1015 }
1016
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001017 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001018 inet_aton(argv[4], &tap->forward.sin_addr);
1019 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001020 tap->enabled = 1;
1021 return CMD_SUCCESS;
1022}
1023
1024DEFUN(free_endp, free_endp_cmd,
1025 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001026 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001027{
1028 struct mgcp_trunk_config *trunk;
1029 struct mgcp_endpoint *endp;
1030
1031 trunk = find_trunk(g_cfg, atoi(argv[0]));
1032 if (!trunk) {
1033 vty_out(vty, "%%Trunk %d not found in the config.%s",
1034 atoi(argv[0]), VTY_NEWLINE);
1035 return CMD_WARNING;
1036 }
1037
1038 if (!trunk->endpoints) {
1039 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1040 trunk->trunk_nr, VTY_NEWLINE);
1041 return CMD_WARNING;
1042 }
1043
1044 int endp_no = strtoul(argv[1], NULL, 16);
1045 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1046 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001047 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001048 return CMD_WARNING;
1049 }
1050
1051 endp = &trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001052 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001053 return CMD_SUCCESS;
1054}
1055
1056DEFUN(reset_endp, reset_endp_cmd,
1057 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001058 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001059{
1060 struct mgcp_trunk_config *trunk;
1061 struct mgcp_endpoint *endp;
1062 int endp_no, rc;
1063
1064 trunk = find_trunk(g_cfg, atoi(argv[0]));
1065 if (!trunk) {
1066 vty_out(vty, "%%Trunk %d not found in the config.%s",
1067 atoi(argv[0]), VTY_NEWLINE);
1068 return CMD_WARNING;
1069 }
1070
1071 if (!trunk->endpoints) {
1072 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1073 trunk->trunk_nr, VTY_NEWLINE);
1074 return CMD_WARNING;
1075 }
1076
1077 endp_no = strtoul(argv[1], NULL, 16);
1078 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1079 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001080 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001081 return CMD_WARNING;
1082 }
1083
1084 endp = &trunk->endpoints[endp_no];
1085 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1086 if (rc < 0) {
1087 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1088 return CMD_WARNING;
1089 }
1090 return CMD_SUCCESS;
1091}
1092
1093DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001094 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001095{
1096 int rc;
1097
1098 rc = mgcp_send_reset_all(g_cfg);
1099 if (rc < 0) {
1100 vty_out(vty, "Error %d during endpoint reset.%s",
1101 rc, VTY_NEWLINE);
1102 return CMD_WARNING;
1103 }
1104 return CMD_SUCCESS;
1105}
1106
1107#define OSMUX_STR "RTP multiplexing\n"
1108DEFUN(cfg_mgcp_osmux,
1109 cfg_mgcp_osmux_cmd,
1110 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001111 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001112{
1113 if (strcmp(argv[0], "off") == 0) {
1114 g_cfg->osmux = OSMUX_USAGE_OFF;
1115 return CMD_SUCCESS;
1116 }
1117
Philipp Maier87bd9be2017-08-22 16:35:41 +02001118 /* Since OSMUX support is not finished, we do not
1119 * allow to turn it on yet. */
1120 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1121 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001122#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001123 if (strcmp(argv[0], "on") == 0)
1124 g_cfg->osmux = OSMUX_USAGE_ON;
1125 else if (strcmp(argv[0], "only") == 0)
1126 g_cfg->osmux = OSMUX_USAGE_ONLY;
1127
1128 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001129 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001130 return CMD_WARNING;
1131 }
1132
1133 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001134#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001135}
1136
1137DEFUN(cfg_mgcp_osmux_ip,
1138 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001139 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001140{
1141 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1142 return CMD_SUCCESS;
1143}
1144
1145DEFUN(cfg_mgcp_osmux_batch_factor,
1146 cfg_mgcp_osmux_batch_factor_cmd,
1147 "osmux batch-factor <1-8>",
1148 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1149{
1150 g_cfg->osmux_batch = atoi(argv[0]);
1151 return CMD_SUCCESS;
1152}
1153
1154DEFUN(cfg_mgcp_osmux_batch_size,
1155 cfg_mgcp_osmux_batch_size_cmd,
1156 "osmux batch-size <1-65535>",
1157 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1158{
1159 g_cfg->osmux_batch_size = atoi(argv[0]);
1160 return CMD_SUCCESS;
1161}
1162
1163DEFUN(cfg_mgcp_osmux_port,
1164 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001165 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001166{
1167 g_cfg->osmux_port = atoi(argv[0]);
1168 return CMD_SUCCESS;
1169}
1170
1171DEFUN(cfg_mgcp_osmux_dummy,
1172 cfg_mgcp_osmux_dummy_cmd,
1173 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001174 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1175 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001176{
1177 if (strcmp(argv[0], "on") == 0)
1178 g_cfg->osmux_dummy = 1;
1179 else if (strcmp(argv[0], "off") == 0)
1180 g_cfg->osmux_dummy = 0;
1181
1182 return CMD_SUCCESS;
1183}
1184
Philipp Maier12943ea2018-01-17 15:40:25 +01001185DEFUN(cfg_mgcp_domain,
1186 cfg_mgcp_domain_cmd,
1187 "domain NAME", "domain\n" "qualified domain name\n")
1188{
1189 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1190 return CMD_SUCCESS;
1191}
1192
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001193int mgcp_vty_init(void)
1194{
1195 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001196 install_element(ENABLE_NODE, &loop_conn_cmd);
1197 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001198 install_element(ENABLE_NODE, &free_endp_cmd);
1199 install_element(ENABLE_NODE, &reset_endp_cmd);
1200 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1201
1202 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1203 install_node(&mgcp_node, config_write_mgcp);
1204
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001205 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001206 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1207 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1208 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001209 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001210 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001211 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001212 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001213 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001214 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001215 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1216 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001217 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1218 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1219 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1220 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1221 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1222 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1223 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1224 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1225 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001226 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1227 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1228 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1229 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1230 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1231 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001232 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001233 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1234 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1235 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1236 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1237 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1238 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1239 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1240 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1241 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1242 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1243 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1244 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1245 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1246 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1247 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1248 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1249 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1250 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1251 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1252 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1253 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001254 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001255
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001256 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1257 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001258 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1259 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1260 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1261 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1262 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1263 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1264 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1265 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1266 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1267 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1268 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1269 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1270 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1271 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1272 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1273 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1274 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1275 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1276 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1277 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1278 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1279 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1280
1281 return 0;
1282}
1283
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001284int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1285 enum mgcp_role role)
1286{
1287 int rc;
1288 struct mgcp_trunk_config *trunk;
1289
1290 cfg->osmux_port = OSMUX_PORT;
1291 cfg->osmux_batch = 4;
1292 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1293
1294 g_cfg = cfg;
1295 rc = vty_read_config_file(config_file, NULL);
1296 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001297 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1298 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001299 return rc;
1300 }
1301
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001302 if (!g_cfg->source_addr) {
1303 fprintf(stderr, "You need to specify a bind address.\n");
1304 return -1;
1305 }
1306
Philipp Maier48454982017-11-10 16:46:41 +01001307 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001308 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001309 "Failed to initialize the virtual trunk (%d endpoints)\n",
1310 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001311 return -1;
1312 }
1313
1314 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001315 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001316 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001317 "Failed to initialize trunk %d (%d endpoints)\n",
1318 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001319 return -1;
1320 }
1321 }
1322 cfg->role = role;
1323
1324 return 0;
1325}