blob: a7a1feb64fcbac6e57fc142550d479f5e92bf60d [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{
Philipp Maierbc0346e2018-06-07 09:52:16 +0200160 struct mgcp_rtp_codec *codec = end->codec;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200161
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 +0200285#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200286#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200287#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200288#define RANGE_START_STR "Start of the range of ports\n"
289#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200290
Philipp Maierf1889d82017-11-08 14:59:39 +0100291DEFUN(cfg_mgcp_rtp_port_range,
292 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200293 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200294 RTP_STR "Range of ports to use for the NET side\n"
295 RANGE_START_STR RANGE_END_STR)
296{
Philipp Maiera19547b2018-05-22 13:44:34 +0200297 int start;
298 int end;
299
300 start = atoi(argv[0]);
301 end = atoi(argv[1]);
302
303 if (end < start) {
304 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
305 end, start, VTY_NEWLINE);
306 return CMD_WARNING;
307 }
308
309 if (start & 1) {
310 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
311 start, start & 0xFFFE, VTY_NEWLINE);
312 start &= 0xFFFE;
313 }
314
315 if ((end & 1) == 0) {
316 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
317 end, end | 1, VTY_NEWLINE);
318 end |= 1;
319 }
320
321 g_cfg->net_ports.range_start = start;
322 g_cfg->net_ports.range_end = end;
323 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
324
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200325 return CMD_SUCCESS;
326}
Philipp Maierf1889d82017-11-08 14:59:39 +0100327ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
328 cfg_mgcp_rtp_net_range_cmd,
329 "rtp net-range <0-65534> <0-65534>",
330 RTP_STR "Range of ports to use for the NET side\n"
331 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200332
Philipp Maierf1889d82017-11-08 14:59:39 +0100333DEFUN(cfg_mgcp_rtp_bind_ip,
334 cfg_mgcp_rtp_bind_ip_cmd,
335 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200336 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
337{
338 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
339 return CMD_SUCCESS;
340}
Philipp Maierf1889d82017-11-08 14:59:39 +0100341ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
342 cfg_mgcp_rtp_net_bind_ip_cmd,
343 "rtp net-bind-ip A.B.C.D",
344 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200345
Philipp Maierf1889d82017-11-08 14:59:39 +0100346DEFUN(cfg_mgcp_rtp_no_bind_ip,
347 cfg_mgcp_rtp_no_bind_ip_cmd,
348 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200349 NO_STR RTP_STR "Bind endpoints facing the Network\n"
350 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200351{
352 talloc_free(g_cfg->net_ports.bind_addr);
353 g_cfg->net_ports.bind_addr = NULL;
354 return CMD_SUCCESS;
355}
Philipp Maierf1889d82017-11-08 14:59:39 +0100356ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
357 cfg_mgcp_rtp_no_net_bind_ip_cmd,
358 "no rtp net-bind-ip",
359 NO_STR RTP_STR "Bind endpoints facing the Network\n"
360 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200361
Philipp Maier1cb1e382017-11-02 17:16:04 +0100362DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
363 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
364 "rtp ip-probing",
365 RTP_STR "automatic rtp bind ip selection\n")
366{
367 g_cfg->net_ports.bind_addr_probe = true;
368 return CMD_SUCCESS;
369}
370
371DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
372 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
373 "no rtp ip-probing",
374 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
375{
376 g_cfg->net_ports.bind_addr_probe = false;
377 return CMD_SUCCESS;
378}
379
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200380DEFUN(cfg_mgcp_rtp_ip_dscp,
381 cfg_mgcp_rtp_ip_dscp_cmd,
382 "rtp ip-dscp <0-255>",
383 RTP_STR
384 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
385{
386 int dscp = atoi(argv[0]);
387 g_cfg->endp_dscp = dscp;
388 return CMD_SUCCESS;
389}
390
391ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200392 "rtp ip-tos <0-255>",
393 RTP_STR
394 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
395#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
396 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200397 cfg_mgcp_rtp_force_ptime_cmd,
398 "rtp force-ptime (10|20|40)",
399 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200400 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200401{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200402 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200403 return CMD_SUCCESS;
404}
405
406DEFUN(cfg_mgcp_no_rtp_force_ptime,
407 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200408 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200409{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200410 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200411 return CMD_SUCCESS;
412}
413
414DEFUN(cfg_mgcp_sdp_fmtp_extra,
415 cfg_mgcp_sdp_fmtp_extra_cmd,
416 "sdp audio fmtp-extra .NAME",
417 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
418 "Extra Information\n")
419{
420 char *txt = argv_concat(argv, argc, 0);
421 if (!txt)
422 return CMD_WARNING;
423
424 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
425 talloc_free(txt);
426 return CMD_SUCCESS;
427}
428
429DEFUN(cfg_mgcp_allow_transcoding,
430 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200431 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200432{
433 g_cfg->trunk.no_audio_transcoding = 0;
434 return CMD_SUCCESS;
435}
436
437DEFUN(cfg_mgcp_no_allow_transcoding,
438 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200439 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200440{
441 g_cfg->trunk.no_audio_transcoding = 1;
442 return CMD_SUCCESS;
443}
444
445#define SDP_STR "SDP File related options\n"
446#define AUDIO_STR "Audio payload options\n"
447DEFUN(cfg_mgcp_sdp_payload_number,
448 cfg_mgcp_sdp_payload_number_cmd,
449 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200450 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200451{
452 unsigned int payload = atoi(argv[0]);
453 g_cfg->trunk.audio_payload = payload;
454 return CMD_SUCCESS;
455}
456
Philipp Maier87bd9be2017-08-22 16:35:41 +0200457ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
458 cfg_mgcp_sdp_payload_number_cmd_old,
459 "sdp audio payload number <0-255>",
460 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200461
Philipp Maier87bd9be2017-08-22 16:35:41 +0200462 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200463 cfg_mgcp_sdp_payload_name_cmd,
464 "sdp audio-payload name NAME",
465 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
466{
467 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
468 return CMD_SUCCESS;
469}
470
471ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200472 "sdp audio payload name NAME",
473 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200474
Philipp Maier87bd9be2017-08-22 16:35:41 +0200475 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200476 cfg_mgcp_sdp_payload_send_ptime_cmd,
477 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200478 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200479{
480 g_cfg->trunk.audio_send_ptime = 1;
481 return CMD_SUCCESS;
482}
483
484DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
485 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
486 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200487 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200488{
489 g_cfg->trunk.audio_send_ptime = 0;
490 return CMD_SUCCESS;
491}
492
493DEFUN(cfg_mgcp_sdp_payload_send_name,
494 cfg_mgcp_sdp_payload_send_name_cmd,
495 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200496 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200497{
498 g_cfg->trunk.audio_send_name = 1;
499 return CMD_SUCCESS;
500}
501
502DEFUN(cfg_mgcp_no_sdp_payload_send_name,
503 cfg_mgcp_no_sdp_payload_send_name_cmd,
504 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200505 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200506{
507 g_cfg->trunk.audio_send_name = 0;
508 return CMD_SUCCESS;
509}
510
511DEFUN(cfg_mgcp_loop,
512 cfg_mgcp_loop_cmd,
513 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200514 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200515{
516 if (g_cfg->osmux) {
517 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
518 return CMD_WARNING;
519 }
520 g_cfg->trunk.audio_loop = atoi(argv[0]);
521 return CMD_SUCCESS;
522}
523
524DEFUN(cfg_mgcp_force_realloc,
525 cfg_mgcp_force_realloc_cmd,
526 "force-realloc (0|1)",
527 "Force endpoint reallocation when the endpoint is still seized\n"
528 "Don't force reallocation\n" "force reallocation\n")
529{
530 g_cfg->trunk.force_realloc = atoi(argv[0]);
531 return CMD_SUCCESS;
532}
533
Philipp Maier87bd9be2017-08-22 16:35:41 +0200534DEFUN(cfg_mgcp_rtp_accept_all,
535 cfg_mgcp_rtp_accept_all_cmd,
536 "rtp-accept-all (0|1)",
537 "Accept all RTP packets, even when the originating IP/Port does not match\n"
538 "enable filter\n" "disable filter\n")
539{
540 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
541 return CMD_SUCCESS;
542}
543
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200544DEFUN(cfg_mgcp_number_endp,
545 cfg_mgcp_number_endp_cmd,
546 "number endpoints <0-65534>",
547 "Number options\n" "Endpoints available\n" "Number endpoints\n")
548{
549 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100550 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200551 return CMD_SUCCESS;
552}
553
Philipp Maier87bd9be2017-08-22 16:35:41 +0200554DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200555{
556 g_cfg->trunk.omit_rtcp = 1;
557 return CMD_SUCCESS;
558}
559
560DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200561 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200562{
563 g_cfg->trunk.omit_rtcp = 0;
564 return CMD_SUCCESS;
565}
566
567DEFUN(cfg_mgcp_patch_rtp_ssrc,
568 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200569 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200570{
571 g_cfg->trunk.force_constant_ssrc = 1;
572 return CMD_SUCCESS;
573}
574
575DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
576 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200577 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200578{
579 g_cfg->trunk.force_constant_ssrc = 0;
580 return CMD_SUCCESS;
581}
582
583DEFUN(cfg_mgcp_patch_rtp_ts,
584 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200585 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200586{
587 g_cfg->trunk.force_aligned_timing = 1;
588 return CMD_SUCCESS;
589}
590
591DEFUN(cfg_mgcp_no_patch_rtp_ts,
592 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200593 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200594{
595 g_cfg->trunk.force_aligned_timing = 0;
596 return CMD_SUCCESS;
597}
598
599DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200600 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200601{
602 g_cfg->trunk.force_constant_ssrc = 0;
603 g_cfg->trunk.force_aligned_timing = 0;
604 return CMD_SUCCESS;
605}
606
607DEFUN(cfg_mgcp_rtp_keepalive,
608 cfg_mgcp_rtp_keepalive_cmd,
609 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200610 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200611{
612 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
613 return CMD_SUCCESS;
614}
615
616DEFUN(cfg_mgcp_rtp_keepalive_once,
617 cfg_mgcp_rtp_keepalive_once_cmd,
618 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200619 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200620{
621 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
622 return CMD_SUCCESS;
623}
624
625DEFUN(cfg_mgcp_no_rtp_keepalive,
626 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200627 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200628{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100629 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200630 return CMD_SUCCESS;
631}
632
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200633#define CALL_AGENT_STR "Callagent information\n"
634DEFUN(cfg_mgcp_agent_addr,
635 cfg_mgcp_agent_addr_cmd,
636 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200637 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200638{
639 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
640 return CMD_SUCCESS;
641}
642
643ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200644 "call agent ip A.B.C.D",
645 CALL_AGENT_STR CALL_AGENT_STR IP_STR
646 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200647
Philipp Maier87bd9be2017-08-22 16:35:41 +0200648 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
649 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200650{
651 struct mgcp_trunk_config *trunk;
652 int index = atoi(argv[0]);
653
654 trunk = mgcp_trunk_num(g_cfg, index);
655 if (!trunk)
656 trunk = mgcp_trunk_alloc(g_cfg, index);
657
658 if (!trunk) {
659 vty_out(vty, "%%Unable to allocate trunk %u.%s",
660 index, VTY_NEWLINE);
661 return CMD_WARNING;
662 }
663
664 vty->node = TRUNK_NODE;
665 vty->index = trunk;
666 return CMD_SUCCESS;
667}
668
669static int config_write_trunk(struct vty *vty)
670{
671 struct mgcp_trunk_config *trunk;
672
673 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
674 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
675 vty_out(vty, " sdp audio-payload number %d%s",
676 trunk->audio_payload, VTY_NEWLINE);
677 vty_out(vty, " sdp audio-payload name %s%s",
678 trunk->audio_name, VTY_NEWLINE);
679 vty_out(vty, " %ssdp audio-payload send-ptime%s",
680 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
681 vty_out(vty, " %ssdp audio-payload send-name%s",
682 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
683
684 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
685 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
686 else if (trunk->keepalive_interval)
687 vty_out(vty, " rtp keep-alive %d%s",
688 trunk->keepalive_interval, VTY_NEWLINE);
689 else
690 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200691 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200692 vty_out(vty, " force-realloc %d%s",
693 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200694 vty_out(vty, " rtp-accept-all %d%s",
695 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200696 if (trunk->omit_rtcp)
697 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
698 else
699 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
700 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
701 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200702 trunk->force_constant_ssrc ? "" : "no ",
703 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200704 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200705 trunk->force_aligned_timing ? "" : "no ",
706 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200707 } else
708 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
709 if (trunk->audio_fmtp_extra)
710 vty_out(vty, " sdp audio fmtp-extra %s%s",
711 trunk->audio_fmtp_extra, VTY_NEWLINE);
712 vty_out(vty, " %sallow-transcoding%s",
713 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
714 }
715
716 return CMD_SUCCESS;
717}
718
719DEFUN(cfg_trunk_sdp_fmtp_extra,
720 cfg_trunk_sdp_fmtp_extra_cmd,
721 "sdp audio fmtp-extra .NAME",
722 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
723 "Extra Information\n")
724{
725 struct mgcp_trunk_config *trunk = vty->index;
726 char *txt = argv_concat(argv, argc, 0);
727 if (!txt)
728 return CMD_WARNING;
729
730 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
731 talloc_free(txt);
732 return CMD_SUCCESS;
733}
734
735DEFUN(cfg_trunk_payload_number,
736 cfg_trunk_payload_number_cmd,
737 "sdp audio-payload number <0-255>",
738 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
739{
740 struct mgcp_trunk_config *trunk = vty->index;
741 unsigned int payload = atoi(argv[0]);
742
743 trunk->audio_payload = payload;
744 return CMD_SUCCESS;
745}
746
747ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200748 "sdp audio payload number <0-255>",
749 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200750
Philipp Maier87bd9be2017-08-22 16:35:41 +0200751 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200752 cfg_trunk_payload_name_cmd,
753 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200754 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200755{
756 struct mgcp_trunk_config *trunk = vty->index;
757
758 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
759 return CMD_SUCCESS;
760}
761
762ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200763 "sdp audio payload name NAME",
764 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200765
Philipp Maier87bd9be2017-08-22 16:35:41 +0200766 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200767 cfg_trunk_loop_cmd,
768 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200769 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200770{
771 struct mgcp_trunk_config *trunk = vty->index;
772
773 if (g_cfg->osmux) {
774 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
775 return CMD_WARNING;
776 }
777 trunk->audio_loop = atoi(argv[0]);
778 return CMD_SUCCESS;
779}
780
781DEFUN(cfg_trunk_sdp_payload_send_ptime,
782 cfg_trunk_sdp_payload_send_ptime_cmd,
783 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200784 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200785{
786 struct mgcp_trunk_config *trunk = vty->index;
787 trunk->audio_send_ptime = 1;
788 return CMD_SUCCESS;
789}
790
791DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
792 cfg_trunk_no_sdp_payload_send_ptime_cmd,
793 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200794 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200795{
796 struct mgcp_trunk_config *trunk = vty->index;
797 trunk->audio_send_ptime = 0;
798 return CMD_SUCCESS;
799}
800
801DEFUN(cfg_trunk_sdp_payload_send_name,
802 cfg_trunk_sdp_payload_send_name_cmd,
803 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200804 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200805{
806 struct mgcp_trunk_config *trunk = vty->index;
807 trunk->audio_send_name = 1;
808 return CMD_SUCCESS;
809}
810
811DEFUN(cfg_trunk_no_sdp_payload_send_name,
812 cfg_trunk_no_sdp_payload_send_name_cmd,
813 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200814 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200815{
816 struct mgcp_trunk_config *trunk = vty->index;
817 trunk->audio_send_name = 0;
818 return CMD_SUCCESS;
819}
820
Philipp Maier87bd9be2017-08-22 16:35:41 +0200821DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200822{
823 struct mgcp_trunk_config *trunk = vty->index;
824 trunk->omit_rtcp = 1;
825 return CMD_SUCCESS;
826}
827
828DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200829 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200830{
831 struct mgcp_trunk_config *trunk = vty->index;
832 trunk->omit_rtcp = 0;
833 return CMD_SUCCESS;
834}
835
836DEFUN(cfg_trunk_patch_rtp_ssrc,
837 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200838 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200839{
840 struct mgcp_trunk_config *trunk = vty->index;
841 trunk->force_constant_ssrc = 1;
842 return CMD_SUCCESS;
843}
844
845DEFUN(cfg_trunk_no_patch_rtp_ssrc,
846 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200847 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200848{
849 struct mgcp_trunk_config *trunk = vty->index;
850 trunk->force_constant_ssrc = 0;
851 return CMD_SUCCESS;
852}
853
854DEFUN(cfg_trunk_patch_rtp_ts,
855 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200856 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200857{
858 struct mgcp_trunk_config *trunk = vty->index;
859 trunk->force_aligned_timing = 1;
860 return CMD_SUCCESS;
861}
862
863DEFUN(cfg_trunk_no_patch_rtp_ts,
864 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200865 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200866{
867 struct mgcp_trunk_config *trunk = vty->index;
868 trunk->force_aligned_timing = 0;
869 return CMD_SUCCESS;
870}
871
872DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200873 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200874{
875 struct mgcp_trunk_config *trunk = vty->index;
876 trunk->force_constant_ssrc = 0;
877 trunk->force_aligned_timing = 0;
878 return CMD_SUCCESS;
879}
880
881DEFUN(cfg_trunk_rtp_keepalive,
882 cfg_trunk_rtp_keepalive_cmd,
883 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200884 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200885{
886 struct mgcp_trunk_config *trunk = vty->index;
887 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
888 return CMD_SUCCESS;
889}
890
891DEFUN(cfg_trunk_rtp_keepalive_once,
892 cfg_trunk_rtp_keepalive_once_cmd,
893 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200894 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200895{
896 struct mgcp_trunk_config *trunk = vty->index;
897 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
898 return CMD_SUCCESS;
899}
900
901DEFUN(cfg_trunk_no_rtp_keepalive,
902 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200903 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200904{
905 struct mgcp_trunk_config *trunk = vty->index;
906 mgcp_trunk_set_keepalive(trunk, 0);
907 return CMD_SUCCESS;
908}
909
910DEFUN(cfg_trunk_allow_transcoding,
911 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200912 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200913{
914 struct mgcp_trunk_config *trunk = vty->index;
915 trunk->no_audio_transcoding = 0;
916 return CMD_SUCCESS;
917}
918
919DEFUN(cfg_trunk_no_allow_transcoding,
920 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200921 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200922{
923 struct mgcp_trunk_config *trunk = vty->index;
924 trunk->no_audio_transcoding = 1;
925 return CMD_SUCCESS;
926}
927
Philipp Maier87bd9be2017-08-22 16:35:41 +0200928DEFUN(loop_conn,
929 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200930 "loop-endpoint <0-64> NAME (0|1)",
931 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200932 "The name in hex of the endpoint\n" "Disable the loop\n"
933 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200934{
935 struct mgcp_trunk_config *trunk;
936 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200937 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200938
939 trunk = find_trunk(g_cfg, atoi(argv[0]));
940 if (!trunk) {
941 vty_out(vty, "%%Trunk %d not found in the config.%s",
942 atoi(argv[0]), VTY_NEWLINE);
943 return CMD_WARNING;
944 }
945
946 if (!trunk->endpoints) {
947 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
948 trunk->trunk_nr, VTY_NEWLINE);
949 return CMD_WARNING;
950 }
951
952 int endp_no = strtoul(argv[1], NULL, 16);
953 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
954 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200955 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200956 return CMD_WARNING;
957 }
958
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200959 endp = &trunk->endpoints[endp_no];
960 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200961 llist_for_each_entry(conn, &endp->conns, entry) {
962 if (conn->type == MGCP_CONN_TYPE_RTP)
963 /* Handle it like a MDCX, switch on SSRC patching if enabled */
964 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
965 else {
966 /* FIXME: Introduce support for other connection (E1)
967 * types when implementation is available */
968 vty_out(vty, "%%Can't enable SSRC patching,"
969 "connection %s is not an RTP connection.%s",
970 mgcp_conn_dump(conn), VTY_NEWLINE);
971 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200972
Philipp Maier87bd9be2017-08-22 16:35:41 +0200973 if (loop)
974 conn->mode = MGCP_CONN_LOOPBACK;
975 else
976 conn->mode = conn->mode_orig;
977 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200978
979 return CMD_SUCCESS;
980}
981
Philipp Maier87bd9be2017-08-22 16:35:41 +0200982DEFUN(tap_rtp,
983 tap_rtp_cmd,
984 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200985 "Forward data on endpoint to a different system\n" "Trunk number\n"
986 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200987 "The connection id in hex\n"
988 "Forward incoming data\n"
989 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200990 "destination IP of the data\n" "destination port\n")
991{
992 struct mgcp_rtp_tap *tap;
993 struct mgcp_trunk_config *trunk;
994 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200995 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +0100996 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200997
998 trunk = find_trunk(g_cfg, atoi(argv[0]));
999 if (!trunk) {
1000 vty_out(vty, "%%Trunk %d not found in the config.%s",
1001 atoi(argv[0]), VTY_NEWLINE);
1002 return CMD_WARNING;
1003 }
1004
1005 if (!trunk->endpoints) {
1006 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1007 trunk->trunk_nr, VTY_NEWLINE);
1008 return CMD_WARNING;
1009 }
1010
1011 int endp_no = strtoul(argv[1], NULL, 16);
1012 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1013 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001014 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001015 return CMD_WARNING;
1016 }
1017
1018 endp = &trunk->endpoints[endp_no];
1019
Philipp Maier01d24a32017-11-21 17:26:09 +01001020 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001021 conn = mgcp_conn_get_rtp(endp, conn_id);
1022 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001023 vty_out(vty, "Conn ID %s is invalid.%s",
1024 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001025 return CMD_WARNING;
1026 }
1027
1028 if (strcmp(argv[3], "in") == 0)
1029 tap = &conn->tap_in;
1030 else if (strcmp(argv[3], "out") == 0)
1031 tap = &conn->tap_out;
1032 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001033 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1034 return CMD_WARNING;
1035 }
1036
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001037 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001038 inet_aton(argv[4], &tap->forward.sin_addr);
1039 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001040 tap->enabled = 1;
1041 return CMD_SUCCESS;
1042}
1043
1044DEFUN(free_endp, free_endp_cmd,
1045 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001046 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001047{
1048 struct mgcp_trunk_config *trunk;
1049 struct mgcp_endpoint *endp;
1050
1051 trunk = find_trunk(g_cfg, atoi(argv[0]));
1052 if (!trunk) {
1053 vty_out(vty, "%%Trunk %d not found in the config.%s",
1054 atoi(argv[0]), VTY_NEWLINE);
1055 return CMD_WARNING;
1056 }
1057
1058 if (!trunk->endpoints) {
1059 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1060 trunk->trunk_nr, VTY_NEWLINE);
1061 return CMD_WARNING;
1062 }
1063
1064 int endp_no = strtoul(argv[1], NULL, 16);
1065 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1066 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001067 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001068 return CMD_WARNING;
1069 }
1070
1071 endp = &trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001072 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001073 return CMD_SUCCESS;
1074}
1075
1076DEFUN(reset_endp, reset_endp_cmd,
1077 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001078 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001079{
1080 struct mgcp_trunk_config *trunk;
1081 struct mgcp_endpoint *endp;
1082 int endp_no, rc;
1083
1084 trunk = find_trunk(g_cfg, atoi(argv[0]));
1085 if (!trunk) {
1086 vty_out(vty, "%%Trunk %d not found in the config.%s",
1087 atoi(argv[0]), VTY_NEWLINE);
1088 return CMD_WARNING;
1089 }
1090
1091 if (!trunk->endpoints) {
1092 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1093 trunk->trunk_nr, VTY_NEWLINE);
1094 return CMD_WARNING;
1095 }
1096
1097 endp_no = strtoul(argv[1], NULL, 16);
1098 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1099 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001100 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001101 return CMD_WARNING;
1102 }
1103
1104 endp = &trunk->endpoints[endp_no];
1105 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1106 if (rc < 0) {
1107 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1108 return CMD_WARNING;
1109 }
1110 return CMD_SUCCESS;
1111}
1112
1113DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001114 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001115{
1116 int rc;
1117
1118 rc = mgcp_send_reset_all(g_cfg);
1119 if (rc < 0) {
1120 vty_out(vty, "Error %d during endpoint reset.%s",
1121 rc, VTY_NEWLINE);
1122 return CMD_WARNING;
1123 }
1124 return CMD_SUCCESS;
1125}
1126
1127#define OSMUX_STR "RTP multiplexing\n"
1128DEFUN(cfg_mgcp_osmux,
1129 cfg_mgcp_osmux_cmd,
1130 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001131 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001132{
1133 if (strcmp(argv[0], "off") == 0) {
1134 g_cfg->osmux = OSMUX_USAGE_OFF;
1135 return CMD_SUCCESS;
1136 }
1137
Philipp Maier87bd9be2017-08-22 16:35:41 +02001138 /* Since OSMUX support is not finished, we do not
1139 * allow to turn it on yet. */
1140 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1141 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001142#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001143 if (strcmp(argv[0], "on") == 0)
1144 g_cfg->osmux = OSMUX_USAGE_ON;
1145 else if (strcmp(argv[0], "only") == 0)
1146 g_cfg->osmux = OSMUX_USAGE_ONLY;
1147
1148 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001149 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001150 return CMD_WARNING;
1151 }
1152
1153 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001154#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001155}
1156
1157DEFUN(cfg_mgcp_osmux_ip,
1158 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001159 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001160{
1161 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1162 return CMD_SUCCESS;
1163}
1164
1165DEFUN(cfg_mgcp_osmux_batch_factor,
1166 cfg_mgcp_osmux_batch_factor_cmd,
1167 "osmux batch-factor <1-8>",
1168 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1169{
1170 g_cfg->osmux_batch = atoi(argv[0]);
1171 return CMD_SUCCESS;
1172}
1173
1174DEFUN(cfg_mgcp_osmux_batch_size,
1175 cfg_mgcp_osmux_batch_size_cmd,
1176 "osmux batch-size <1-65535>",
1177 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1178{
1179 g_cfg->osmux_batch_size = atoi(argv[0]);
1180 return CMD_SUCCESS;
1181}
1182
1183DEFUN(cfg_mgcp_osmux_port,
1184 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001185 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001186{
1187 g_cfg->osmux_port = atoi(argv[0]);
1188 return CMD_SUCCESS;
1189}
1190
1191DEFUN(cfg_mgcp_osmux_dummy,
1192 cfg_mgcp_osmux_dummy_cmd,
1193 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001194 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1195 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001196{
1197 if (strcmp(argv[0], "on") == 0)
1198 g_cfg->osmux_dummy = 1;
1199 else if (strcmp(argv[0], "off") == 0)
1200 g_cfg->osmux_dummy = 0;
1201
1202 return CMD_SUCCESS;
1203}
1204
Philipp Maier12943ea2018-01-17 15:40:25 +01001205DEFUN(cfg_mgcp_domain,
1206 cfg_mgcp_domain_cmd,
1207 "domain NAME", "domain\n" "qualified domain name\n")
1208{
1209 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1210 return CMD_SUCCESS;
1211}
1212
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001213int mgcp_vty_init(void)
1214{
1215 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001216 install_element(ENABLE_NODE, &loop_conn_cmd);
1217 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001218 install_element(ENABLE_NODE, &free_endp_cmd);
1219 install_element(ENABLE_NODE, &reset_endp_cmd);
1220 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1221
1222 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1223 install_node(&mgcp_node, config_write_mgcp);
1224
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001225 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001226 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1227 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1228 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001229 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001230 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001231 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001232 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001233 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001234 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001235 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1236 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001237 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1238 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1239 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1240 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1241 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1242 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1243 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1244 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1245 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001246 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1247 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1248 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1249 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1250 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1251 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001252 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001253 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1254 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1255 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1256 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1257 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1258 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1259 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1260 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1261 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1262 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1263 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1264 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1265 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1266 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1267 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1268 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1269 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1270 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1271 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1272 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1273 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001274 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001275
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001276 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1277 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001278 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1279 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1280 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1281 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1282 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1283 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1284 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1285 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1286 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1287 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1288 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1289 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1290 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1291 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1292 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1293 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1294 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1295 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1296 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1297 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1298 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1299 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1300
1301 return 0;
1302}
1303
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001304int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1305 enum mgcp_role role)
1306{
1307 int rc;
1308 struct mgcp_trunk_config *trunk;
1309
1310 cfg->osmux_port = OSMUX_PORT;
1311 cfg->osmux_batch = 4;
1312 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1313
1314 g_cfg = cfg;
1315 rc = vty_read_config_file(config_file, NULL);
1316 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001317 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1318 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001319 return rc;
1320 }
1321
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001322 if (!g_cfg->source_addr) {
1323 fprintf(stderr, "You need to specify a bind address.\n");
1324 return -1;
1325 }
1326
Philipp Maier48454982017-11-10 16:46:41 +01001327 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001328 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001329 "Failed to initialize the virtual trunk (%d endpoints)\n",
1330 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001331 return -1;
1332 }
1333
1334 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001335 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001336 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001337 "Failed to initialize trunk %d (%d endpoints)\n",
1338 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001339 return -1;
1340 }
1341 }
1342 cfg->role = role;
1343
1344 return 0;
1345}