blob: 75cc52f172ffad4d63f4f77872559588aba4fd51 [file] [log] [blame]
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
5 * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
6 * (C) 2009-2011 by On-Waves
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020024#include <osmocom/core/talloc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020025#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020026#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020027#include <osmocom/mgcp/mgcp_internal.h>
28#include <osmocom/mgcp/vty.h>
29#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010030#include <osmocom/mgcp/mgcp_endp.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020031
32#include <string.h>
Philipp Maierbca0ef62018-07-09 17:20:51 +020033#include <inttypes.h>
Stefan Sperling12086582018-06-26 15:26:28 +020034#include <limits.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020035
36#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
37#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
38#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
39
40static struct mgcp_config *g_cfg = NULL;
41
42static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
43{
44 struct mgcp_trunk_config *trunk;
45
46 if (nr == 0)
47 trunk = &cfg->trunk;
48 else
49 trunk = mgcp_trunk_num(cfg, nr);
50
51 return trunk;
52}
53
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020054struct cmd_node mgcp_node = {
55 MGCP_NODE,
56 "%s(config-mgcp)# ",
57 1,
58};
59
60struct cmd_node trunk_node = {
61 TRUNK_NODE,
62 "%s(config-mgcp-trunk)# ",
63 1,
64};
65
66static int config_write_mgcp(struct vty *vty)
67{
68 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maier12943ea2018-01-17 15:40:25 +010069 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020070 if (g_cfg->local_ip)
71 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020072 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
73 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Philipp Maierf1889d82017-11-08 14:59:39 +010074 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020075 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
76 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020077 if (g_cfg->net_ports.bind_addr)
Philipp Maierf1889d82017-11-08 14:59:39 +010078 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020079 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010080 if (g_cfg->net_ports.bind_addr_probe)
81 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
82 else
83 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020084 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
85 if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
86 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
87 else if (g_cfg->trunk.keepalive_interval)
88 vty_out(vty, " rtp keep-alive %d%s",
89 g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
90 else
91 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
92
93 if (g_cfg->trunk.omit_rtcp)
94 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
95 else
96 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +020097 if (g_cfg->trunk.force_constant_ssrc
98 || g_cfg->trunk.force_aligned_timing) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020099 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200100 g_cfg->trunk.force_constant_ssrc ? "" : "no ",
101 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200102 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200103 g_cfg->trunk.force_aligned_timing ? "" : "no ",
104 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200105 } else
106 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
107 if (g_cfg->trunk.audio_payload != -1)
108 vty_out(vty, " sdp audio-payload number %d%s",
109 g_cfg->trunk.audio_payload, VTY_NEWLINE);
110 if (g_cfg->trunk.audio_name)
111 vty_out(vty, " sdp audio-payload name %s%s",
112 g_cfg->trunk.audio_name, VTY_NEWLINE);
113 if (g_cfg->trunk.audio_fmtp_extra)
114 vty_out(vty, " sdp audio fmtp-extra %s%s",
115 g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
116 vty_out(vty, " %ssdp audio-payload send-ptime%s",
117 g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
118 vty_out(vty, " %ssdp audio-payload send-name%s",
119 g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200120 vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
121 vty_out(vty, " number endpoints %u%s",
Philipp Maierfcd06552017-11-10 17:32:22 +0100122 g_cfg->trunk.vty_number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200123 vty_out(vty, " %sallow-transcoding%s",
124 g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
125 if (g_cfg->call_agent_addr)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200126 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
127 VTY_NEWLINE);
128 if (g_cfg->force_ptime > 0)
129 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
130 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200131
132 switch (g_cfg->osmux) {
133 case OSMUX_USAGE_ON:
134 vty_out(vty, " osmux on%s", VTY_NEWLINE);
135 break;
136 case OSMUX_USAGE_ONLY:
137 vty_out(vty, " osmux only%s", VTY_NEWLINE);
138 break;
139 case OSMUX_USAGE_OFF:
140 default:
141 vty_out(vty, " osmux off%s", VTY_NEWLINE);
142 break;
143 }
144 if (g_cfg->osmux) {
145 vty_out(vty, " osmux bind-ip %s%s",
146 g_cfg->osmux_addr, VTY_NEWLINE);
147 vty_out(vty, " osmux batch-factor %d%s",
148 g_cfg->osmux_batch, VTY_NEWLINE);
149 vty_out(vty, " osmux batch-size %u%s",
150 g_cfg->osmux_batch_size, VTY_NEWLINE);
151 vty_out(vty, " osmux port %u%s",
152 g_cfg->osmux_port, VTY_NEWLINE);
153 vty_out(vty, " osmux dummy %s%s",
154 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
155 }
156 return CMD_SUCCESS;
157}
158
Philipp Maiercede2a42018-07-03 14:14:21 +0200159static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200160{
Philipp Maiercede2a42018-07-03 14:14:21 +0200161 struct mgcp_rtp_state *state = &conn->state;
162 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200163 struct mgcp_rtp_codec *codec = end->codec;
Philipp Maiercede2a42018-07-03 14:14:21 +0200164 struct rate_ctr *dropped_packets;
165
166 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200167
168 vty_out(vty,
Philipp Maierbca0ef62018-07-09 17:20:51 +0200169 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
170 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200171 " Payload Type: %d Rate: %u Channels: %d %s"
172 " Frame Duration: %u Frame Denominator: %u%s"
173 " FPP: %d Packet Duration: %u%s"
174 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
175 " Output-Enabled: %d Force-PTIME: %d%s",
Philipp Maier9e1d1642018-05-09 16:26:34 +0200176 state->in_stream.err_ts_ctr->current,
177 state->out_stream.err_ts_ctr->current,
178 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200179 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200180 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200181 codec->frame_duration_num, codec->frame_duration_den,
182 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
183 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
184 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
185 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200186}
187
Stefan Sperling12086582018-06-26 15:26:28 +0200188static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp, int epidx,
189 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200190{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200191 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200192
Stefan Sperling12086582018-06-26 15:26:28 +0200193 vty_out(vty, "%s trunk %d endpoint %s%.2x:%s",
194 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr,
195 trunk_type == MGCP_TRUNK_VIRTUAL ? MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK : "",
196 epidx, VTY_NEWLINE);
197
198 if (llist_empty(&endp->conns)) {
199 vty_out(vty, " No active connections%s", VTY_NEWLINE);
200 return;
201 }
202
203 llist_for_each_entry(conn, &endp->conns, entry) {
204 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
205
206 if (show_stats) {
207 /* FIXME: Also add verbosity for other
208 * connection types (E1) as soon as
209 * the implementation is available */
210 if (conn->type == MGCP_CONN_TYPE_RTP) {
211 dump_rtp_end(vty, &conn->u.rtp);
212 }
213 }
214 }
215}
216
217static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg, int show_stats)
218{
219 int i;
220
221 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200222 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
223 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
224
225 if (!cfg->endpoints) {
226 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
227 return;
228 }
229
230 for (i = 1; i < cfg->number_endpoints; ++i) {
231 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Stefan Sperling12086582018-06-26 15:26:28 +0200232 dump_endpoint(vty, endp, i, cfg->trunk_nr, cfg->trunk_type, show_stats);
233 if (i < cfg->number_endpoints - 1)
234 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200235 }
236}
237
Stefan Sperling12086582018-06-26 15:26:28 +0200238#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
239
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200240DEFUN(show_mcgp, show_mgcp_cmd,
241 "show mgcp [stats]",
242 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200243 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200244 "Include Statistics\n")
245{
246 struct mgcp_trunk_config *trunk;
247 int show_stats = argc >= 1;
248
249 dump_trunk(vty, &g_cfg->trunk, show_stats);
250
251 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200252 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200253
254 if (g_cfg->osmux)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200255 vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(),
256 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200257
258 return CMD_SUCCESS;
259}
260
Stefan Sperling12086582018-06-26 15:26:28 +0200261static void
262dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk_config *trunk, const char *epname)
263{
264 const size_t virt_prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK) - 1;
265 unsigned long epidx;
266 char *endp;
267 int i;
268
269 if (strncmp(epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, virt_prefix_len) == 0)
270 epname += virt_prefix_len;
271 errno = 0;
272 epidx = strtoul(epname, &endp, 16);
273 if (epname[0] == '\0' || *endp != '\0') {
274 vty_out(vty, "endpoint name '%s' is not a hex number%s", epname, VTY_NEWLINE);
275 return;
276 }
277 if ((errno == ERANGE && epidx == ULONG_MAX) /* parsed value out of range */
278 || epidx >= trunk->number_endpoints) {
279 vty_out(vty, "endpoint %.2lx not configured on trunk %d%s", epidx, trunk->trunk_nr, VTY_NEWLINE);
280 return;
281 }
282
283 for (i = 0; i < trunk->number_endpoints; ++i) {
284 struct mgcp_endpoint *endp = &trunk->endpoints[i];
285 if (i == epidx) {
286 dump_endpoint(vty, endp, i, trunk->trunk_nr, trunk->trunk_type, true);
287 break;
288 }
289 }
290}
291
292DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
293 "show mgcp endpoint NAME",
294 SHOW_STR
295 SHOW_MGCP_STR
296 "Display information about an endpoint\n" "The name of the endpoint\n")
297{
298 struct mgcp_trunk_config *trunk;
299
300 dump_mgcp_endpoint(vty, &g_cfg->trunk, argv[0]);
301 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
302 dump_mgcp_endpoint(vty, trunk, argv[0]);
303
304 return CMD_SUCCESS;
305}
306
307DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
308 "show mgcp trunk <0-64> endpoint NAME",
309 SHOW_STR
310 SHOW_MGCP_STR
311 "Display information about a trunk\n" "Trunk number\n"
312 "Display information about an endpoint\n" "The name of the endpoint\n")
313{
314 struct mgcp_trunk_config *trunk;
315 int trunkidx = atoi(argv[0]);
316
317 trunk = find_trunk(g_cfg, trunkidx);
318 if (!trunk) {
319 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
320 return CMD_WARNING;
321 }
322
323 dump_mgcp_endpoint(vty, trunk, argv[1]);
324 return CMD_SUCCESS;
325}
326
Philipp Maier87bd9be2017-08-22 16:35:41 +0200327DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200328{
329 vty->node = MGCP_NODE;
330 return CMD_SUCCESS;
331}
332
333DEFUN(cfg_mgcp_local_ip,
334 cfg_mgcp_local_ip_cmd,
335 "local ip A.B.C.D",
336 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200337 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200338{
339 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
340 return CMD_SUCCESS;
341}
342
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200343#define BIND_STR "Listen/Bind related socket option\n"
344DEFUN(cfg_mgcp_bind_ip,
345 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200346 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200347{
348 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
349 return CMD_SUCCESS;
350}
351
352DEFUN(cfg_mgcp_bind_port,
353 cfg_mgcp_bind_port_cmd,
354 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200355 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200356{
357 unsigned int port = atoi(argv[0]);
358 g_cfg->source_port = port;
359 return CMD_SUCCESS;
360}
361
362DEFUN(cfg_mgcp_bind_early,
363 cfg_mgcp_bind_early_cmd,
364 "bind early (0|1)",
365 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200366 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200367{
368 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
369 return CMD_WARNING;
370}
371
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200372#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200373#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200374#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200375#define RANGE_START_STR "Start of the range of ports\n"
376#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200377
Philipp Maierf1889d82017-11-08 14:59:39 +0100378DEFUN(cfg_mgcp_rtp_port_range,
379 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200380 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200381 RTP_STR "Range of ports to use for the NET side\n"
382 RANGE_START_STR RANGE_END_STR)
383{
Philipp Maiera19547b2018-05-22 13:44:34 +0200384 int start;
385 int end;
386
387 start = atoi(argv[0]);
388 end = atoi(argv[1]);
389
390 if (end < start) {
391 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
392 end, start, VTY_NEWLINE);
393 return CMD_WARNING;
394 }
395
396 if (start & 1) {
397 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
398 start, start & 0xFFFE, VTY_NEWLINE);
399 start &= 0xFFFE;
400 }
401
402 if ((end & 1) == 0) {
403 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
404 end, end | 1, VTY_NEWLINE);
405 end |= 1;
406 }
407
408 g_cfg->net_ports.range_start = start;
409 g_cfg->net_ports.range_end = end;
410 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
411
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200412 return CMD_SUCCESS;
413}
Philipp Maierf1889d82017-11-08 14:59:39 +0100414ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
415 cfg_mgcp_rtp_net_range_cmd,
416 "rtp net-range <0-65534> <0-65534>",
417 RTP_STR "Range of ports to use for the NET side\n"
418 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200419
Philipp Maierf1889d82017-11-08 14:59:39 +0100420DEFUN(cfg_mgcp_rtp_bind_ip,
421 cfg_mgcp_rtp_bind_ip_cmd,
422 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200423 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
424{
425 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
426 return CMD_SUCCESS;
427}
Philipp Maierf1889d82017-11-08 14:59:39 +0100428ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
429 cfg_mgcp_rtp_net_bind_ip_cmd,
430 "rtp net-bind-ip A.B.C.D",
431 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200432
Philipp Maierf1889d82017-11-08 14:59:39 +0100433DEFUN(cfg_mgcp_rtp_no_bind_ip,
434 cfg_mgcp_rtp_no_bind_ip_cmd,
435 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200436 NO_STR RTP_STR "Bind endpoints facing the Network\n"
437 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200438{
439 talloc_free(g_cfg->net_ports.bind_addr);
440 g_cfg->net_ports.bind_addr = NULL;
441 return CMD_SUCCESS;
442}
Philipp Maierf1889d82017-11-08 14:59:39 +0100443ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
444 cfg_mgcp_rtp_no_net_bind_ip_cmd,
445 "no rtp net-bind-ip",
446 NO_STR RTP_STR "Bind endpoints facing the Network\n"
447 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200448
Philipp Maier1cb1e382017-11-02 17:16:04 +0100449DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
450 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
451 "rtp ip-probing",
452 RTP_STR "automatic rtp bind ip selection\n")
453{
454 g_cfg->net_ports.bind_addr_probe = true;
455 return CMD_SUCCESS;
456}
457
458DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
459 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
460 "no rtp ip-probing",
461 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
462{
463 g_cfg->net_ports.bind_addr_probe = false;
464 return CMD_SUCCESS;
465}
466
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200467DEFUN(cfg_mgcp_rtp_ip_dscp,
468 cfg_mgcp_rtp_ip_dscp_cmd,
469 "rtp ip-dscp <0-255>",
470 RTP_STR
471 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
472{
473 int dscp = atoi(argv[0]);
474 g_cfg->endp_dscp = dscp;
475 return CMD_SUCCESS;
476}
477
478ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200479 "rtp ip-tos <0-255>",
480 RTP_STR
481 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
482#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
483 DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200484 cfg_mgcp_rtp_force_ptime_cmd,
485 "rtp force-ptime (10|20|40)",
486 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200487 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200488{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200489 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200490 return CMD_SUCCESS;
491}
492
493DEFUN(cfg_mgcp_no_rtp_force_ptime,
494 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200495 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200496{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200497 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200498 return CMD_SUCCESS;
499}
500
501DEFUN(cfg_mgcp_sdp_fmtp_extra,
502 cfg_mgcp_sdp_fmtp_extra_cmd,
503 "sdp audio fmtp-extra .NAME",
504 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
505 "Extra Information\n")
506{
507 char *txt = argv_concat(argv, argc, 0);
508 if (!txt)
509 return CMD_WARNING;
510
511 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
512 talloc_free(txt);
513 return CMD_SUCCESS;
514}
515
516DEFUN(cfg_mgcp_allow_transcoding,
517 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200518 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200519{
520 g_cfg->trunk.no_audio_transcoding = 0;
521 return CMD_SUCCESS;
522}
523
524DEFUN(cfg_mgcp_no_allow_transcoding,
525 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200526 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200527{
528 g_cfg->trunk.no_audio_transcoding = 1;
529 return CMD_SUCCESS;
530}
531
532#define SDP_STR "SDP File related options\n"
533#define AUDIO_STR "Audio payload options\n"
534DEFUN(cfg_mgcp_sdp_payload_number,
535 cfg_mgcp_sdp_payload_number_cmd,
536 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200537 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200538{
539 unsigned int payload = atoi(argv[0]);
540 g_cfg->trunk.audio_payload = payload;
541 return CMD_SUCCESS;
542}
543
Philipp Maier87bd9be2017-08-22 16:35:41 +0200544ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
545 cfg_mgcp_sdp_payload_number_cmd_old,
546 "sdp audio payload number <0-255>",
547 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200548
Philipp Maier87bd9be2017-08-22 16:35:41 +0200549 DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200550 cfg_mgcp_sdp_payload_name_cmd,
551 "sdp audio-payload name NAME",
552 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
553{
554 osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
555 return CMD_SUCCESS;
556}
557
558ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200559 "sdp audio payload name NAME",
560 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200561
Philipp Maier87bd9be2017-08-22 16:35:41 +0200562 DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200563 cfg_mgcp_sdp_payload_send_ptime_cmd,
564 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200565 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200566{
567 g_cfg->trunk.audio_send_ptime = 1;
568 return CMD_SUCCESS;
569}
570
571DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
572 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
573 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200574 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200575{
576 g_cfg->trunk.audio_send_ptime = 0;
577 return CMD_SUCCESS;
578}
579
580DEFUN(cfg_mgcp_sdp_payload_send_name,
581 cfg_mgcp_sdp_payload_send_name_cmd,
582 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200583 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200584{
585 g_cfg->trunk.audio_send_name = 1;
586 return CMD_SUCCESS;
587}
588
589DEFUN(cfg_mgcp_no_sdp_payload_send_name,
590 cfg_mgcp_no_sdp_payload_send_name_cmd,
591 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200592 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200593{
594 g_cfg->trunk.audio_send_name = 0;
595 return CMD_SUCCESS;
596}
597
598DEFUN(cfg_mgcp_loop,
599 cfg_mgcp_loop_cmd,
600 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200601 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200602{
603 if (g_cfg->osmux) {
604 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
605 return CMD_WARNING;
606 }
607 g_cfg->trunk.audio_loop = atoi(argv[0]);
608 return CMD_SUCCESS;
609}
610
611DEFUN(cfg_mgcp_force_realloc,
612 cfg_mgcp_force_realloc_cmd,
613 "force-realloc (0|1)",
614 "Force endpoint reallocation when the endpoint is still seized\n"
615 "Don't force reallocation\n" "force reallocation\n")
616{
617 g_cfg->trunk.force_realloc = atoi(argv[0]);
618 return CMD_SUCCESS;
619}
620
Philipp Maier87bd9be2017-08-22 16:35:41 +0200621DEFUN(cfg_mgcp_rtp_accept_all,
622 cfg_mgcp_rtp_accept_all_cmd,
623 "rtp-accept-all (0|1)",
624 "Accept all RTP packets, even when the originating IP/Port does not match\n"
625 "enable filter\n" "disable filter\n")
626{
627 g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
628 return CMD_SUCCESS;
629}
630
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200631DEFUN(cfg_mgcp_number_endp,
632 cfg_mgcp_number_endp_cmd,
633 "number endpoints <0-65534>",
634 "Number options\n" "Endpoints available\n" "Number endpoints\n")
635{
636 /* + 1 as we start counting at one */
Philipp Maierfcd06552017-11-10 17:32:22 +0100637 g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200638 return CMD_SUCCESS;
639}
640
Philipp Maier87bd9be2017-08-22 16:35:41 +0200641DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200642{
643 g_cfg->trunk.omit_rtcp = 1;
644 return CMD_SUCCESS;
645}
646
647DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200648 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200649{
650 g_cfg->trunk.omit_rtcp = 0;
651 return CMD_SUCCESS;
652}
653
654DEFUN(cfg_mgcp_patch_rtp_ssrc,
655 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200656 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200657{
658 g_cfg->trunk.force_constant_ssrc = 1;
659 return CMD_SUCCESS;
660}
661
662DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
663 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200664 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200665{
666 g_cfg->trunk.force_constant_ssrc = 0;
667 return CMD_SUCCESS;
668}
669
670DEFUN(cfg_mgcp_patch_rtp_ts,
671 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200672 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200673{
674 g_cfg->trunk.force_aligned_timing = 1;
675 return CMD_SUCCESS;
676}
677
678DEFUN(cfg_mgcp_no_patch_rtp_ts,
679 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200680 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200681{
682 g_cfg->trunk.force_aligned_timing = 0;
683 return CMD_SUCCESS;
684}
685
686DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200687 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200688{
689 g_cfg->trunk.force_constant_ssrc = 0;
690 g_cfg->trunk.force_aligned_timing = 0;
691 return CMD_SUCCESS;
692}
693
694DEFUN(cfg_mgcp_rtp_keepalive,
695 cfg_mgcp_rtp_keepalive_cmd,
696 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200697 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200698{
699 mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
700 return CMD_SUCCESS;
701}
702
703DEFUN(cfg_mgcp_rtp_keepalive_once,
704 cfg_mgcp_rtp_keepalive_once_cmd,
705 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200706 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200707{
708 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
709 return CMD_SUCCESS;
710}
711
712DEFUN(cfg_mgcp_no_rtp_keepalive,
713 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200714 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200715{
Philipp Maiere726d4f2017-11-01 10:41:34 +0100716 mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200717 return CMD_SUCCESS;
718}
719
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200720#define CALL_AGENT_STR "Callagent information\n"
721DEFUN(cfg_mgcp_agent_addr,
722 cfg_mgcp_agent_addr_cmd,
723 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200724 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200725{
726 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
727 return CMD_SUCCESS;
728}
729
730ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200731 "call agent ip A.B.C.D",
732 CALL_AGENT_STR CALL_AGENT_STR IP_STR
733 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200734
Philipp Maier87bd9be2017-08-22 16:35:41 +0200735 DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
736 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200737{
738 struct mgcp_trunk_config *trunk;
739 int index = atoi(argv[0]);
740
741 trunk = mgcp_trunk_num(g_cfg, index);
742 if (!trunk)
743 trunk = mgcp_trunk_alloc(g_cfg, index);
744
745 if (!trunk) {
746 vty_out(vty, "%%Unable to allocate trunk %u.%s",
747 index, VTY_NEWLINE);
748 return CMD_WARNING;
749 }
750
751 vty->node = TRUNK_NODE;
752 vty->index = trunk;
753 return CMD_SUCCESS;
754}
755
756static int config_write_trunk(struct vty *vty)
757{
758 struct mgcp_trunk_config *trunk;
759
760 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
761 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
762 vty_out(vty, " sdp audio-payload number %d%s",
763 trunk->audio_payload, VTY_NEWLINE);
764 vty_out(vty, " sdp audio-payload name %s%s",
765 trunk->audio_name, VTY_NEWLINE);
766 vty_out(vty, " %ssdp audio-payload send-ptime%s",
767 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
768 vty_out(vty, " %ssdp audio-payload send-name%s",
769 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
770
771 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
772 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
773 else if (trunk->keepalive_interval)
774 vty_out(vty, " rtp keep-alive %d%s",
775 trunk->keepalive_interval, VTY_NEWLINE);
776 else
777 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200778 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200779 vty_out(vty, " force-realloc %d%s",
780 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200781 vty_out(vty, " rtp-accept-all %d%s",
782 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200783 if (trunk->omit_rtcp)
784 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
785 else
786 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
787 if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
788 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200789 trunk->force_constant_ssrc ? "" : "no ",
790 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200791 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200792 trunk->force_aligned_timing ? "" : "no ",
793 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200794 } else
795 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
796 if (trunk->audio_fmtp_extra)
797 vty_out(vty, " sdp audio fmtp-extra %s%s",
798 trunk->audio_fmtp_extra, VTY_NEWLINE);
799 vty_out(vty, " %sallow-transcoding%s",
800 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
801 }
802
803 return CMD_SUCCESS;
804}
805
806DEFUN(cfg_trunk_sdp_fmtp_extra,
807 cfg_trunk_sdp_fmtp_extra_cmd,
808 "sdp audio fmtp-extra .NAME",
809 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
810 "Extra Information\n")
811{
812 struct mgcp_trunk_config *trunk = vty->index;
813 char *txt = argv_concat(argv, argc, 0);
814 if (!txt)
815 return CMD_WARNING;
816
817 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
818 talloc_free(txt);
819 return CMD_SUCCESS;
820}
821
822DEFUN(cfg_trunk_payload_number,
823 cfg_trunk_payload_number_cmd,
824 "sdp audio-payload number <0-255>",
825 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
826{
827 struct mgcp_trunk_config *trunk = vty->index;
828 unsigned int payload = atoi(argv[0]);
829
830 trunk->audio_payload = payload;
831 return CMD_SUCCESS;
832}
833
834ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200835 "sdp audio payload number <0-255>",
836 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200837
Philipp Maier87bd9be2017-08-22 16:35:41 +0200838 DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200839 cfg_trunk_payload_name_cmd,
840 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200841 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200842{
843 struct mgcp_trunk_config *trunk = vty->index;
844
845 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
846 return CMD_SUCCESS;
847}
848
849ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200850 "sdp audio payload name NAME",
851 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200852
Philipp Maier87bd9be2017-08-22 16:35:41 +0200853 DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200854 cfg_trunk_loop_cmd,
855 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200856 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200857{
858 struct mgcp_trunk_config *trunk = vty->index;
859
860 if (g_cfg->osmux) {
861 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
862 return CMD_WARNING;
863 }
864 trunk->audio_loop = atoi(argv[0]);
865 return CMD_SUCCESS;
866}
867
868DEFUN(cfg_trunk_sdp_payload_send_ptime,
869 cfg_trunk_sdp_payload_send_ptime_cmd,
870 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200871 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200872{
873 struct mgcp_trunk_config *trunk = vty->index;
874 trunk->audio_send_ptime = 1;
875 return CMD_SUCCESS;
876}
877
878DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
879 cfg_trunk_no_sdp_payload_send_ptime_cmd,
880 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200881 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200882{
883 struct mgcp_trunk_config *trunk = vty->index;
884 trunk->audio_send_ptime = 0;
885 return CMD_SUCCESS;
886}
887
888DEFUN(cfg_trunk_sdp_payload_send_name,
889 cfg_trunk_sdp_payload_send_name_cmd,
890 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200891 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200892{
893 struct mgcp_trunk_config *trunk = vty->index;
894 trunk->audio_send_name = 1;
895 return CMD_SUCCESS;
896}
897
898DEFUN(cfg_trunk_no_sdp_payload_send_name,
899 cfg_trunk_no_sdp_payload_send_name_cmd,
900 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200901 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200902{
903 struct mgcp_trunk_config *trunk = vty->index;
904 trunk->audio_send_name = 0;
905 return CMD_SUCCESS;
906}
907
Philipp Maier87bd9be2017-08-22 16:35:41 +0200908DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200909{
910 struct mgcp_trunk_config *trunk = vty->index;
911 trunk->omit_rtcp = 1;
912 return CMD_SUCCESS;
913}
914
915DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200916 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200917{
918 struct mgcp_trunk_config *trunk = vty->index;
919 trunk->omit_rtcp = 0;
920 return CMD_SUCCESS;
921}
922
923DEFUN(cfg_trunk_patch_rtp_ssrc,
924 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200925 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200926{
927 struct mgcp_trunk_config *trunk = vty->index;
928 trunk->force_constant_ssrc = 1;
929 return CMD_SUCCESS;
930}
931
932DEFUN(cfg_trunk_no_patch_rtp_ssrc,
933 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200934 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200935{
936 struct mgcp_trunk_config *trunk = vty->index;
937 trunk->force_constant_ssrc = 0;
938 return CMD_SUCCESS;
939}
940
941DEFUN(cfg_trunk_patch_rtp_ts,
942 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200943 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200944{
945 struct mgcp_trunk_config *trunk = vty->index;
946 trunk->force_aligned_timing = 1;
947 return CMD_SUCCESS;
948}
949
950DEFUN(cfg_trunk_no_patch_rtp_ts,
951 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200952 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200953{
954 struct mgcp_trunk_config *trunk = vty->index;
955 trunk->force_aligned_timing = 0;
956 return CMD_SUCCESS;
957}
958
959DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200960 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200961{
962 struct mgcp_trunk_config *trunk = vty->index;
963 trunk->force_constant_ssrc = 0;
964 trunk->force_aligned_timing = 0;
965 return CMD_SUCCESS;
966}
967
968DEFUN(cfg_trunk_rtp_keepalive,
969 cfg_trunk_rtp_keepalive_cmd,
970 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200971 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200972{
973 struct mgcp_trunk_config *trunk = vty->index;
974 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
975 return CMD_SUCCESS;
976}
977
978DEFUN(cfg_trunk_rtp_keepalive_once,
979 cfg_trunk_rtp_keepalive_once_cmd,
980 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200981 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200982{
983 struct mgcp_trunk_config *trunk = vty->index;
984 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
985 return CMD_SUCCESS;
986}
987
988DEFUN(cfg_trunk_no_rtp_keepalive,
989 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200990 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200991{
992 struct mgcp_trunk_config *trunk = vty->index;
993 mgcp_trunk_set_keepalive(trunk, 0);
994 return CMD_SUCCESS;
995}
996
997DEFUN(cfg_trunk_allow_transcoding,
998 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200999 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000{
1001 struct mgcp_trunk_config *trunk = vty->index;
1002 trunk->no_audio_transcoding = 0;
1003 return CMD_SUCCESS;
1004}
1005
1006DEFUN(cfg_trunk_no_allow_transcoding,
1007 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001008 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001009{
1010 struct mgcp_trunk_config *trunk = vty->index;
1011 trunk->no_audio_transcoding = 1;
1012 return CMD_SUCCESS;
1013}
1014
Philipp Maier87bd9be2017-08-22 16:35:41 +02001015DEFUN(loop_conn,
1016 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001017 "loop-endpoint <0-64> NAME (0|1)",
1018 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001019 "The name in hex of the endpoint\n" "Disable the loop\n"
1020 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001021{
1022 struct mgcp_trunk_config *trunk;
1023 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001024 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001025
1026 trunk = find_trunk(g_cfg, atoi(argv[0]));
1027 if (!trunk) {
1028 vty_out(vty, "%%Trunk %d not found in the config.%s",
1029 atoi(argv[0]), VTY_NEWLINE);
1030 return CMD_WARNING;
1031 }
1032
1033 if (!trunk->endpoints) {
1034 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1035 trunk->trunk_nr, VTY_NEWLINE);
1036 return CMD_WARNING;
1037 }
1038
1039 int endp_no = strtoul(argv[1], NULL, 16);
1040 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1041 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001042 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001043 return CMD_WARNING;
1044 }
1045
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001046 endp = &trunk->endpoints[endp_no];
1047 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001048 llist_for_each_entry(conn, &endp->conns, entry) {
1049 if (conn->type == MGCP_CONN_TYPE_RTP)
1050 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1051 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1052 else {
1053 /* FIXME: Introduce support for other connection (E1)
1054 * types when implementation is available */
1055 vty_out(vty, "%%Can't enable SSRC patching,"
1056 "connection %s is not an RTP connection.%s",
1057 mgcp_conn_dump(conn), VTY_NEWLINE);
1058 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001059
Philipp Maier87bd9be2017-08-22 16:35:41 +02001060 if (loop)
1061 conn->mode = MGCP_CONN_LOOPBACK;
1062 else
1063 conn->mode = conn->mode_orig;
1064 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001065
1066 return CMD_SUCCESS;
1067}
1068
Philipp Maier87bd9be2017-08-22 16:35:41 +02001069DEFUN(tap_rtp,
1070 tap_rtp_cmd,
1071 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001072 "Forward data on endpoint to a different system\n" "Trunk number\n"
1073 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001074 "The connection id in hex\n"
1075 "Forward incoming data\n"
1076 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001077 "destination IP of the data\n" "destination port\n")
1078{
1079 struct mgcp_rtp_tap *tap;
1080 struct mgcp_trunk_config *trunk;
1081 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001082 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001083 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001084
1085 trunk = find_trunk(g_cfg, atoi(argv[0]));
1086 if (!trunk) {
1087 vty_out(vty, "%%Trunk %d not found in the config.%s",
1088 atoi(argv[0]), VTY_NEWLINE);
1089 return CMD_WARNING;
1090 }
1091
1092 if (!trunk->endpoints) {
1093 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1094 trunk->trunk_nr, VTY_NEWLINE);
1095 return CMD_WARNING;
1096 }
1097
1098 int endp_no = strtoul(argv[1], NULL, 16);
1099 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1100 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001101 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001102 return CMD_WARNING;
1103 }
1104
1105 endp = &trunk->endpoints[endp_no];
1106
Philipp Maier01d24a32017-11-21 17:26:09 +01001107 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001108 conn = mgcp_conn_get_rtp(endp, conn_id);
1109 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001110 vty_out(vty, "Conn ID %s is invalid.%s",
1111 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001112 return CMD_WARNING;
1113 }
1114
1115 if (strcmp(argv[3], "in") == 0)
1116 tap = &conn->tap_in;
1117 else if (strcmp(argv[3], "out") == 0)
1118 tap = &conn->tap_out;
1119 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001120 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1121 return CMD_WARNING;
1122 }
1123
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001124 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001125 inet_aton(argv[4], &tap->forward.sin_addr);
1126 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001127 tap->enabled = 1;
1128 return CMD_SUCCESS;
1129}
1130
1131DEFUN(free_endp, free_endp_cmd,
1132 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001133 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001134{
1135 struct mgcp_trunk_config *trunk;
1136 struct mgcp_endpoint *endp;
1137
1138 trunk = find_trunk(g_cfg, atoi(argv[0]));
1139 if (!trunk) {
1140 vty_out(vty, "%%Trunk %d not found in the config.%s",
1141 atoi(argv[0]), VTY_NEWLINE);
1142 return CMD_WARNING;
1143 }
1144
1145 if (!trunk->endpoints) {
1146 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1147 trunk->trunk_nr, VTY_NEWLINE);
1148 return CMD_WARNING;
1149 }
1150
1151 int endp_no = strtoul(argv[1], NULL, 16);
1152 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1153 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001154 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001155 return CMD_WARNING;
1156 }
1157
1158 endp = &trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001159 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001160 return CMD_SUCCESS;
1161}
1162
1163DEFUN(reset_endp, reset_endp_cmd,
1164 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001165 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001166{
1167 struct mgcp_trunk_config *trunk;
1168 struct mgcp_endpoint *endp;
1169 int endp_no, rc;
1170
1171 trunk = find_trunk(g_cfg, atoi(argv[0]));
1172 if (!trunk) {
1173 vty_out(vty, "%%Trunk %d not found in the config.%s",
1174 atoi(argv[0]), VTY_NEWLINE);
1175 return CMD_WARNING;
1176 }
1177
1178 if (!trunk->endpoints) {
1179 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1180 trunk->trunk_nr, VTY_NEWLINE);
1181 return CMD_WARNING;
1182 }
1183
1184 endp_no = strtoul(argv[1], NULL, 16);
1185 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1186 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001187 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001188 return CMD_WARNING;
1189 }
1190
1191 endp = &trunk->endpoints[endp_no];
1192 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1193 if (rc < 0) {
1194 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1195 return CMD_WARNING;
1196 }
1197 return CMD_SUCCESS;
1198}
1199
1200DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001201 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001202{
1203 int rc;
1204
1205 rc = mgcp_send_reset_all(g_cfg);
1206 if (rc < 0) {
1207 vty_out(vty, "Error %d during endpoint reset.%s",
1208 rc, VTY_NEWLINE);
1209 return CMD_WARNING;
1210 }
1211 return CMD_SUCCESS;
1212}
1213
1214#define OSMUX_STR "RTP multiplexing\n"
1215DEFUN(cfg_mgcp_osmux,
1216 cfg_mgcp_osmux_cmd,
1217 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001218 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001219{
1220 if (strcmp(argv[0], "off") == 0) {
1221 g_cfg->osmux = OSMUX_USAGE_OFF;
1222 return CMD_SUCCESS;
1223 }
1224
Philipp Maier87bd9be2017-08-22 16:35:41 +02001225 /* Since OSMUX support is not finished, we do not
1226 * allow to turn it on yet. */
1227 vty_out(vty, "OSMUX currently unavailable in this software version.%s", VTY_NEWLINE);
1228 return CMD_WARNING;
Philipp Maier2982e422017-11-07 12:27:48 +01001229#if 0
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001230 if (strcmp(argv[0], "on") == 0)
1231 g_cfg->osmux = OSMUX_USAGE_ON;
1232 else if (strcmp(argv[0], "only") == 0)
1233 g_cfg->osmux = OSMUX_USAGE_ONLY;
1234
1235 if (g_cfg->trunk.audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001236 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001237 return CMD_WARNING;
1238 }
1239
1240 return CMD_SUCCESS;
Philipp Maier2982e422017-11-07 12:27:48 +01001241#endif
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001242}
1243
1244DEFUN(cfg_mgcp_osmux_ip,
1245 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001246 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001247{
1248 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1249 return CMD_SUCCESS;
1250}
1251
1252DEFUN(cfg_mgcp_osmux_batch_factor,
1253 cfg_mgcp_osmux_batch_factor_cmd,
1254 "osmux batch-factor <1-8>",
1255 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1256{
1257 g_cfg->osmux_batch = atoi(argv[0]);
1258 return CMD_SUCCESS;
1259}
1260
1261DEFUN(cfg_mgcp_osmux_batch_size,
1262 cfg_mgcp_osmux_batch_size_cmd,
1263 "osmux batch-size <1-65535>",
1264 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1265{
1266 g_cfg->osmux_batch_size = atoi(argv[0]);
1267 return CMD_SUCCESS;
1268}
1269
1270DEFUN(cfg_mgcp_osmux_port,
1271 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001272 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001273{
1274 g_cfg->osmux_port = atoi(argv[0]);
1275 return CMD_SUCCESS;
1276}
1277
1278DEFUN(cfg_mgcp_osmux_dummy,
1279 cfg_mgcp_osmux_dummy_cmd,
1280 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001281 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1282 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001283{
1284 if (strcmp(argv[0], "on") == 0)
1285 g_cfg->osmux_dummy = 1;
1286 else if (strcmp(argv[0], "off") == 0)
1287 g_cfg->osmux_dummy = 0;
1288
1289 return CMD_SUCCESS;
1290}
1291
Philipp Maier12943ea2018-01-17 15:40:25 +01001292DEFUN(cfg_mgcp_domain,
1293 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001294 "domain NAME",
1295 "Set the domain part expected in MGCP messages' endpoint names\n"
1296 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001297{
1298 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1299 return CMD_SUCCESS;
1300}
1301
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001302int mgcp_vty_init(void)
1303{
1304 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001305 install_element_ve(&show_mgcp_endpoint_cmd);
1306 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001307 install_element(ENABLE_NODE, &loop_conn_cmd);
1308 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001309 install_element(ENABLE_NODE, &free_endp_cmd);
1310 install_element(ENABLE_NODE, &reset_endp_cmd);
1311 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1312
1313 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1314 install_node(&mgcp_node, config_write_mgcp);
1315
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001316 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001317 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1318 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1319 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001320 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001321 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001322 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001323 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001324 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001325 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001326 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1327 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001328 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1329 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1330 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1331 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1332 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1333 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1334 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1335 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1336 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001337 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1338 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1339 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1340 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1341 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1342 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001343 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001344 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1345 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1346 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1347 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1348 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1349 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1350 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1351 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
1352 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1353 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1354 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1355 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1356 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1357 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1358 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1359 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1360 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1361 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1362 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1363 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1364 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001365 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001366
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001367 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1368 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001369 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1370 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1371 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1372 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1373 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1374 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1375 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1376 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1377 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1378 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1379 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1380 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1381 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
1382 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1383 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1384 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1385 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1386 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1387 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1388 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1389 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1390 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1391
1392 return 0;
1393}
1394
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001395int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1396 enum mgcp_role role)
1397{
1398 int rc;
1399 struct mgcp_trunk_config *trunk;
1400
1401 cfg->osmux_port = OSMUX_PORT;
1402 cfg->osmux_batch = 4;
1403 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1404
1405 g_cfg = cfg;
1406 rc = vty_read_config_file(config_file, NULL);
1407 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001408 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1409 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001410 return rc;
1411 }
1412
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001413 if (!g_cfg->source_addr) {
1414 fprintf(stderr, "You need to specify a bind address.\n");
1415 return -1;
1416 }
1417
Philipp Maier48454982017-11-10 16:46:41 +01001418 if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001419 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001420 "Failed to initialize the virtual trunk (%d endpoints)\n",
1421 g_cfg->trunk.number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001422 return -1;
1423 }
1424
1425 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001426 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001427 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001428 "Failed to initialize trunk %d (%d endpoints)\n",
1429 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001430 return -1;
1431 }
1432 }
1433 cfg->role = role;
1434
1435 return 0;
1436}