blob: 7ff1fddab95cbd271b1b1726affc03a7211c1f28 [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 if (g_cfg->net_ports.bind_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +020074 vty_out(vty, " rtp net-bind-ip %s%s",
75 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010076 if (g_cfg->net_ports.bind_addr_probe)
77 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
78 else
79 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020080 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
81 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
82 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
83 else if (g_cfg->trunk.keepalive_interval)
84 vty_out(vty, " rtp keep-alive %d%s",
85 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
86 else
87 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
88
89 if (g_cfg->trunk.omit_rtcp)
90 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
91 else
92 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020093 if (g_cfg->trunk.force_constant_ssrc
94 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020095 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020096 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
97 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020098 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020099 g_cfg->trunk.force_aligned_timing ? "" : "no ",
100 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200101 } else
102 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
103 if (g_cfg->trunk.audio_payload != -1)
104 vty_out(vty, " sdp audio-payload number %d%s",
105 g_cfg->trunk.audio_payload, VTY_NEWLINE);
106 if (g_cfg->trunk.audio_name)
107 vty_out(vty, " sdp audio-payload name %s%s",
108 g_cfg->trunk.audio_name, VTY_NEWLINE);
109 if (g_cfg->trunk.audio_fmtp_extra)
110 vty_out(vty, " sdp audio fmtp-extra %s%s",
111 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
112 vty_out(vty, " %ssdp audio-payload send-ptime%s",
113 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
114 vty_out(vty, " %ssdp audio-payload send-name%s",
115 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200116 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
117 vty_out(vty, " number endpoints %u%s",
118 g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200119 vty_out(vty, " %sallow-transcoding%s",
120 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
121 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200122 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
123 VTY_NEWLINE);
124 if (g_cfg->force_ptime > 0)
125 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
126 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200127
128 switch (g_cfg->osmux) {
129 case OSMUX_USAGE_ON:
130 vty_out(vty, " osmux on%s", VTY_NEWLINE);
131 break;
132 case OSMUX_USAGE_ONLY:
133 vty_out(vty, " osmux only%s", VTY_NEWLINE);
134 break;
135 case OSMUX_USAGE_OFF:
136 default:
137 vty_out(vty, " osmux off%s", VTY_NEWLINE);
138 break;
139 }
140 if (g_cfg->osmux) {
141 vty_out(vty, " osmux bind-ip %s%s",
142 g_cfg->osmux_addr, VTY_NEWLINE);
143 vty_out(vty, " osmux batch-factor %d%s",
144 g_cfg->osmux_batch, VTY_NEWLINE);
145 vty_out(vty, " osmux batch-size %u%s",
146 g_cfg->osmux_batch_size, VTY_NEWLINE);
147 vty_out(vty, " osmux port %u%s",
148 g_cfg->osmux_port, VTY_NEWLINE);
149 vty_out(vty, " osmux dummy %s%s",
150 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
151 }
152 return CMD_SUCCESS;
153}
154
Philipp Maier87bd9be2017-08-22 16:35:41 +0200155static void dump_rtp_end(struct vty *vty, struct mgcp_rtp_state *state,
156 struct mgcp_rtp_end *end)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200157{
158 struct mgcp_rtp_codec *codec = &end->codec;
159
160 vty_out(vty,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200161 " Timestamp Errs: %d->%d%s"
162 " Dropped Packets: %d%s"
163 " Payload Type: %d Rate: %u Channels: %d %s"
164 " Frame Duration: %u Frame Denominator: %u%s"
165 " FPP: %d Packet Duration: %u%s"
166 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
167 " Output-Enabled: %d Force-PTIME: %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200168 state->in_stream.err_ts_counter,
169 state->out_stream.err_ts_counter, VTY_NEWLINE,
170 end->dropped_packets, VTY_NEWLINE,
171 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200172 codec->frame_duration_num, codec->frame_duration_den,
173 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
174 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
175 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
176 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200177}
178
Philipp Maier87bd9be2017-08-22 16:35:41 +0200179static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg,
180 int verbose)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200181{
182 int i;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200183 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200184
185 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
186 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
187 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
188
189 if (!cfg->endpoints) {
190 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
191 return;
192 }
193
194 for (i = 1; i < cfg->number_endpoints; ++i) {
195 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200196
Philipp Maier87bd9be2017-08-22 16:35:41 +0200197 vty_out(vty, "Endpoint 0x%.2x:%s", i, VTY_NEWLINE);
198
199 llist_for_each_entry(conn, &endp->conns, entry) {
200 vty_out(vty, " CONN: %s%s",
201 mgcp_conn_dump(conn), VTY_NEWLINE);
202
203 if (verbose) {
204 /* FIXME: Also add verbosity for other
205 * connection types (E1) as soon as
206 * the implementation is available */
207 if (conn->type == MGCP_CONN_TYPE_RTP) {
208 dump_rtp_end(vty, &conn->u.rtp.state,
209 &conn->u.rtp.end);
210 }
211 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200212 }
213 }
214}
215
216DEFUN(show_mcgp, show_mgcp_cmd,
217 "show mgcp [stats]",
218 SHOW_STR
219 "Display information about the MGCP Media Gateway\n"
220 "Include Statistics\n")
221{
222 struct mgcp_trunk_config *trunk;
223 int show_stats = argc >= 1;
224
225 dump_trunk(vty, &g_cfg->trunk, show_stats);
226
227 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200228 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200229
230 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200231 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
232 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200233
234 return CMD_SUCCESS;
235}
236
Philipp Maier87bd9be2017-08-22 16:35:41 +0200237DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200238{
239 vty->node = MGCP_NODE;
240 return CMD_SUCCESS;
241}
242
243DEFUN(cfg_mgcp_local_ip,
244 cfg_mgcp_local_ip_cmd,
245 "local ip A.B.C.D",
246 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200247 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200248{
249 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
250 return CMD_SUCCESS;
251}
252
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200253#define BIND_STR "Listen/Bind related socket option\n"
254DEFUN(cfg_mgcp_bind_ip,
255 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200256 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200257{
258 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
259 return CMD_SUCCESS;
260}
261
262DEFUN(cfg_mgcp_bind_port,
263 cfg_mgcp_bind_port_cmd,
264 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200265 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200266{
267 unsigned int port = atoi(argv[0]);
268 g_cfg->source_port = port;
269 return CMD_SUCCESS;
270}
271
272DEFUN(cfg_mgcp_bind_early,
273 cfg_mgcp_bind_early_cmd,
274 "bind early (0|1)",
275 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200276 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200277{
278 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
279 return CMD_WARNING;
280}
281
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200282static void parse_range(struct mgcp_port_range *range, const char **argv)
283{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200284 range->range_start = atoi(argv[0]);
285 range->range_end = atoi(argv[1]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200286 range->last_port = g_cfg->net_ports.range_start;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200287}
288
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200289#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200290#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200291#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200292#define RANGE_START_STR "Start of the range of ports\n"
293#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200294
295DEFUN(cfg_mgcp_rtp_net_range,
296 cfg_mgcp_rtp_net_range_cmd,
297 "rtp net-range <0-65534> <0-65534>",
298 RTP_STR "Range of ports to use for the NET side\n"
299 RANGE_START_STR RANGE_END_STR)
300{
301 parse_range(&g_cfg->net_ports, argv);
302 return CMD_SUCCESS;
303}
304
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200305DEFUN(cfg_mgcp_rtp_net_bind_ip,
306 cfg_mgcp_rtp_net_bind_ip_cmd,
307 "rtp net-bind-ip A.B.C.D",
308 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
309{
310 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
311 return CMD_SUCCESS;
312}
313
314DEFUN(cfg_mgcp_rtp_no_net_bind_ip,
315 cfg_mgcp_rtp_no_net_bind_ip_cmd,
316 "no rtp net-bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200317 NO_STR RTP_STR "Bind endpoints facing the Network\n"
318 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200319{
320 talloc_free(g_cfg->net_ports.bind_addr);
321 g_cfg->net_ports.bind_addr = NULL;
322 return CMD_SUCCESS;
323}
324
Philipp Maier1cb1e382017-11-02 17:16:04 +0100325DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
326 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
327 "rtp ip-probing",
328 RTP_STR "automatic rtp bind ip selection\n")
329{
330 g_cfg->net_ports.bind_addr_probe = true;
331 return CMD_SUCCESS;
332}
333
334DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
335 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
336 "no rtp ip-probing",
337 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
338{
339 g_cfg->net_ports.bind_addr_probe = false;
340 return CMD_SUCCESS;
341}
342
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200343DEFUN(cfg_mgcp_rtp_ip_dscp,
344 cfg_mgcp_rtp_ip_dscp_cmd,
345 "rtp ip-dscp <0-255>",
346 RTP_STR
347 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
348{
349 int dscp = atoi(argv[0]);
350 g_cfg->endp_dscp = dscp;
351 return CMD_SUCCESS;
352}
353
354ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200355 "rtp ip-tos <0-255>",
356 RTP_STR
357 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
358#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
359 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200360 cfg_mgcp_rtp_force_ptime_cmd,
361 "rtp force-ptime (10|20|40)",
362 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200363 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200364{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200365 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200366 return CMD_SUCCESS;
367}
368
369DEFUN(cfg_mgcp_no_rtp_force_ptime,
370 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200371 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200372{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200373 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200374 return CMD_SUCCESS;
375}
376
377DEFUN(cfg_mgcp_sdp_fmtp_extra,
378 cfg_mgcp_sdp_fmtp_extra_cmd,
379 "sdp audio fmtp-extra .NAME",
380 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
381 "Extra Information\n")
382{
383 char *txt = argv_concat(argv, argc, 0);
384 if (!txt)
385 return CMD_WARNING;
386
387 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
388 talloc_free(txt);
389 return CMD_SUCCESS;
390}
391
392DEFUN(cfg_mgcp_allow_transcoding,
393 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200394 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200395{
396 g_cfg->trunk.no_audio_transcoding = 0;
397 return CMD_SUCCESS;
398}
399
400DEFUN(cfg_mgcp_no_allow_transcoding,
401 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200402 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200403{
404 g_cfg->trunk.no_audio_transcoding = 1;
405 return CMD_SUCCESS;
406}
407
408#define SDP_STR "SDP File related options\n"
409#define AUDIO_STR "Audio payload options\n"
410DEFUN(cfg_mgcp_sdp_payload_number,
411 cfg_mgcp_sdp_payload_number_cmd,
412 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200413 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200414{
415 unsigned int payload = atoi(argv[0]);
416 g_cfg->trunk.audio_payload = payload;
417 return CMD_SUCCESS;
418}
419
Philipp Maier87bd9be2017-08-22 16:35:41 +0200420ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
421 cfg_mgcp_sdp_payload_number_cmd_old,
422 "sdp audio payload number <0-255>",
423 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200424
Philipp Maier87bd9be2017-08-22 16:35:41 +0200425 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200426 cfg_mgcp_sdp_payload_name_cmd,
427 "sdp audio-payload name NAME",
428 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
429{
430 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
431 return CMD_SUCCESS;
432}
433
434ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200435 "sdp audio payload name NAME",
436 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200437
Philipp Maier87bd9be2017-08-22 16:35:41 +0200438 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200439 cfg_mgcp_sdp_payload_send_ptime_cmd,
440 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200441 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200442{
443 g_cfg->trunk.audio_send_ptime = 1;
444 return CMD_SUCCESS;
445}
446
447DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
448 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
449 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200450 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200451{
452 g_cfg->trunk.audio_send_ptime = 0;
453 return CMD_SUCCESS;
454}
455
456DEFUN(cfg_mgcp_sdp_payload_send_name,
457 cfg_mgcp_sdp_payload_send_name_cmd,
458 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200459 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200460{
461 g_cfg->trunk.audio_send_name = 1;
462 return CMD_SUCCESS;
463}
464
465DEFUN(cfg_mgcp_no_sdp_payload_send_name,
466 cfg_mgcp_no_sdp_payload_send_name_cmd,
467 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200468 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200469{
470 g_cfg->trunk.audio_send_name = 0;
471 return CMD_SUCCESS;
472}
473
474DEFUN(cfg_mgcp_loop,
475 cfg_mgcp_loop_cmd,
476 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200477 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200478{
479 if (g_cfg->osmux) {
480 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
481 return CMD_WARNING;
482 }
483 g_cfg->trunk.audio_loop = atoi(argv[0]);
484 return CMD_SUCCESS;
485}
486
487DEFUN(cfg_mgcp_force_realloc,
488 cfg_mgcp_force_realloc_cmd,
489 "force-realloc (0|1)",
490 "Force endpoint reallocation when the endpoint is still seized\n"
491 "Don't force reallocation\n" "force reallocation\n")
492{
493 g_cfg->trunk.force_realloc = atoi(argv[0]);
494 return CMD_SUCCESS;
495}
496
Philipp Maier87bd9be2017-08-22 16:35:41 +0200497DEFUN(cfg_mgcp_rtp_accept_all,
498 cfg_mgcp_rtp_accept_all_cmd,
499 "rtp-accept-all (0|1)",
500 "Accept all RTP packets, even when the originating IP/Port does not match\n"
501 "enable filter\n" "disable filter\n")
502{
503 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
504 return CMD_SUCCESS;
505}
506
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200507DEFUN(cfg_mgcp_number_endp,
508 cfg_mgcp_number_endp_cmd,
509 "number endpoints <0-65534>",
510 "Number options\n" "Endpoints available\n" "Number endpoints\n")
511{
512 /* + 1 as we start counting at one */
513 g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
514 return CMD_SUCCESS;
515}
516
Philipp Maier87bd9be2017-08-22 16:35:41 +0200517DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200518{
519 g_cfg->trunk.omit_rtcp = 1;
520 return CMD_SUCCESS;
521}
522
523DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200524 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200525{
526 g_cfg->trunk.omit_rtcp = 0;
527 return CMD_SUCCESS;
528}
529
530DEFUN(cfg_mgcp_patch_rtp_ssrc,
531 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200532 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200533{
534 g_cfg->trunk.force_constant_ssrc = 1;
535 return CMD_SUCCESS;
536}
537
538DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
539 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200540 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200541{
542 g_cfg->trunk.force_constant_ssrc = 0;
543 return CMD_SUCCESS;
544}
545
546DEFUN(cfg_mgcp_patch_rtp_ts,
547 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200548 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200549{
550 g_cfg->trunk.force_aligned_timing = 1;
551 return CMD_SUCCESS;
552}
553
554DEFUN(cfg_mgcp_no_patch_rtp_ts,
555 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200556 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200557{
558 g_cfg->trunk.force_aligned_timing = 0;
559 return CMD_SUCCESS;
560}
561
562DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200563 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200564{
565 g_cfg->trunk.force_constant_ssrc = 0;
566 g_cfg->trunk.force_aligned_timing = 0;
567 return CMD_SUCCESS;
568}
569
570DEFUN(cfg_mgcp_rtp_keepalive,
571 cfg_mgcp_rtp_keepalive_cmd,
572 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200573 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200574{
575 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
576 return CMD_SUCCESS;
577}
578
579DEFUN(cfg_mgcp_rtp_keepalive_once,
580 cfg_mgcp_rtp_keepalive_once_cmd,
581 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200582 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200583{
584 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
585 return CMD_SUCCESS;
586}
587
588DEFUN(cfg_mgcp_no_rtp_keepalive,
589 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200590 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200591{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100592 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200593 return CMD_SUCCESS;
594}
595
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200596#define CALL_AGENT_STR "Callagent information\n"
597DEFUN(cfg_mgcp_agent_addr,
598 cfg_mgcp_agent_addr_cmd,
599 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200600 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200601{
602 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
603 return CMD_SUCCESS;
604}
605
606ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200607 "call agent ip A.B.C.D",
608 CALL_AGENT_STR CALL_AGENT_STR IP_STR
609 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200610
Philipp Maier87bd9be2017-08-22 16:35:41 +0200611 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
612 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200613{
614 struct mgcp_trunk_config *trunk;
615 int index = atoi(argv[0]);
616
617 trunk = mgcp_trunk_num(g_cfg, index);
618 if (!trunk)
619 trunk = mgcp_trunk_alloc(g_cfg, index);
620
621 if (!trunk) {
622 vty_out(vty, "%%Unable to allocate trunk %u.%s",
623 index, VTY_NEWLINE);
624 return CMD_WARNING;
625 }
626
627 vty->node = TRUNK_NODE;
628 vty->index = trunk;
629 return CMD_SUCCESS;
630}
631
632static int config_write_trunk(struct vty *vty)
633{
634 struct mgcp_trunk_config *trunk;
635
636 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
637 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
638 vty_out(vty, " sdp audio-payload number %d%s",
639 trunk->audio_payload, VTY_NEWLINE);
640 vty_out(vty, " sdp audio-payload name %s%s",
641 trunk->audio_name, VTY_NEWLINE);
642 vty_out(vty, " %ssdp audio-payload send-ptime%s",
643 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
644 vty_out(vty, " %ssdp audio-payload send-name%s",
645 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
646
647 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
648 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
649 else if (trunk->keepalive_interval)
650 vty_out(vty, " rtp keep-alive %d%s",
651 trunk->keepalive_interval, VTY_NEWLINE);
652 else
653 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200654 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200655 vty_out(vty, " force-realloc %d%s",
656 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200657 vty_out(vty, " rtp-accept-all %d%s",
658 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200659 if (trunk->omit_rtcp)
660 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
661 else
662 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
663 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
664 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200665 trunk->force_constant_ssrc ? "" : "no ",
666 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200667 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200668 trunk->force_aligned_timing ? "" : "no ",
669 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200670 } else
671 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
672 if (trunk->audio_fmtp_extra)
673 vty_out(vty, " sdp audio fmtp-extra %s%s",
674 trunk->audio_fmtp_extra, VTY_NEWLINE);
675 vty_out(vty, " %sallow-transcoding%s",
676 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
677 }
678
679 return CMD_SUCCESS;
680}
681
682DEFUN(cfg_trunk_sdp_fmtp_extra,
683 cfg_trunk_sdp_fmtp_extra_cmd,
684 "sdp audio fmtp-extra .NAME",
685 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
686 "Extra Information\n")
687{
688 struct mgcp_trunk_config *trunk = vty->index;
689 char *txt = argv_concat(argv, argc, 0);
690 if (!txt)
691 return CMD_WARNING;
692
693 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
694 talloc_free(txt);
695 return CMD_SUCCESS;
696}
697
698DEFUN(cfg_trunk_payload_number,
699 cfg_trunk_payload_number_cmd,
700 "sdp audio-payload number <0-255>",
701 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
702{
703 struct mgcp_trunk_config *trunk = vty->index;
704 unsigned int payload = atoi(argv[0]);
705
706 trunk->audio_payload = payload;
707 return CMD_SUCCESS;
708}
709
710ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200711 "sdp audio payload number <0-255>",
712 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200713
Philipp Maier87bd9be2017-08-22 16:35:41 +0200714 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200715 cfg_trunk_payload_name_cmd,
716 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200717 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200718{
719 struct mgcp_trunk_config *trunk = vty->index;
720
721 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
722 return CMD_SUCCESS;
723}
724
725ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200726 "sdp audio payload name NAME",
727 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200728
Philipp Maier87bd9be2017-08-22 16:35:41 +0200729 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730 cfg_trunk_loop_cmd,
731 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200732 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200733{
734 struct mgcp_trunk_config *trunk = vty->index;
735
736 if (g_cfg->osmux) {
737 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
738 return CMD_WARNING;
739 }
740 trunk->audio_loop = atoi(argv[0]);
741 return CMD_SUCCESS;
742}
743
744DEFUN(cfg_trunk_sdp_payload_send_ptime,
745 cfg_trunk_sdp_payload_send_ptime_cmd,
746 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200747 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200748{
749 struct mgcp_trunk_config *trunk = vty->index;
750 trunk->audio_send_ptime = 1;
751 return CMD_SUCCESS;
752}
753
754DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
755 cfg_trunk_no_sdp_payload_send_ptime_cmd,
756 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200757 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200758{
759 struct mgcp_trunk_config *trunk = vty->index;
760 trunk->audio_send_ptime = 0;
761 return CMD_SUCCESS;
762}
763
764DEFUN(cfg_trunk_sdp_payload_send_name,
765 cfg_trunk_sdp_payload_send_name_cmd,
766 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200767 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200768{
769 struct mgcp_trunk_config *trunk = vty->index;
770 trunk->audio_send_name = 1;
771 return CMD_SUCCESS;
772}
773
774DEFUN(cfg_trunk_no_sdp_payload_send_name,
775 cfg_trunk_no_sdp_payload_send_name_cmd,
776 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200777 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200778{
779 struct mgcp_trunk_config *trunk = vty->index;
780 trunk->audio_send_name = 0;
781 return CMD_SUCCESS;
782}
783
Philipp Maier87bd9be2017-08-22 16:35:41 +0200784DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200785{
786 struct mgcp_trunk_config *trunk = vty->index;
787 trunk->omit_rtcp = 1;
788 return CMD_SUCCESS;
789}
790
791DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200792 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200793{
794 struct mgcp_trunk_config *trunk = vty->index;
795 trunk->omit_rtcp = 0;
796 return CMD_SUCCESS;
797}
798
799DEFUN(cfg_trunk_patch_rtp_ssrc,
800 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200801 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200802{
803 struct mgcp_trunk_config *trunk = vty->index;
804 trunk->force_constant_ssrc = 1;
805 return CMD_SUCCESS;
806}
807
808DEFUN(cfg_trunk_no_patch_rtp_ssrc,
809 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200810 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200811{
812 struct mgcp_trunk_config *trunk = vty->index;
813 trunk->force_constant_ssrc = 0;
814 return CMD_SUCCESS;
815}
816
817DEFUN(cfg_trunk_patch_rtp_ts,
818 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200819 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200820{
821 struct mgcp_trunk_config *trunk = vty->index;
822 trunk->force_aligned_timing = 1;
823 return CMD_SUCCESS;
824}
825
826DEFUN(cfg_trunk_no_patch_rtp_ts,
827 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200828 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200829{
830 struct mgcp_trunk_config *trunk = vty->index;
831 trunk->force_aligned_timing = 0;
832 return CMD_SUCCESS;
833}
834
835DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200836 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200837{
838 struct mgcp_trunk_config *trunk = vty->index;
839 trunk->force_constant_ssrc = 0;
840 trunk->force_aligned_timing = 0;
841 return CMD_SUCCESS;
842}
843
844DEFUN(cfg_trunk_rtp_keepalive,
845 cfg_trunk_rtp_keepalive_cmd,
846 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200847 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200848{
849 struct mgcp_trunk_config *trunk = vty->index;
850 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
851 return CMD_SUCCESS;
852}
853
854DEFUN(cfg_trunk_rtp_keepalive_once,
855 cfg_trunk_rtp_keepalive_once_cmd,
856 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200857 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200858{
859 struct mgcp_trunk_config *trunk = vty->index;
860 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
861 return CMD_SUCCESS;
862}
863
864DEFUN(cfg_trunk_no_rtp_keepalive,
865 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200866 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200867{
868 struct mgcp_trunk_config *trunk = vty->index;
869 mgcp_trunk_set_keepalive(trunk, 0);
870 return CMD_SUCCESS;
871}
872
873DEFUN(cfg_trunk_allow_transcoding,
874 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200875 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200876{
877 struct mgcp_trunk_config *trunk = vty->index;
878 trunk->no_audio_transcoding = 0;
879 return CMD_SUCCESS;
880}
881
882DEFUN(cfg_trunk_no_allow_transcoding,
883 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200884 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200885{
886 struct mgcp_trunk_config *trunk = vty->index;
887 trunk->no_audio_transcoding = 1;
888 return CMD_SUCCESS;
889}
890
Philipp Maier87bd9be2017-08-22 16:35:41 +0200891DEFUN(loop_conn,
892 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200893 "loop-endpoint <0-64> NAME (0|1)",
894 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200895 "The name in hex of the endpoint\n" "Disable the loop\n"
896 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200897{
898 struct mgcp_trunk_config *trunk;
899 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200900 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200901
902 trunk = find_trunk(g_cfg, atoi(argv[0]));
903 if (!trunk) {
904 vty_out(vty, "%%Trunk %d not found in the config.%s",
905 atoi(argv[0]), VTY_NEWLINE);
906 return CMD_WARNING;
907 }
908
909 if (!trunk->endpoints) {
910 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
911 trunk->trunk_nr, VTY_NEWLINE);
912 return CMD_WARNING;
913 }
914
915 int endp_no = strtoul(argv[1], NULL, 16);
916 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
917 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200918 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200919 return CMD_WARNING;
920 }
921
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200922 endp = &trunk->endpoints[endp_no];
923 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200924 llist_for_each_entry(conn, &endp->conns, entry) {
925 if (conn->type == MGCP_CONN_TYPE_RTP)
926 /* Handle it like a MDCX, switch on SSRC patching if enabled */
927 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
928 else {
929 /* FIXME: Introduce support for other connection (E1)
930 * types when implementation is available */
931 vty_out(vty, "%%Can't enable SSRC patching,"
932 "connection %s is not an RTP connection.%s",
933 mgcp_conn_dump(conn), VTY_NEWLINE);
934 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200935
Philipp Maier87bd9be2017-08-22 16:35:41 +0200936 if (loop)
937 conn->mode = MGCP_CONN_LOOPBACK;
938 else
939 conn->mode = conn->mode_orig;
940 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200941
942 return CMD_SUCCESS;
943}
944
Philipp Maier87bd9be2017-08-22 16:35:41 +0200945DEFUN(tap_rtp,
946 tap_rtp_cmd,
947 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200948 "Forward data on endpoint to a different system\n" "Trunk number\n"
949 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200950 "The connection id in hex\n"
951 "Forward incoming data\n"
952 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200953 "destination IP of the data\n" "destination port\n")
954{
955 struct mgcp_rtp_tap *tap;
956 struct mgcp_trunk_config *trunk;
957 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +0200958 struct mgcp_conn_rtp *conn;
959 uint32_t conn_id;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200960
961 trunk = find_trunk(g_cfg, atoi(argv[0]));
962 if (!trunk) {
963 vty_out(vty, "%%Trunk %d not found in the config.%s",
964 atoi(argv[0]), VTY_NEWLINE);
965 return CMD_WARNING;
966 }
967
968 if (!trunk->endpoints) {
969 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
970 trunk->trunk_nr, VTY_NEWLINE);
971 return CMD_WARNING;
972 }
973
974 int endp_no = strtoul(argv[1], NULL, 16);
975 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
976 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200977 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200978 return CMD_WARNING;
979 }
980
981 endp = &trunk->endpoints[endp_no];
982
Philipp Maier87bd9be2017-08-22 16:35:41 +0200983 conn_id = strtoul(argv[2], NULL, 10);
984 conn = mgcp_conn_get_rtp(endp, conn_id);
985 if (!conn) {
986 vty_out(vty, "Conn ID %s/%d is invalid.%s",
987 argv[2], conn_id, VTY_NEWLINE);
988 return CMD_WARNING;
989 }
990
991 if (strcmp(argv[3], "in") == 0)
992 tap = &conn->tap_in;
993 else if (strcmp(argv[3], "out") == 0)
994 tap = &conn->tap_out;
995 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200996 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
997 return CMD_WARNING;
998 }
999
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001001 inet_aton(argv[4], &tap->forward.sin_addr);
1002 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001003 tap->enabled = 1;
1004 return CMD_SUCCESS;
1005}
1006
1007DEFUN(free_endp, free_endp_cmd,
1008 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001009 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001010{
1011 struct mgcp_trunk_config *trunk;
1012 struct mgcp_endpoint *endp;
1013
1014 trunk = find_trunk(g_cfg, atoi(argv[0]));
1015 if (!trunk) {
1016 vty_out(vty, "%%Trunk %d not found in the config.%s",
1017 atoi(argv[0]), VTY_NEWLINE);
1018 return CMD_WARNING;
1019 }
1020
1021 if (!trunk->endpoints) {
1022 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1023 trunk->trunk_nr, VTY_NEWLINE);
1024 return CMD_WARNING;
1025 }
1026
1027 int endp_no = strtoul(argv[1], NULL, 16);
1028 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1029 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001030 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001031 return CMD_WARNING;
1032 }
1033
1034 endp = &trunk->endpoints[endp_no];
1035 mgcp_release_endp(endp);
1036 return CMD_SUCCESS;
1037}
1038
1039DEFUN(reset_endp, reset_endp_cmd,
1040 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001041 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001042{
1043 struct mgcp_trunk_config *trunk;
1044 struct mgcp_endpoint *endp;
1045 int endp_no, rc;
1046
1047 trunk = find_trunk(g_cfg, atoi(argv[0]));
1048 if (!trunk) {
1049 vty_out(vty, "%%Trunk %d not found in the config.%s",
1050 atoi(argv[0]), VTY_NEWLINE);
1051 return CMD_WARNING;
1052 }
1053
1054 if (!trunk->endpoints) {
1055 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1056 trunk->trunk_nr, VTY_NEWLINE);
1057 return CMD_WARNING;
1058 }
1059
1060 endp_no = strtoul(argv[1], NULL, 16);
1061 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1062 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001063 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001064 return CMD_WARNING;
1065 }
1066
1067 endp = &trunk->endpoints[endp_no];
1068 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1069 if (rc < 0) {
1070 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1071 return CMD_WARNING;
1072 }
1073 return CMD_SUCCESS;
1074}
1075
1076DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001077 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001078{
1079 int rc;
1080
1081 rc = mgcp_send_reset_all(g_cfg);
1082 if (rc < 0) {
1083 vty_out(vty, "Error %d during endpoint reset.%s",
1084 rc, VTY_NEWLINE);
1085 return CMD_WARNING;
1086 }
1087 return CMD_SUCCESS;
1088}
1089
1090#define OSMUX_STR "RTP multiplexing\n"
1091DEFUN(cfg_mgcp_osmux,
1092 cfg_mgcp_osmux_cmd,
1093 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001094 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001095{
1096 if (strcmp(argv[0], "off") == 0) {
1097 g_cfg->osmux = OSMUX_USAGE_OFF;
1098 return CMD_SUCCESS;
1099 }
1100
Philipp Maier87bd9be2017-08-22 16:35:41 +02001101 /* Since OSMUX support is not finished, we do not
1102 * allow to turn it on yet. */
1103 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1104 return CMD_WARNING;
1105
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001106 if (strcmp(argv[0], "on") == 0)
1107 g_cfg->osmux = OSMUX_USAGE_ON;
1108 else if (strcmp(argv[0], "only") == 0)
1109 g_cfg->osmux = OSMUX_USAGE_ONLY;
1110
1111 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001112 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001113 return CMD_WARNING;
1114 }
1115
1116 return CMD_SUCCESS;
1117}
1118
1119DEFUN(cfg_mgcp_osmux_ip,
1120 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001121 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001122{
1123 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1124 return CMD_SUCCESS;
1125}
1126
1127DEFUN(cfg_mgcp_osmux_batch_factor,
1128 cfg_mgcp_osmux_batch_factor_cmd,
1129 "osmux batch-factor <1-8>",
1130 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1131{
1132 g_cfg->osmux_batch = atoi(argv[0]);
1133 return CMD_SUCCESS;
1134}
1135
1136DEFUN(cfg_mgcp_osmux_batch_size,
1137 cfg_mgcp_osmux_batch_size_cmd,
1138 "osmux batch-size <1-65535>",
1139 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1140{
1141 g_cfg->osmux_batch_size = atoi(argv[0]);
1142 return CMD_SUCCESS;
1143}
1144
1145DEFUN(cfg_mgcp_osmux_port,
1146 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001147 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001148{
1149 g_cfg->osmux_port = atoi(argv[0]);
1150 return CMD_SUCCESS;
1151}
1152
1153DEFUN(cfg_mgcp_osmux_dummy,
1154 cfg_mgcp_osmux_dummy_cmd,
1155 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001156 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1157 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001158{
1159 if (strcmp(argv[0], "on") == 0)
1160 g_cfg->osmux_dummy = 1;
1161 else if (strcmp(argv[0], "off") == 0)
1162 g_cfg->osmux_dummy = 0;
1163
1164 return CMD_SUCCESS;
1165}
1166
1167int mgcp_vty_init(void)
1168{
1169 install_element_ve(&show_mgcp_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001170 install_element(ENABLE_NODE, &loop_conn_cmd);
1171 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001172 install_element(ENABLE_NODE, &free_endp_cmd);
1173 install_element(ENABLE_NODE, &reset_endp_cmd);
1174 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1175
1176 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1177 install_node(&mgcp_node, config_write_mgcp);
1178
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001179 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001180 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1181 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1182 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001183 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
1184 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
1185 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001186 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1187 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001188 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1189 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1190 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1191 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1192 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1193 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1194 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1195 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1196 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001197 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1198 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1199 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1200 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1201 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1202 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001203 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001204 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1205 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1206 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1207 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1208 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1209 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1210 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1211 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1212 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1213 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1214 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1215 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1216 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1217 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1218 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1219 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1220 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1221 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1222 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1223 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1224 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
1225
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001226 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1227 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001228 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1229 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1230 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1231 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1232 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1233 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1234 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1235 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1236 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1237 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1238 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1239 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1240 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1241 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1242 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1243 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1244 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1245 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1246 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1247 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1248 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1249 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1250
1251 return 0;
1252}
1253
1254static int allocate_trunk(struct mgcp_trunk_config *trunk)
1255{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001256 if (mgcp_endpoints_allocate(trunk) != 0) {
1257 LOGP(DLMGCP, LOGL_ERROR,
1258 "Failed to allocate %d endpoints on trunk %d.\n",
1259 trunk->number_endpoints, trunk->trunk_nr);
1260 return -1;
1261 }
1262
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001263 return 0;
1264}
1265
1266int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1267 enum mgcp_role role)
1268{
1269 int rc;
1270 struct mgcp_trunk_config *trunk;
1271
1272 cfg->osmux_port = OSMUX_PORT;
1273 cfg->osmux_batch = 4;
1274 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1275
1276 g_cfg = cfg;
1277 rc = vty_read_config_file(config_file, NULL);
1278 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001279 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1280 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001281 return rc;
1282 }
1283
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001284 if (!g_cfg->source_addr) {
1285 fprintf(stderr, "You need to specify a bind address.\n");
1286 return -1;
1287 }
1288
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001289 if (allocate_trunk(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001290 LOGP(DLMGCP, LOGL_ERROR,
1291 "Failed to initialize the virtual trunk.\n");
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001292 return -1;
1293 }
1294
1295 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
1296 if (allocate_trunk(trunk) != 0) {
1297 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001298 "Failed to initialize E1 trunk %d.\n",
1299 trunk->trunk_nr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001300 return -1;
1301 }
1302 }
1303 cfg->role = role;
1304
1305 return 0;
1306}