blob: 7107bcc563396cb7f15bd0bf4698d0d1f7287ad5 [file] [log] [blame]
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
5 * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
6 * (C) 2009-2011 by On-Waves
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020024#include <osmocom/core/talloc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020025#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020026#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020027#include <osmocom/mgcp/mgcp_internal.h>
28#include <osmocom/mgcp/vty.h>
29#include <osmocom/mgcp/mgcp_conn.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020030
31#include <string.h>
32
33#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
34#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
35#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
36
37static struct mgcp_config *g_cfg = NULL;
38
39static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
40{
41 struct mgcp_trunk_config *trunk;
42
43 if (nr == 0)
44 trunk = &cfg->trunk;
45 else
46 trunk = mgcp_trunk_num(cfg, nr);
47
48 return trunk;
49}
50
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020051struct cmd_node mgcp_node = {
52 MGCP_NODE,
53 "%s(config-mgcp)# ",
54 1,
55};
56
57struct cmd_node trunk_node = {
58 TRUNK_NODE,
59 "%s(config-mgcp-trunk)# ",
60 1,
61};
62
63static int config_write_mgcp(struct vty *vty)
64{
65 vty_out(vty, "mgcp%s", VTY_NEWLINE);
66 if (g_cfg->local_ip)
67 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020068 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
69 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020070 vty_out(vty, " rtp net-range %u %u%s",
71 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
72 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020073
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020074 if (g_cfg->net_ports.bind_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +020075 vty_out(vty, " rtp net-bind-ip %s%s",
76 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020077
78 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
79 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
80 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
81 else if (g_cfg->trunk.keepalive_interval)
82 vty_out(vty, " rtp keep-alive %d%s",
83 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
84 else
85 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
86
87 if (g_cfg->trunk.omit_rtcp)
88 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
89 else
90 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020091 if (g_cfg->trunk.force_constant_ssrc
92 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020093 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020094 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
95 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020096 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020097 g_cfg->trunk.force_aligned_timing ? "" : "no ",
98 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020099 } else
100 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
101 if (g_cfg->trunk.audio_payload != -1)
102 vty_out(vty, " sdp audio-payload number %d%s",
103 g_cfg->trunk.audio_payload, VTY_NEWLINE);
104 if (g_cfg->trunk.audio_name)
105 vty_out(vty, " sdp audio-payload name %s%s",
106 g_cfg->trunk.audio_name, VTY_NEWLINE);
107 if (g_cfg->trunk.audio_fmtp_extra)
108 vty_out(vty, " sdp audio fmtp-extra %s%s",
109 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
110 vty_out(vty, " %ssdp audio-payload send-ptime%s",
111 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
112 vty_out(vty, " %ssdp audio-payload send-name%s",
113 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200114 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
115 vty_out(vty, " number endpoints %u%s",
116 g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200117 vty_out(vty, " %sallow-transcoding%s",
118 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
119 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200120 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
121 VTY_NEWLINE);
122 if (g_cfg->force_ptime > 0)
123 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
124 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200125
126 switch (g_cfg->osmux) {
127 case OSMUX_USAGE_ON:
128 vty_out(vty, " osmux on%s", VTY_NEWLINE);
129 break;
130 case OSMUX_USAGE_ONLY:
131 vty_out(vty, " osmux only%s", VTY_NEWLINE);
132 break;
133 case OSMUX_USAGE_OFF:
134 default:
135 vty_out(vty, " osmux off%s", VTY_NEWLINE);
136 break;
137 }
138 if (g_cfg->osmux) {
139 vty_out(vty, " osmux bind-ip %s%s",
140 g_cfg->osmux_addr, VTY_NEWLINE);
141 vty_out(vty, " osmux batch-factor %d%s",
142 g_cfg->osmux_batch, VTY_NEWLINE);
143 vty_out(vty, " osmux batch-size %u%s",
144 g_cfg->osmux_batch_size, VTY_NEWLINE);
145 vty_out(vty, " osmux port %u%s",
146 g_cfg->osmux_port, VTY_NEWLINE);
147 vty_out(vty, " osmux dummy %s%s",
148 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
149 }
150 return CMD_SUCCESS;
151}
152
Philipp Maier87bd9be2017-08-22 16:35:41 +0200153static void dump_rtp_end(struct vty *vty, struct mgcp_rtp_state *state,
154 struct mgcp_rtp_end *end)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200155{
156 struct mgcp_rtp_codec *codec = &end->codec;
157
158 vty_out(vty,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200159 " Timestamp Errs: %d->%d%s"
160 " Dropped Packets: %d%s"
161 " Payload Type: %d Rate: %u Channels: %d %s"
162 " Frame Duration: %u Frame Denominator: %u%s"
163 " FPP: %d Packet Duration: %u%s"
164 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
165 " Output-Enabled: %d Force-PTIME: %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200166 state->in_stream.err_ts_counter,
167 state->out_stream.err_ts_counter, VTY_NEWLINE,
168 end->dropped_packets, VTY_NEWLINE,
169 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200170 codec->frame_duration_num, codec->frame_duration_den,
171 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
172 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
173 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
174 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200175}
176
Philipp Maier87bd9be2017-08-22 16:35:41 +0200177static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
178 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200179{
180 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200181 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200182
183 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
184 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
185 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
186
187 if (!cfg->endpoints) {
188 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
189 return;
190 }
191
192 for (i = 1; i < cfg->number_endpoints; ++i) {
193 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200194
Philipp Maier87bd9be2017-08-22 16:35:41 +0200195 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
196
197 llist_for_each_entry(conn, &endp->conns, entry) {
198 vty_out(vty, " CONN: %s%s",
199 mgcp_conn_dump(conn), VTY_NEWLINE);
200
201 if (verbose) {
202 /* FIXME: Also add verbosity for other
203 * connection types (E1) as soon as
204 * the implementation is available */
205 if (conn->type == MGCP_CONN_TYPE_RTP) {
206 dump_rtp_end(vty, &conn->u.rtp.state,
207 &conn->u.rtp.end);
208 }
209 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200210 }
211 }
212}
213
214DEFUN(show_mcgp, show_mgcp_cmd,
215 "show mgcp [stats]",
216 SHOW_STR
217 "Display information about the MGCP Media Gateway\n"
218 "Include Statistics\n")
219{
220 struct mgcp_trunk_config *trunk;
221 int show_stats = argc >= 1;
222
223 dump_trunk(vty, &g_cfg->trunk, show_stats);
224
225 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200226 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200227
228 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200229 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
230 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200231
232 return CMD_SUCCESS;
233}
234
Philipp Maier87bd9be2017-08-22 16:35:41 +0200235DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200236{
237 vty->node = MGCP_NODE;
238 return CMD_SUCCESS;
239}
240
241DEFUN(cfg_mgcp_local_ip,
242 cfg_mgcp_local_ip_cmd,
243 "local ip A.B.C.D",
244 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200245 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200246{
247 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
248 return CMD_SUCCESS;
249}
250
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200251#define BIND_STR "Listen/Bind related socket option\n"
252DEFUN(cfg_mgcp_bind_ip,
253 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200254 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200255{
256 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
257 return CMD_SUCCESS;
258}
259
260DEFUN(cfg_mgcp_bind_port,
261 cfg_mgcp_bind_port_cmd,
262 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200263 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200264{
265 unsigned int port = atoi(argv[0]);
266 g_cfg->source_port = port;
267 return CMD_SUCCESS;
268}
269
270DEFUN(cfg_mgcp_bind_early,
271 cfg_mgcp_bind_early_cmd,
272 "bind early (0|1)",
273 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200274 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200275{
276 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
277 return CMD_WARNING;
278}
279
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200280static void parse_range(struct mgcp_port_range *range, const char **argv)
281{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200282 range->range_start = atoi(argv[0]);
283 range->range_end = atoi(argv[1]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200284 range->last_port = g_cfg->net_ports.range_start;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200285}
286
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200287#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200288#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200289#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200290#define RANGE_START_STR "Start of the range of ports\n"
291#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200292
293DEFUN(cfg_mgcp_rtp_net_range,
294 cfg_mgcp_rtp_net_range_cmd,
295 "rtp net-range <0-65534> <0-65534>",
296 RTP_STR "Range of ports to use for the NET side\n"
297 RANGE_START_STR RANGE_END_STR)
298{
299 parse_range(&g_cfg->net_ports, argv);
300 return CMD_SUCCESS;
301}
302
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200303DEFUN(cfg_mgcp_rtp_net_bind_ip,
304 cfg_mgcp_rtp_net_bind_ip_cmd,
305 "rtp net-bind-ip A.B.C.D",
306 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
307{
308 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
309 return CMD_SUCCESS;
310}
311
312DEFUN(cfg_mgcp_rtp_no_net_bind_ip,
313 cfg_mgcp_rtp_no_net_bind_ip_cmd,
314 "no rtp net-bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200315 NO_STR RTP_STR "Bind endpoints facing the Network\n"
316 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200317{
318 talloc_free(g_cfg->net_ports.bind_addr);
319 g_cfg->net_ports.bind_addr = NULL;
320 return CMD_SUCCESS;
321}
322
323DEFUN(cfg_mgcp_rtp_ip_dscp,
324 cfg_mgcp_rtp_ip_dscp_cmd,
325 "rtp ip-dscp <0-255>",
326 RTP_STR
327 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
328{
329 int dscp = atoi(argv[0]);
330 g_cfg->endp_dscp = dscp;
331 return CMD_SUCCESS;
332}
333
334ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200335 "rtp ip-tos <0-255>",
336 RTP_STR
337 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
338#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
339 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200340 cfg_mgcp_rtp_force_ptime_cmd,
341 "rtp force-ptime (10|20|40)",
342 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200343 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200344{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200345 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200346 return CMD_SUCCESS;
347}
348
349DEFUN(cfg_mgcp_no_rtp_force_ptime,
350 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200351 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200352{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200353 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200354 return CMD_SUCCESS;
355}
356
357DEFUN(cfg_mgcp_sdp_fmtp_extra,
358 cfg_mgcp_sdp_fmtp_extra_cmd,
359 "sdp audio fmtp-extra .NAME",
360 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
361 "Extra Information\n")
362{
363 char *txt = argv_concat(argv, argc, 0);
364 if (!txt)
365 return CMD_WARNING;
366
367 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
368 talloc_free(txt);
369 return CMD_SUCCESS;
370}
371
372DEFUN(cfg_mgcp_allow_transcoding,
373 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200374 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200375{
376 g_cfg->trunk.no_audio_transcoding = 0;
377 return CMD_SUCCESS;
378}
379
380DEFUN(cfg_mgcp_no_allow_transcoding,
381 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200382 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200383{
384 g_cfg->trunk.no_audio_transcoding = 1;
385 return CMD_SUCCESS;
386}
387
388#define SDP_STR "SDP File related options\n"
389#define AUDIO_STR "Audio payload options\n"
390DEFUN(cfg_mgcp_sdp_payload_number,
391 cfg_mgcp_sdp_payload_number_cmd,
392 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200393 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200394{
395 unsigned int payload = atoi(argv[0]);
396 g_cfg->trunk.audio_payload = payload;
397 return CMD_SUCCESS;
398}
399
Philipp Maier87bd9be2017-08-22 16:35:41 +0200400ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
401 cfg_mgcp_sdp_payload_number_cmd_old,
402 "sdp audio payload number <0-255>",
403 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200404
Philipp Maier87bd9be2017-08-22 16:35:41 +0200405 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200406 cfg_mgcp_sdp_payload_name_cmd,
407 "sdp audio-payload name NAME",
408 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
409{
410 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
411 return CMD_SUCCESS;
412}
413
414ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200415 "sdp audio payload name NAME",
416 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200417
Philipp Maier87bd9be2017-08-22 16:35:41 +0200418 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200419 cfg_mgcp_sdp_payload_send_ptime_cmd,
420 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200421 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200422{
423 g_cfg->trunk.audio_send_ptime = 1;
424 return CMD_SUCCESS;
425}
426
427DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
428 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
429 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200430 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200431{
432 g_cfg->trunk.audio_send_ptime = 0;
433 return CMD_SUCCESS;
434}
435
436DEFUN(cfg_mgcp_sdp_payload_send_name,
437 cfg_mgcp_sdp_payload_send_name_cmd,
438 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200439 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200440{
441 g_cfg->trunk.audio_send_name = 1;
442 return CMD_SUCCESS;
443}
444
445DEFUN(cfg_mgcp_no_sdp_payload_send_name,
446 cfg_mgcp_no_sdp_payload_send_name_cmd,
447 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200448 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200449{
450 g_cfg->trunk.audio_send_name = 0;
451 return CMD_SUCCESS;
452}
453
454DEFUN(cfg_mgcp_loop,
455 cfg_mgcp_loop_cmd,
456 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200457 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200458{
459 if (g_cfg->osmux) {
460 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
461 return CMD_WARNING;
462 }
463 g_cfg->trunk.audio_loop = atoi(argv[0]);
464 return CMD_SUCCESS;
465}
466
467DEFUN(cfg_mgcp_force_realloc,
468 cfg_mgcp_force_realloc_cmd,
469 "force-realloc (0|1)",
470 "Force endpoint reallocation when the endpoint is still seized\n"
471 "Don't force reallocation\n" "force reallocation\n")
472{
473 g_cfg->trunk.force_realloc = atoi(argv[0]);
474 return CMD_SUCCESS;
475}
476
Philipp Maier87bd9be2017-08-22 16:35:41 +0200477DEFUN(cfg_mgcp_rtp_accept_all,
478 cfg_mgcp_rtp_accept_all_cmd,
479 "rtp-accept-all (0|1)",
480 "Accept all RTP packets, even when the originating IP/Port does not match\n"
481 "enable filter\n" "disable filter\n")
482{
483 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
484 return CMD_SUCCESS;
485}
486
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200487DEFUN(cfg_mgcp_number_endp,
488 cfg_mgcp_number_endp_cmd,
489 "number endpoints <0-65534>",
490 "Number options\n" "Endpoints available\n" "Number endpoints\n")
491{
492 /* + 1 as we start counting at one */
493 g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
494 return CMD_SUCCESS;
495}
496
Philipp Maier87bd9be2017-08-22 16:35:41 +0200497DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200498{
499 g_cfg->trunk.omit_rtcp = 1;
500 return CMD_SUCCESS;
501}
502
503DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200504 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200505{
506 g_cfg->trunk.omit_rtcp = 0;
507 return CMD_SUCCESS;
508}
509
510DEFUN(cfg_mgcp_patch_rtp_ssrc,
511 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200512 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200513{
514 g_cfg->trunk.force_constant_ssrc = 1;
515 return CMD_SUCCESS;
516}
517
518DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
519 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200520 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200521{
522 g_cfg->trunk.force_constant_ssrc = 0;
523 return CMD_SUCCESS;
524}
525
526DEFUN(cfg_mgcp_patch_rtp_ts,
527 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200528 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200529{
530 g_cfg->trunk.force_aligned_timing = 1;
531 return CMD_SUCCESS;
532}
533
534DEFUN(cfg_mgcp_no_patch_rtp_ts,
535 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200536 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200537{
538 g_cfg->trunk.force_aligned_timing = 0;
539 return CMD_SUCCESS;
540}
541
542DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200543 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200544{
545 g_cfg->trunk.force_constant_ssrc = 0;
546 g_cfg->trunk.force_aligned_timing = 0;
547 return CMD_SUCCESS;
548}
549
550DEFUN(cfg_mgcp_rtp_keepalive,
551 cfg_mgcp_rtp_keepalive_cmd,
552 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200553 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200554{
555 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
556 return CMD_SUCCESS;
557}
558
559DEFUN(cfg_mgcp_rtp_keepalive_once,
560 cfg_mgcp_rtp_keepalive_once_cmd,
561 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200562 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200563{
564 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
565 return CMD_SUCCESS;
566}
567
568DEFUN(cfg_mgcp_no_rtp_keepalive,
569 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200570 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200571{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100572 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200573 return CMD_SUCCESS;
574}
575
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200576#define CALL_AGENT_STR "Callagent information\n"
577DEFUN(cfg_mgcp_agent_addr,
578 cfg_mgcp_agent_addr_cmd,
579 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200580 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200581{
582 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
583 return CMD_SUCCESS;
584}
585
586ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200587 "call agent ip A.B.C.D",
588 CALL_AGENT_STR CALL_AGENT_STR IP_STR
589 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200590
Philipp Maier87bd9be2017-08-22 16:35:41 +0200591 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
592 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200593{
594 struct mgcp_trunk_config *trunk;
595 int index = atoi(argv[0]);
596
597 trunk = mgcp_trunk_num(g_cfg, index);
598 if (!trunk)
599 trunk = mgcp_trunk_alloc(g_cfg, index);
600
601 if (!trunk) {
602 vty_out(vty, "%%Unable to allocate trunk %u.%s",
603 index, VTY_NEWLINE);
604 return CMD_WARNING;
605 }
606
607 vty->node = TRUNK_NODE;
608 vty->index = trunk;
609 return CMD_SUCCESS;
610}
611
612static int config_write_trunk(struct vty *vty)
613{
614 struct mgcp_trunk_config *trunk;
615
616 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
617 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
618 vty_out(vty, " sdp audio-payload number %d%s",
619 trunk->audio_payload, VTY_NEWLINE);
620 vty_out(vty, " sdp audio-payload name %s%s",
621 trunk->audio_name, VTY_NEWLINE);
622 vty_out(vty, " %ssdp audio-payload send-ptime%s",
623 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
624 vty_out(vty, " %ssdp audio-payload send-name%s",
625 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
626
627 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
628 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
629 else if (trunk->keepalive_interval)
630 vty_out(vty, " rtp keep-alive %d%s",
631 trunk->keepalive_interval, VTY_NEWLINE);
632 else
633 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200634 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200635 vty_out(vty, " force-realloc %d%s",
636 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200637 vty_out(vty, " rtp-accept-all %d%s",
638 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200639 if (trunk->omit_rtcp)
640 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
641 else
642 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
643 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
644 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200645 trunk->force_constant_ssrc ? "" : "no ",
646 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200647 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200648 trunk->force_aligned_timing ? "" : "no ",
649 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200650 } else
651 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
652 if (trunk->audio_fmtp_extra)
653 vty_out(vty, " sdp audio fmtp-extra %s%s",
654 trunk->audio_fmtp_extra, VTY_NEWLINE);
655 vty_out(vty, " %sallow-transcoding%s",
656 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
657 }
658
659 return CMD_SUCCESS;
660}
661
662DEFUN(cfg_trunk_sdp_fmtp_extra,
663 cfg_trunk_sdp_fmtp_extra_cmd,
664 "sdp audio fmtp-extra .NAME",
665 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
666 "Extra Information\n")
667{
668 struct mgcp_trunk_config *trunk = vty->index;
669 char *txt = argv_concat(argv, argc, 0);
670 if (!txt)
671 return CMD_WARNING;
672
673 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
674 talloc_free(txt);
675 return CMD_SUCCESS;
676}
677
678DEFUN(cfg_trunk_payload_number,
679 cfg_trunk_payload_number_cmd,
680 "sdp audio-payload number <0-255>",
681 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
682{
683 struct mgcp_trunk_config *trunk = vty->index;
684 unsigned int payload = atoi(argv[0]);
685
686 trunk->audio_payload = payload;
687 return CMD_SUCCESS;
688}
689
690ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200691 "sdp audio payload number <0-255>",
692 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200693
Philipp Maier87bd9be2017-08-22 16:35:41 +0200694 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200695 cfg_trunk_payload_name_cmd,
696 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200697 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200698{
699 struct mgcp_trunk_config *trunk = vty->index;
700
701 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
702 return CMD_SUCCESS;
703}
704
705ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200706 "sdp audio payload name NAME",
707 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200708
Philipp Maier87bd9be2017-08-22 16:35:41 +0200709 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200710 cfg_trunk_loop_cmd,
711 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200712 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200713{
714 struct mgcp_trunk_config *trunk = vty->index;
715
716 if (g_cfg->osmux) {
717 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
718 return CMD_WARNING;
719 }
720 trunk->audio_loop = atoi(argv[0]);
721 return CMD_SUCCESS;
722}
723
724DEFUN(cfg_trunk_sdp_payload_send_ptime,
725 cfg_trunk_sdp_payload_send_ptime_cmd,
726 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200727 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200728{
729 struct mgcp_trunk_config *trunk = vty->index;
730 trunk->audio_send_ptime = 1;
731 return CMD_SUCCESS;
732}
733
734DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
735 cfg_trunk_no_sdp_payload_send_ptime_cmd,
736 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200737 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200738{
739 struct mgcp_trunk_config *trunk = vty->index;
740 trunk->audio_send_ptime = 0;
741 return CMD_SUCCESS;
742}
743
744DEFUN(cfg_trunk_sdp_payload_send_name,
745 cfg_trunk_sdp_payload_send_name_cmd,
746 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200747 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200748{
749 struct mgcp_trunk_config *trunk = vty->index;
750 trunk->audio_send_name = 1;
751 return CMD_SUCCESS;
752}
753
754DEFUN(cfg_trunk_no_sdp_payload_send_name,
755 cfg_trunk_no_sdp_payload_send_name_cmd,
756 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200757 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200758{
759 struct mgcp_trunk_config *trunk = vty->index;
760 trunk->audio_send_name = 0;
761 return CMD_SUCCESS;
762}
763
Philipp Maier87bd9be2017-08-22 16:35:41 +0200764DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200765{
766 struct mgcp_trunk_config *trunk = vty->index;
767 trunk->omit_rtcp = 1;
768 return CMD_SUCCESS;
769}
770
771DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200772 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200773{
774 struct mgcp_trunk_config *trunk = vty->index;
775 trunk->omit_rtcp = 0;
776 return CMD_SUCCESS;
777}
778
779DEFUN(cfg_trunk_patch_rtp_ssrc,
780 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200781 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200782{
783 struct mgcp_trunk_config *trunk = vty->index;
784 trunk->force_constant_ssrc = 1;
785 return CMD_SUCCESS;
786}
787
788DEFUN(cfg_trunk_no_patch_rtp_ssrc,
789 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200790 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200791{
792 struct mgcp_trunk_config *trunk = vty->index;
793 trunk->force_constant_ssrc = 0;
794 return CMD_SUCCESS;
795}
796
797DEFUN(cfg_trunk_patch_rtp_ts,
798 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200799 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200800{
801 struct mgcp_trunk_config *trunk = vty->index;
802 trunk->force_aligned_timing = 1;
803 return CMD_SUCCESS;
804}
805
806DEFUN(cfg_trunk_no_patch_rtp_ts,
807 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200808 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200809{
810 struct mgcp_trunk_config *trunk = vty->index;
811 trunk->force_aligned_timing = 0;
812 return CMD_SUCCESS;
813}
814
815DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200816 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200817{
818 struct mgcp_trunk_config *trunk = vty->index;
819 trunk->force_constant_ssrc = 0;
820 trunk->force_aligned_timing = 0;
821 return CMD_SUCCESS;
822}
823
824DEFUN(cfg_trunk_rtp_keepalive,
825 cfg_trunk_rtp_keepalive_cmd,
826 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200827 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200828{
829 struct mgcp_trunk_config *trunk = vty->index;
830 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
831 return CMD_SUCCESS;
832}
833
834DEFUN(cfg_trunk_rtp_keepalive_once,
835 cfg_trunk_rtp_keepalive_once_cmd,
836 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200837 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200838{
839 struct mgcp_trunk_config *trunk = vty->index;
840 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
841 return CMD_SUCCESS;
842}
843
844DEFUN(cfg_trunk_no_rtp_keepalive,
845 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200846 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200847{
848 struct mgcp_trunk_config *trunk = vty->index;
849 mgcp_trunk_set_keepalive(trunk, 0);
850 return CMD_SUCCESS;
851}
852
853DEFUN(cfg_trunk_allow_transcoding,
854 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200855 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200856{
857 struct mgcp_trunk_config *trunk = vty->index;
858 trunk->no_audio_transcoding = 0;
859 return CMD_SUCCESS;
860}
861
862DEFUN(cfg_trunk_no_allow_transcoding,
863 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200864 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200865{
866 struct mgcp_trunk_config *trunk = vty->index;
867 trunk->no_audio_transcoding = 1;
868 return CMD_SUCCESS;
869}
870
Philipp Maier87bd9be2017-08-22 16:35:41 +0200871DEFUN(loop_conn,
872 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200873 "loop-endpoint <0-64> NAME (0|1)",
874 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200875 "The name in hex of the endpoint\n" "Disable the loop\n"
876 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200877{
878 struct mgcp_trunk_config *trunk;
879 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200880 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200881
882 trunk = find_trunk(g_cfg, atoi(argv[0]));
883 if (!trunk) {
884 vty_out(vty, "%%Trunk %d not found in the config.%s",
885 atoi(argv[0]), VTY_NEWLINE);
886 return CMD_WARNING;
887 }
888
889 if (!trunk->endpoints) {
890 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
891 trunk->trunk_nr, VTY_NEWLINE);
892 return CMD_WARNING;
893 }
894
895 int endp_no = strtoul(argv[1], NULL, 16);
896 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
897 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200898 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200899 return CMD_WARNING;
900 }
901
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200902 endp = &trunk->endpoints[endp_no];
903 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200904 llist_for_each_entry(conn, &endp->conns, entry) {
905 if (conn->type == MGCP_CONN_TYPE_RTP)
906 /* Handle it like a MDCX, switch on SSRC patching if enabled */
907 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
908 else {
909 /* FIXME: Introduce support for other connection (E1)
910 * types when implementation is available */
911 vty_out(vty, "%%Can't enable SSRC patching,"
912 "connection %s is not an RTP connection.%s",
913 mgcp_conn_dump(conn), VTY_NEWLINE);
914 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200915
Philipp Maier87bd9be2017-08-22 16:35:41 +0200916 if (loop)
917 conn->mode = MGCP_CONN_LOOPBACK;
918 else
919 conn->mode = conn->mode_orig;
920 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200921
922 return CMD_SUCCESS;
923}
924
Philipp Maier87bd9be2017-08-22 16:35:41 +0200925DEFUN(tap_rtp,
926 tap_rtp_cmd,
927 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200928 "Forward data on endpoint to a different system\n" "Trunk number\n"
929 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200930 "The connection id in hex\n"
931 "Forward incoming data\n"
932 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200933 "destination IP of the data\n" "destination port\n")
934{
935 struct mgcp_rtp_tap *tap;
936 struct mgcp_trunk_config *trunk;
937 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200938 struct mgcp_conn_rtp *conn;
939 uint32_t conn_id;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200940
941 trunk = find_trunk(g_cfg, atoi(argv[0]));
942 if (!trunk) {
943 vty_out(vty, "%%Trunk %d not found in the config.%s",
944 atoi(argv[0]), VTY_NEWLINE);
945 return CMD_WARNING;
946 }
947
948 if (!trunk->endpoints) {
949 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
950 trunk->trunk_nr, VTY_NEWLINE);
951 return CMD_WARNING;
952 }
953
954 int endp_no = strtoul(argv[1], NULL, 16);
955 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
956 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200957 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200958 return CMD_WARNING;
959 }
960
961 endp = &trunk->endpoints[endp_no];
962
Philipp Maier87bd9be2017-08-22 16:35:41 +0200963 conn_id = strtoul(argv[2], NULL, 10);
964 conn = mgcp_conn_get_rtp(endp, conn_id);
965 if (!conn) {
966 vty_out(vty, "Conn ID %s/%d is invalid.%s",
967 argv[2], conn_id, VTY_NEWLINE);
968 return CMD_WARNING;
969 }
970
971 if (strcmp(argv[3], "in") == 0)
972 tap = &conn->tap_in;
973 else if (strcmp(argv[3], "out") == 0)
974 tap = &conn->tap_out;
975 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200976 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
977 return CMD_WARNING;
978 }
979
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200980 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +0200981 inet_aton(argv[4], &tap->forward.sin_addr);
982 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200983 tap->enabled = 1;
984 return CMD_SUCCESS;
985}
986
987DEFUN(free_endp, free_endp_cmd,
988 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200989 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200990{
991 struct mgcp_trunk_config *trunk;
992 struct mgcp_endpoint *endp;
993
994 trunk = find_trunk(g_cfg, atoi(argv[0]));
995 if (!trunk) {
996 vty_out(vty, "%%Trunk %d not found in the config.%s",
997 atoi(argv[0]), VTY_NEWLINE);
998 return CMD_WARNING;
999 }
1000
1001 if (!trunk->endpoints) {
1002 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1003 trunk->trunk_nr, VTY_NEWLINE);
1004 return CMD_WARNING;
1005 }
1006
1007 int endp_no = strtoul(argv[1], NULL, 16);
1008 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1009 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001010 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001011 return CMD_WARNING;
1012 }
1013
1014 endp = &trunk->endpoints[endp_no];
1015 mgcp_release_endp(endp);
1016 return CMD_SUCCESS;
1017}
1018
1019DEFUN(reset_endp, reset_endp_cmd,
1020 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001021 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001022{
1023 struct mgcp_trunk_config *trunk;
1024 struct mgcp_endpoint *endp;
1025 int endp_no, rc;
1026
1027 trunk = find_trunk(g_cfg, atoi(argv[0]));
1028 if (!trunk) {
1029 vty_out(vty, "%%Trunk %d not found in the config.%s",
1030 atoi(argv[0]), VTY_NEWLINE);
1031 return CMD_WARNING;
1032 }
1033
1034 if (!trunk->endpoints) {
1035 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1036 trunk->trunk_nr, VTY_NEWLINE);
1037 return CMD_WARNING;
1038 }
1039
1040 endp_no = strtoul(argv[1], NULL, 16);
1041 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1042 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001043 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001044 return CMD_WARNING;
1045 }
1046
1047 endp = &trunk->endpoints[endp_no];
1048 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1049 if (rc < 0) {
1050 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1051 return CMD_WARNING;
1052 }
1053 return CMD_SUCCESS;
1054}
1055
1056DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001057 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001058{
1059 int rc;
1060
1061 rc = mgcp_send_reset_all(g_cfg);
1062 if (rc < 0) {
1063 vty_out(vty, "Error %d during endpoint reset.%s",
1064 rc, VTY_NEWLINE);
1065 return CMD_WARNING;
1066 }
1067 return CMD_SUCCESS;
1068}
1069
1070#define OSMUX_STR "RTP multiplexing\n"
1071DEFUN(cfg_mgcp_osmux,
1072 cfg_mgcp_osmux_cmd,
1073 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001074 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001075{
1076 if (strcmp(argv[0], "off") == 0) {
1077 g_cfg->osmux = OSMUX_USAGE_OFF;
1078 return CMD_SUCCESS;
1079 }
1080
Philipp Maier87bd9be2017-08-22 16:35:41 +02001081 /* Since OSMUX support is not finished, we do not
1082 * allow to turn it on yet. */
1083 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1084 return CMD_WARNING;
1085
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001086 if (strcmp(argv[0], "on") == 0)
1087 g_cfg->osmux = OSMUX_USAGE_ON;
1088 else if (strcmp(argv[0], "only") == 0)
1089 g_cfg->osmux = OSMUX_USAGE_ONLY;
1090
1091 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001092 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001093 return CMD_WARNING;
1094 }
1095
1096 return CMD_SUCCESS;
1097}
1098
1099DEFUN(cfg_mgcp_osmux_ip,
1100 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001101 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001102{
1103 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1104 return CMD_SUCCESS;
1105}
1106
1107DEFUN(cfg_mgcp_osmux_batch_factor,
1108 cfg_mgcp_osmux_batch_factor_cmd,
1109 "osmux batch-factor <1-8>",
1110 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1111{
1112 g_cfg->osmux_batch = atoi(argv[0]);
1113 return CMD_SUCCESS;
1114}
1115
1116DEFUN(cfg_mgcp_osmux_batch_size,
1117 cfg_mgcp_osmux_batch_size_cmd,
1118 "osmux batch-size <1-65535>",
1119 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1120{
1121 g_cfg->osmux_batch_size = atoi(argv[0]);
1122 return CMD_SUCCESS;
1123}
1124
1125DEFUN(cfg_mgcp_osmux_port,
1126 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001127 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001128{
1129 g_cfg->osmux_port = atoi(argv[0]);
1130 return CMD_SUCCESS;
1131}
1132
1133DEFUN(cfg_mgcp_osmux_dummy,
1134 cfg_mgcp_osmux_dummy_cmd,
1135 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001136 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1137 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001138{
1139 if (strcmp(argv[0], "on") == 0)
1140 g_cfg->osmux_dummy = 1;
1141 else if (strcmp(argv[0], "off") == 0)
1142 g_cfg->osmux_dummy = 0;
1143
1144 return CMD_SUCCESS;
1145}
1146
1147int mgcp_vty_init(void)
1148{
1149 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001150 install_element(ENABLE_NODE, &loop_conn_cmd);
1151 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001152 install_element(ENABLE_NODE, &free_endp_cmd);
1153 install_element(ENABLE_NODE, &reset_endp_cmd);
1154 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1155
1156 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1157 install_node(&mgcp_node, config_write_mgcp);
1158
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001159 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001160 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1161 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1162 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001163 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
1164 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
1165 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001166 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1167 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1168 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1169 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1170 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1171 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1172 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1173 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1174 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001175 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1176 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1177 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1178 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1179 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1180 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001181 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001182 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1183 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1184 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1185 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1186 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1187 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1188 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1189 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1190 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1191 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1192 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1193 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1194 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1195 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1196 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1197 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1198 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1199 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1200 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1201 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1202 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
1203
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001204 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1205 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001206 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1207 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1208 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1209 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1210 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1211 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1212 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1213 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1214 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1215 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1216 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1217 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1218 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1219 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1220 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1221 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1222 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1223 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1224 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1225 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1226 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1227 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1228
1229 return 0;
1230}
1231
1232static int allocate_trunk(struct mgcp_trunk_config *trunk)
1233{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001234 if (mgcp_endpoints_allocate(trunk) != 0) {
1235 LOGP(DLMGCP, LOGL_ERROR,
1236 "Failed to allocate %d endpoints on trunk %d.\n",
1237 trunk->number_endpoints, trunk->trunk_nr);
1238 return -1;
1239 }
1240
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001241 return 0;
1242}
1243
1244int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1245 enum mgcp_role role)
1246{
1247 int rc;
1248 struct mgcp_trunk_config *trunk;
1249
1250 cfg->osmux_port = OSMUX_PORT;
1251 cfg->osmux_batch = 4;
1252 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1253
1254 g_cfg = cfg;
1255 rc = vty_read_config_file(config_file, NULL);
1256 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001257 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1258 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001259 return rc;
1260 }
1261
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001262 if (!g_cfg->source_addr) {
1263 fprintf(stderr, "You need to specify a bind address.\n");
1264 return -1;
1265 }
1266
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001267 if (allocate_trunk(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001268 LOGP(DLMGCP, LOGL_ERROR,
1269 "Failed to initialize the virtual trunk.\n");
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001270 return -1;
1271 }
1272
1273 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
1274 if (allocate_trunk(trunk) != 0) {
1275 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001276 "Failed to initialize E1 trunk %d.\n",
1277 trunk->trunk_nr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001278 return -1;
1279 }
1280 }
1281 cfg->role = role;
1282
1283 return 0;
1284}