blob: 54b139af6168b3577c7bbbbfd3fea898ee8da550 [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>
Stefan Sperling1e174872018-10-25 18:36:10 +020025#include <osmocom/vty/misc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020026#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020027#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020028#include <osmocom/mgcp/mgcp_internal.h>
29#include <osmocom/mgcp/vty.h>
30#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010031#include <osmocom/mgcp/mgcp_endp.h>
Philipp Maierc66ab2c2020-06-02 20:55:34 +020032#include <osmocom/mgcp/mgcp_trunk.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020033
34#include <string.h>
Philipp Maierbca0ef62018-07-09 17:20:51 +020035#include <inttypes.h>
Stefan Sperling12086582018-06-26 15:26:28 +020036#include <limits.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020037
38#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
39#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
40#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
Philipp Maier9fc8a022019-02-20 12:26:52 +010041#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"
42
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020043
44static struct mgcp_config *g_cfg = NULL;
45
Philipp Maier14b27a82020-06-02 20:15:30 +020046static struct mgcp_trunk *find_trunk(struct mgcp_config *cfg, int nr)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020047{
Philipp Maier14b27a82020-06-02 20:15:30 +020048 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020049
50 if (nr == 0)
Harald Weltec39b1bf2020-03-08 11:29:39 +010051 trunk = cfg->virt_trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020052 else
Philipp Maierc66ab2c2020-06-02 20:55:34 +020053 trunk = mgcp_trunk_by_num(cfg, nr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020054
55 return trunk;
56}
57
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020058struct cmd_node mgcp_node = {
59 MGCP_NODE,
60 "%s(config-mgcp)# ",
61 1,
62};
63
64struct cmd_node trunk_node = {
65 TRUNK_NODE,
66 "%s(config-mgcp-trunk)# ",
67 1,
68};
69
70static int config_write_mgcp(struct vty *vty)
71{
Philipp Maier14b27a82020-06-02 20:15:30 +020072 struct mgcp_trunk *trunk = g_cfg->virt_trunk;
Harald Weltec39b1bf2020-03-08 11:29:39 +010073
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020074 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020075 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020076 if (g_cfg->local_ip)
77 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020078 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
79 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
80 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020081 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
82 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020083 if (g_cfg->net_ports.bind_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +020084 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020085 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010086 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020087 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010088 else
Philipp Maierf53796c2020-06-02 20:38:28 +020089 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
90 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010091 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020092 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010093 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020094 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010095 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020096 else
Philipp Maierf53796c2020-06-02 20:38:28 +020097 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020098
Harald Weltec39b1bf2020-03-08 11:29:39 +010099 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +0200100 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200101 else
Philipp Maierf53796c2020-06-02 20:38:28 +0200102 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100103 if (trunk->force_constant_ssrc
104 || trunk->force_aligned_timing
105 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200106 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100107 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200108 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200109 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100110 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200111 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200112 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100113 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100114 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200115 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200116 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100117 if (trunk->audio_payload != -1)
Philipp Maierf53796c2020-06-02 20:38:28 +0200118 vty_out(vty, " sdp audio-payload number %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100119 trunk->audio_payload, VTY_NEWLINE);
120 if (trunk->audio_name)
Philipp Maierf53796c2020-06-02 20:38:28 +0200121 vty_out(vty, " sdp audio-payload name %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100122 trunk->audio_name, VTY_NEWLINE);
123 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200124 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100125 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200126 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100127 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200128 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100129 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200130 vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
131 vty_out(vty, " number endpoints %u%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100132 trunk->vty_number_endpoints - 1, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200133 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100134 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200135 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200136 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200137 VTY_NEWLINE);
138 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200139 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200140 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200141
142 switch (g_cfg->osmux) {
143 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200144 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200145 break;
146 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200147 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200148 break;
149 case OSMUX_USAGE_OFF:
150 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200151 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200152 break;
153 }
154 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200155 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200156 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200157 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200158 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200159 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200160 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200161 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200162 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200163 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200164 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
165 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100166
167 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200168 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100169
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200170 return CMD_SUCCESS;
171}
172
Philipp Maiercede2a42018-07-03 14:14:21 +0200173static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200174{
Philipp Maiercede2a42018-07-03 14:14:21 +0200175 struct mgcp_rtp_state *state = &conn->state;
176 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200177 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100178 struct rate_ctr *tx_packets, *tx_bytes;
179 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200180 struct rate_ctr *dropped_packets;
181
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100182 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
183 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
184 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
185 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200186 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200187
188 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100189 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
190 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200191 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
192 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200193 " Payload Type: %d Rate: %u Channels: %d %s"
194 " Frame Duration: %u Frame Denominator: %u%s"
195 " FPP: %d Packet Duration: %u%s"
196 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
197 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100198 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
199 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200200 state->in_stream.err_ts_ctr->current,
201 state->out_stream.err_ts_ctr->current,
202 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200203 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200204 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200205 codec->frame_duration_num, codec->frame_duration_den,
206 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
207 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
208 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
209 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200210}
211
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200212static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200213 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200214{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200215 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200216
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200217 vty_out(vty, "%s trunk %d endpoint %s:%s",
218 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200219
220 if (llist_empty(&endp->conns)) {
221 vty_out(vty, " No active connections%s", VTY_NEWLINE);
222 return;
223 }
224
225 llist_for_each_entry(conn, &endp->conns, entry) {
226 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
227
228 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100229 if (endp->cfg->conn_timeout) {
230 struct timeval remaining;
231 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
232 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
233 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
234 }
235
Stefan Sperling12086582018-06-26 15:26:28 +0200236 /* FIXME: Also add verbosity for other
237 * connection types (E1) as soon as
238 * the implementation is available */
239 if (conn->type == MGCP_CONN_TYPE_RTP) {
240 dump_rtp_end(vty, &conn->u.rtp);
241 }
242 }
243 }
244}
245
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200246static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
247{
248 vty_out(vty, "%s", VTY_NEWLINE);
249 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
250
251 if (ratectr->mgcp_general_ctr_group) {
252 vty_out(vty, " %s:%s",
253 ratectr->mgcp_general_ctr_group->desc->
254 group_description, VTY_NEWLINE);
255 vty_out_rate_ctr_group_fmt(vty,
256 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
257 ratectr->mgcp_general_ctr_group);
258 }
259}
260
261static void dump_ratectr_trunk(struct vty *vty, struct mgcp_ratectr_trunk *ratectr)
262{
263 vty_out(vty, "%s", VTY_NEWLINE);
264 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
265
266 if (ratectr->mgcp_crcx_ctr_group) {
267 vty_out(vty, " %s:%s",
268 ratectr->mgcp_crcx_ctr_group->desc->group_description,
269 VTY_NEWLINE);
270 vty_out_rate_ctr_group_fmt(vty,
271 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
272 ratectr->mgcp_crcx_ctr_group);
273 }
274 if (ratectr->mgcp_dlcx_ctr_group) {
275 vty_out(vty, " %s:%s",
276 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
277 VTY_NEWLINE);
278 vty_out_rate_ctr_group_fmt(vty,
279 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
280 ratectr->mgcp_dlcx_ctr_group);
281 }
282 if (ratectr->mgcp_mdcx_ctr_group) {
283 vty_out(vty, " %s:%s",
284 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
285 VTY_NEWLINE);
286 vty_out_rate_ctr_group_fmt(vty,
287 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
288 ratectr->mgcp_mdcx_ctr_group);
289 }
290 if (ratectr->all_rtp_conn_stats) {
291 vty_out(vty, " %s:%s",
292 ratectr->all_rtp_conn_stats->desc->group_description,
293 VTY_NEWLINE);
294 vty_out_rate_ctr_group_fmt(vty,
295 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
296 ratectr->all_rtp_conn_stats);
297 }
298}
299
300
301static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200302{
303 int i;
304
305 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200306 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
307 trunk->trunk_nr, trunk->number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200308
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200309 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200310 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
311 return;
312 }
313
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200314 for (i = 0; i < trunk->number_endpoints; ++i) {
315 struct mgcp_endpoint *endp = trunk->endpoints[i];
316 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
317 show_stats);
318 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200319 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200320 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200321
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200322 if (show_stats)
323 dump_ratectr_trunk(vty, &trunk->ratectr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200324}
325
Stefan Sperling12086582018-06-26 15:26:28 +0200326#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
327
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200328DEFUN(show_mcgp, show_mgcp_cmd,
329 "show mgcp [stats]",
330 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200331 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200332 "Include Statistics\n")
333{
Philipp Maier14b27a82020-06-02 20:15:30 +0200334 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200335 int show_stats = argc >= 1;
336
Harald Weltec39b1bf2020-03-08 11:29:39 +0100337 dump_trunk(vty, g_cfg->virt_trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200338
339 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200340 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200341
342 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200343 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200344 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200345
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200346 if (show_stats)
347 dump_ratectr_global(vty, &g_cfg->ratectr);
348
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200349 return CMD_SUCCESS;
350}
351
Stefan Sperling12086582018-06-26 15:26:28 +0200352static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200353dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200354{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200355 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200356
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200357 if (trunk) {
358 /* If a trunk is given, search on that specific trunk only */
359 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
360 if (!endp) {
361 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
362 return;
363 }
364 } else {
365 /* If no trunk is given, search on all possible trunks */
366 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
367 if (!endp) {
368 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
369 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200370 }
371 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200372
373 trunk = endp->trunk;
374 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200375}
376
377DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
378 "show mgcp endpoint NAME",
379 SHOW_STR
380 SHOW_MGCP_STR
381 "Display information about an endpoint\n" "The name of the endpoint\n")
382{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200383 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200384 return CMD_SUCCESS;
385}
386
387DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
388 "show mgcp trunk <0-64> endpoint NAME",
389 SHOW_STR
390 SHOW_MGCP_STR
391 "Display information about a trunk\n" "Trunk number\n"
392 "Display information about an endpoint\n" "The name of the endpoint\n")
393{
Philipp Maier14b27a82020-06-02 20:15:30 +0200394 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200395 int trunkidx = atoi(argv[0]);
396
397 trunk = find_trunk(g_cfg, trunkidx);
398 if (!trunk) {
399 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
400 return CMD_WARNING;
401 }
402
403 dump_mgcp_endpoint(vty, trunk, argv[1]);
404 return CMD_SUCCESS;
405}
406
Philipp Maier87bd9be2017-08-22 16:35:41 +0200407DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200408{
409 vty->node = MGCP_NODE;
410 return CMD_SUCCESS;
411}
412
413DEFUN(cfg_mgcp_local_ip,
414 cfg_mgcp_local_ip_cmd,
415 "local ip A.B.C.D",
416 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200417 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200418{
419 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
420 return CMD_SUCCESS;
421}
422
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200423#define BIND_STR "Listen/Bind related socket option\n"
424DEFUN(cfg_mgcp_bind_ip,
425 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200426 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200427{
428 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
429 return CMD_SUCCESS;
430}
431
432DEFUN(cfg_mgcp_bind_port,
433 cfg_mgcp_bind_port_cmd,
434 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200435 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200436{
437 unsigned int port = atoi(argv[0]);
438 g_cfg->source_port = port;
439 return CMD_SUCCESS;
440}
441
442DEFUN(cfg_mgcp_bind_early,
443 cfg_mgcp_bind_early_cmd,
444 "bind early (0|1)",
445 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200446 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200447{
448 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
449 return CMD_WARNING;
450}
451
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200452#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200453#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200454#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200455#define RANGE_START_STR "Start of the range of ports\n"
456#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200457
Philipp Maierf1889d82017-11-08 14:59:39 +0100458DEFUN(cfg_mgcp_rtp_port_range,
459 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200460 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200461 RTP_STR "Range of ports to use for the NET side\n"
462 RANGE_START_STR RANGE_END_STR)
463{
Philipp Maiera19547b2018-05-22 13:44:34 +0200464 int start;
465 int end;
466
467 start = atoi(argv[0]);
468 end = atoi(argv[1]);
469
470 if (end < start) {
471 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
472 end, start, VTY_NEWLINE);
473 return CMD_WARNING;
474 }
475
476 if (start & 1) {
477 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
478 start, start & 0xFFFE, VTY_NEWLINE);
479 start &= 0xFFFE;
480 }
481
482 if ((end & 1) == 0) {
483 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
484 end, end | 1, VTY_NEWLINE);
485 end |= 1;
486 }
487
488 g_cfg->net_ports.range_start = start;
489 g_cfg->net_ports.range_end = end;
490 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
491
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200492 return CMD_SUCCESS;
493}
Philipp Maierf1889d82017-11-08 14:59:39 +0100494ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
495 cfg_mgcp_rtp_net_range_cmd,
496 "rtp net-range <0-65534> <0-65534>",
497 RTP_STR "Range of ports to use for the NET side\n"
498 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200499
Philipp Maierf1889d82017-11-08 14:59:39 +0100500DEFUN(cfg_mgcp_rtp_bind_ip,
501 cfg_mgcp_rtp_bind_ip_cmd,
502 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200503 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
504{
505 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
506 return CMD_SUCCESS;
507}
Philipp Maierf1889d82017-11-08 14:59:39 +0100508ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
509 cfg_mgcp_rtp_net_bind_ip_cmd,
510 "rtp net-bind-ip A.B.C.D",
511 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200512
Philipp Maierf1889d82017-11-08 14:59:39 +0100513DEFUN(cfg_mgcp_rtp_no_bind_ip,
514 cfg_mgcp_rtp_no_bind_ip_cmd,
515 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200516 NO_STR RTP_STR "Bind endpoints facing the Network\n"
517 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200518{
519 talloc_free(g_cfg->net_ports.bind_addr);
520 g_cfg->net_ports.bind_addr = NULL;
521 return CMD_SUCCESS;
522}
Philipp Maierf1889d82017-11-08 14:59:39 +0100523ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
524 cfg_mgcp_rtp_no_net_bind_ip_cmd,
525 "no rtp net-bind-ip",
526 NO_STR RTP_STR "Bind endpoints facing the Network\n"
527 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200528
Philipp Maier1cb1e382017-11-02 17:16:04 +0100529DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
530 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
531 "rtp ip-probing",
532 RTP_STR "automatic rtp bind ip selection\n")
533{
534 g_cfg->net_ports.bind_addr_probe = true;
535 return CMD_SUCCESS;
536}
537
538DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
539 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
540 "no rtp ip-probing",
541 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
542{
543 g_cfg->net_ports.bind_addr_probe = false;
544 return CMD_SUCCESS;
545}
546
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200547DEFUN(cfg_mgcp_rtp_ip_dscp,
548 cfg_mgcp_rtp_ip_dscp_cmd,
549 "rtp ip-dscp <0-255>",
550 RTP_STR
551 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
552{
553 int dscp = atoi(argv[0]);
554 g_cfg->endp_dscp = dscp;
555 return CMD_SUCCESS;
556}
557
558ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200559 "rtp ip-tos <0-255>",
560 RTP_STR
561 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
562#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200563DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200564 cfg_mgcp_rtp_force_ptime_cmd,
565 "rtp force-ptime (10|20|40)",
566 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200567 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200568{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200569 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200570 return CMD_SUCCESS;
571}
572
573DEFUN(cfg_mgcp_no_rtp_force_ptime,
574 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200575 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200576{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200577 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200578 return CMD_SUCCESS;
579}
580
581DEFUN(cfg_mgcp_sdp_fmtp_extra,
582 cfg_mgcp_sdp_fmtp_extra_cmd,
583 "sdp audio fmtp-extra .NAME",
584 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
585 "Extra Information\n")
586{
587 char *txt = argv_concat(argv, argc, 0);
588 if (!txt)
589 return CMD_WARNING;
590
Harald Weltec39b1bf2020-03-08 11:29:39 +0100591 osmo_talloc_replace_string(g_cfg, &g_cfg->virt_trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200592 talloc_free(txt);
593 return CMD_SUCCESS;
594}
595
596DEFUN(cfg_mgcp_allow_transcoding,
597 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200598 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200599{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100600 g_cfg->virt_trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200601 return CMD_SUCCESS;
602}
603
604DEFUN(cfg_mgcp_no_allow_transcoding,
605 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200606 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200607{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100608 g_cfg->virt_trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200609 return CMD_SUCCESS;
610}
611
612#define SDP_STR "SDP File related options\n"
613#define AUDIO_STR "Audio payload options\n"
614DEFUN(cfg_mgcp_sdp_payload_number,
615 cfg_mgcp_sdp_payload_number_cmd,
616 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200617 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200618{
619 unsigned int payload = atoi(argv[0]);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100620 g_cfg->virt_trunk->audio_payload = payload;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200621 return CMD_SUCCESS;
622}
623
Philipp Maier87bd9be2017-08-22 16:35:41 +0200624ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
625 cfg_mgcp_sdp_payload_number_cmd_old,
626 "sdp audio payload number <0-255>",
627 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200628
Philipp Maier21be42a2020-05-29 21:39:48 +0200629DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200630 cfg_mgcp_sdp_payload_name_cmd,
631 "sdp audio-payload name NAME",
632 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
633{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100634 osmo_talloc_replace_string(g_cfg, &g_cfg->virt_trunk->audio_name, argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200635 return CMD_SUCCESS;
636}
637
638ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200639 "sdp audio payload name NAME",
640 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200641
Philipp Maier21be42a2020-05-29 21:39:48 +0200642DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200643 cfg_mgcp_sdp_payload_send_ptime_cmd,
644 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200645 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200646{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100647 g_cfg->virt_trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200648 return CMD_SUCCESS;
649}
650
651DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
652 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
653 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200654 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200655{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100656 g_cfg->virt_trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200657 return CMD_SUCCESS;
658}
659
660DEFUN(cfg_mgcp_sdp_payload_send_name,
661 cfg_mgcp_sdp_payload_send_name_cmd,
662 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200663 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200664{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100665 g_cfg->virt_trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200666 return CMD_SUCCESS;
667}
668
669DEFUN(cfg_mgcp_no_sdp_payload_send_name,
670 cfg_mgcp_no_sdp_payload_send_name_cmd,
671 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200672 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200673{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100674 g_cfg->virt_trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200675 return CMD_SUCCESS;
676}
677
678DEFUN(cfg_mgcp_loop,
679 cfg_mgcp_loop_cmd,
680 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200681 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200682{
683 if (g_cfg->osmux) {
684 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
685 return CMD_WARNING;
686 }
Harald Weltec39b1bf2020-03-08 11:29:39 +0100687 g_cfg->virt_trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200688 return CMD_SUCCESS;
689}
690
691DEFUN(cfg_mgcp_force_realloc,
692 cfg_mgcp_force_realloc_cmd,
693 "force-realloc (0|1)",
694 "Force endpoint reallocation when the endpoint is still seized\n"
695 "Don't force reallocation\n" "force reallocation\n")
696{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100697 g_cfg->virt_trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200698 return CMD_SUCCESS;
699}
700
Philipp Maier87bd9be2017-08-22 16:35:41 +0200701DEFUN(cfg_mgcp_rtp_accept_all,
702 cfg_mgcp_rtp_accept_all_cmd,
703 "rtp-accept-all (0|1)",
704 "Accept all RTP packets, even when the originating IP/Port does not match\n"
705 "enable filter\n" "disable filter\n")
706{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100707 g_cfg->virt_trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200708 return CMD_SUCCESS;
709}
710
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200711DEFUN(cfg_mgcp_number_endp,
712 cfg_mgcp_number_endp_cmd,
713 "number endpoints <0-65534>",
714 "Number options\n" "Endpoints available\n" "Number endpoints\n")
715{
716 /* + 1 as we start counting at one */
Harald Weltec39b1bf2020-03-08 11:29:39 +0100717 g_cfg->virt_trunk->vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200718 return CMD_SUCCESS;
719}
720
Philipp Maier87bd9be2017-08-22 16:35:41 +0200721DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200722{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100723 g_cfg->virt_trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200724 return CMD_SUCCESS;
725}
726
727DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200728 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200729{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100730 g_cfg->virt_trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200731 return CMD_SUCCESS;
732}
733
734DEFUN(cfg_mgcp_patch_rtp_ssrc,
735 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200736 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200737{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100738 g_cfg->virt_trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200739 return CMD_SUCCESS;
740}
741
742DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
743 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200744 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200745{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100746 g_cfg->virt_trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200747 return CMD_SUCCESS;
748}
749
750DEFUN(cfg_mgcp_patch_rtp_ts,
751 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200752 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200753{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100754 g_cfg->virt_trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200755 return CMD_SUCCESS;
756}
757
758DEFUN(cfg_mgcp_no_patch_rtp_ts,
759 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200760 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200761{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100762 g_cfg->virt_trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200763 return CMD_SUCCESS;
764}
765
Philipp Maier9fc8a022019-02-20 12:26:52 +0100766DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
767 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
768 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
769{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100770 g_cfg->virt_trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100771 return CMD_SUCCESS;
772}
773
774DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
775 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
776 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
777{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100778 g_cfg->virt_trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100779 return CMD_SUCCESS;
780}
781
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200782DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200783 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200784{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100785 g_cfg->virt_trunk->force_constant_ssrc = 0;
786 g_cfg->virt_trunk->force_aligned_timing = 0;
787 g_cfg->virt_trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200788 return CMD_SUCCESS;
789}
790
791DEFUN(cfg_mgcp_rtp_keepalive,
792 cfg_mgcp_rtp_keepalive_cmd,
793 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200794 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200795{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100796 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200797 return CMD_SUCCESS;
798}
799
800DEFUN(cfg_mgcp_rtp_keepalive_once,
801 cfg_mgcp_rtp_keepalive_once_cmd,
802 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200803 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200804{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100805 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200806 return CMD_SUCCESS;
807}
808
809DEFUN(cfg_mgcp_no_rtp_keepalive,
810 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200811 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200812{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100813 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200814 return CMD_SUCCESS;
815}
816
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200817#define CALL_AGENT_STR "Callagent information\n"
818DEFUN(cfg_mgcp_agent_addr,
819 cfg_mgcp_agent_addr_cmd,
820 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200821 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200822{
823 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
824 return CMD_SUCCESS;
825}
826
827ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200828 "call agent ip A.B.C.D",
829 CALL_AGENT_STR CALL_AGENT_STR IP_STR
830 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200831
Philipp Maier21be42a2020-05-29 21:39:48 +0200832DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200833 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200834{
Philipp Maier14b27a82020-06-02 20:15:30 +0200835 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200836 int index = atoi(argv[0]);
837
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200838 trunk = mgcp_trunk_by_num(g_cfg, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100839 if (!trunk) {
840 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200841 if (!trunk) {
842 vty_out(vty, "%%Unable to allocate trunk %u.%s",
843 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100844 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200845 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200846 }
847
848 vty->node = TRUNK_NODE;
849 vty->index = trunk;
850 return CMD_SUCCESS;
851}
852
853static int config_write_trunk(struct vty *vty)
854{
Philipp Maier14b27a82020-06-02 20:15:30 +0200855 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200856
857 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
858 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
859 vty_out(vty, " sdp audio-payload number %d%s",
860 trunk->audio_payload, VTY_NEWLINE);
861 vty_out(vty, " sdp audio-payload name %s%s",
862 trunk->audio_name, VTY_NEWLINE);
863 vty_out(vty, " %ssdp audio-payload send-ptime%s",
864 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
865 vty_out(vty, " %ssdp audio-payload send-name%s",
866 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
867
868 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
869 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
870 else if (trunk->keepalive_interval)
871 vty_out(vty, " rtp keep-alive %d%s",
872 trunk->keepalive_interval, VTY_NEWLINE);
873 else
874 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200875 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200876 vty_out(vty, " force-realloc %d%s",
877 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200878 vty_out(vty, " rtp-accept-all %d%s",
879 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200880 if (trunk->omit_rtcp)
881 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
882 else
883 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100884 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Harald Weltec39b1bf2020-03-08 11:29:39 +0100885 || g_cfg->virt_trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200886 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200887 trunk->force_constant_ssrc ? "" : "no ",
888 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200889 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200890 trunk->force_aligned_timing ? "" : "no ",
891 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100892 vty_out(vty, " %srtp-patch rfc5993hr%s",
893 trunk->rfc5993_hr_convert ? "" : "no ",
894 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200895 } else
896 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
897 if (trunk->audio_fmtp_extra)
898 vty_out(vty, " sdp audio fmtp-extra %s%s",
899 trunk->audio_fmtp_extra, VTY_NEWLINE);
900 vty_out(vty, " %sallow-transcoding%s",
901 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
902 }
903
904 return CMD_SUCCESS;
905}
906
907DEFUN(cfg_trunk_sdp_fmtp_extra,
908 cfg_trunk_sdp_fmtp_extra_cmd,
909 "sdp audio fmtp-extra .NAME",
910 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
911 "Extra Information\n")
912{
Philipp Maier14b27a82020-06-02 20:15:30 +0200913 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200914 char *txt = argv_concat(argv, argc, 0);
915 if (!txt)
916 return CMD_WARNING;
917
918 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
919 talloc_free(txt);
920 return CMD_SUCCESS;
921}
922
923DEFUN(cfg_trunk_payload_number,
924 cfg_trunk_payload_number_cmd,
925 "sdp audio-payload number <0-255>",
926 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
927{
Philipp Maier14b27a82020-06-02 20:15:30 +0200928 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200929 unsigned int payload = atoi(argv[0]);
930
931 trunk->audio_payload = payload;
932 return CMD_SUCCESS;
933}
934
935ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200936 "sdp audio payload number <0-255>",
937 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200938
Philipp Maier21be42a2020-05-29 21:39:48 +0200939DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200940 cfg_trunk_payload_name_cmd,
941 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200942 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200943{
Philipp Maier14b27a82020-06-02 20:15:30 +0200944 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200945
946 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
947 return CMD_SUCCESS;
948}
949
950ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200951 "sdp audio payload name NAME",
952 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200953
Philipp Maier21be42a2020-05-29 21:39:48 +0200954DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200955 cfg_trunk_loop_cmd,
956 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200957 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200958{
Philipp Maier14b27a82020-06-02 20:15:30 +0200959 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200960
961 if (g_cfg->osmux) {
962 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
963 return CMD_WARNING;
964 }
965 trunk->audio_loop = atoi(argv[0]);
966 return CMD_SUCCESS;
967}
968
969DEFUN(cfg_trunk_sdp_payload_send_ptime,
970 cfg_trunk_sdp_payload_send_ptime_cmd,
971 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200972 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200973{
Philipp Maier14b27a82020-06-02 20:15:30 +0200974 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200975 trunk->audio_send_ptime = 1;
976 return CMD_SUCCESS;
977}
978
979DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
980 cfg_trunk_no_sdp_payload_send_ptime_cmd,
981 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200982 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200983{
Philipp Maier14b27a82020-06-02 20:15:30 +0200984 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200985 trunk->audio_send_ptime = 0;
986 return CMD_SUCCESS;
987}
988
989DEFUN(cfg_trunk_sdp_payload_send_name,
990 cfg_trunk_sdp_payload_send_name_cmd,
991 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200992 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200993{
Philipp Maier14b27a82020-06-02 20:15:30 +0200994 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200995 trunk->audio_send_name = 1;
996 return CMD_SUCCESS;
997}
998
999DEFUN(cfg_trunk_no_sdp_payload_send_name,
1000 cfg_trunk_no_sdp_payload_send_name_cmd,
1001 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001002 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001003{
Philipp Maier14b27a82020-06-02 20:15:30 +02001004 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001005 trunk->audio_send_name = 0;
1006 return CMD_SUCCESS;
1007}
1008
Philipp Maier87bd9be2017-08-22 16:35:41 +02001009DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001010{
Philipp Maier14b27a82020-06-02 20:15:30 +02001011 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001012 trunk->omit_rtcp = 1;
1013 return CMD_SUCCESS;
1014}
1015
1016DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001017 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001018{
Philipp Maier14b27a82020-06-02 20:15:30 +02001019 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001020 trunk->omit_rtcp = 0;
1021 return CMD_SUCCESS;
1022}
1023
1024DEFUN(cfg_trunk_patch_rtp_ssrc,
1025 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001026 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001027{
Philipp Maier14b27a82020-06-02 20:15:30 +02001028 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001029 trunk->force_constant_ssrc = 1;
1030 return CMD_SUCCESS;
1031}
1032
1033DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1034 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001035 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001036{
Philipp Maier14b27a82020-06-02 20:15:30 +02001037 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001038 trunk->force_constant_ssrc = 0;
1039 return CMD_SUCCESS;
1040}
1041
1042DEFUN(cfg_trunk_patch_rtp_ts,
1043 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001044 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001045{
Philipp Maier14b27a82020-06-02 20:15:30 +02001046 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001047 trunk->force_aligned_timing = 1;
1048 return CMD_SUCCESS;
1049}
1050
1051DEFUN(cfg_trunk_no_patch_rtp_ts,
1052 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001053 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001054{
Philipp Maier14b27a82020-06-02 20:15:30 +02001055 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001056 trunk->force_aligned_timing = 0;
1057 return CMD_SUCCESS;
1058}
1059
Philipp Maier9fc8a022019-02-20 12:26:52 +01001060DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1061 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1062 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1063{
Philipp Maier14b27a82020-06-02 20:15:30 +02001064 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001065 trunk->rfc5993_hr_convert = true;
1066 return CMD_SUCCESS;
1067}
1068
1069DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1070 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1071 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1072{
Philipp Maier14b27a82020-06-02 20:15:30 +02001073 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001074 trunk->rfc5993_hr_convert = false;
1075 return CMD_SUCCESS;
1076}
1077
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001078DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001079 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001080{
Philipp Maier14b27a82020-06-02 20:15:30 +02001081 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001082 trunk->force_constant_ssrc = 0;
1083 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001084 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001085 return CMD_SUCCESS;
1086}
1087
1088DEFUN(cfg_trunk_rtp_keepalive,
1089 cfg_trunk_rtp_keepalive_cmd,
1090 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001091 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001092{
Philipp Maier14b27a82020-06-02 20:15:30 +02001093 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001094 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1095 return CMD_SUCCESS;
1096}
1097
1098DEFUN(cfg_trunk_rtp_keepalive_once,
1099 cfg_trunk_rtp_keepalive_once_cmd,
1100 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001101 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001102{
Philipp Maier14b27a82020-06-02 20:15:30 +02001103 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001104 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1105 return CMD_SUCCESS;
1106}
1107
1108DEFUN(cfg_trunk_no_rtp_keepalive,
1109 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001110 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001111{
Philipp Maier14b27a82020-06-02 20:15:30 +02001112 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001113 mgcp_trunk_set_keepalive(trunk, 0);
1114 return CMD_SUCCESS;
1115}
1116
1117DEFUN(cfg_trunk_allow_transcoding,
1118 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001119 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001120{
Philipp Maier14b27a82020-06-02 20:15:30 +02001121 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001122 trunk->no_audio_transcoding = 0;
1123 return CMD_SUCCESS;
1124}
1125
1126DEFUN(cfg_trunk_no_allow_transcoding,
1127 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001128 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001129{
Philipp Maier14b27a82020-06-02 20:15:30 +02001130 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001131 trunk->no_audio_transcoding = 1;
1132 return CMD_SUCCESS;
1133}
1134
Philipp Maier87bd9be2017-08-22 16:35:41 +02001135DEFUN(loop_conn,
1136 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001137 "loop-endpoint <0-64> NAME (0|1)",
1138 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001139 "The name in hex of the endpoint\n" "Disable the loop\n"
1140 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001141{
Philipp Maier14b27a82020-06-02 20:15:30 +02001142 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001143 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001144 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001145
1146 trunk = find_trunk(g_cfg, atoi(argv[0]));
1147 if (!trunk) {
1148 vty_out(vty, "%%Trunk %d not found in the config.%s",
1149 atoi(argv[0]), VTY_NEWLINE);
1150 return CMD_WARNING;
1151 }
1152
1153 if (!trunk->endpoints) {
1154 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1155 trunk->trunk_nr, VTY_NEWLINE);
1156 return CMD_WARNING;
1157 }
1158
1159 int endp_no = strtoul(argv[1], NULL, 16);
1160 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1161 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001162 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001163 return CMD_WARNING;
1164 }
1165
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001166 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001167 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001168 llist_for_each_entry(conn, &endp->conns, entry) {
1169 if (conn->type == MGCP_CONN_TYPE_RTP)
1170 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1171 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1172 else {
1173 /* FIXME: Introduce support for other connection (E1)
1174 * types when implementation is available */
1175 vty_out(vty, "%%Can't enable SSRC patching,"
1176 "connection %s is not an RTP connection.%s",
1177 mgcp_conn_dump(conn), VTY_NEWLINE);
1178 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001179
Philipp Maier87bd9be2017-08-22 16:35:41 +02001180 if (loop)
1181 conn->mode = MGCP_CONN_LOOPBACK;
1182 else
1183 conn->mode = conn->mode_orig;
1184 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001185
1186 return CMD_SUCCESS;
1187}
1188
Philipp Maier87bd9be2017-08-22 16:35:41 +02001189DEFUN(tap_rtp,
1190 tap_rtp_cmd,
1191 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001192 "Forward data on endpoint to a different system\n" "Trunk number\n"
1193 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001194 "The connection id in hex\n"
1195 "Forward incoming data\n"
1196 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001197 "destination IP of the data\n" "destination port\n")
1198{
1199 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001200 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001201 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001202 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001203 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001204
1205 trunk = find_trunk(g_cfg, atoi(argv[0]));
1206 if (!trunk) {
1207 vty_out(vty, "%%Trunk %d not found in the config.%s",
1208 atoi(argv[0]), VTY_NEWLINE);
1209 return CMD_WARNING;
1210 }
1211
1212 if (!trunk->endpoints) {
1213 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1214 trunk->trunk_nr, VTY_NEWLINE);
1215 return CMD_WARNING;
1216 }
1217
1218 int endp_no = strtoul(argv[1], NULL, 16);
1219 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1220 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001221 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001222 return CMD_WARNING;
1223 }
1224
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001225 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001226
Philipp Maier01d24a32017-11-21 17:26:09 +01001227 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001228 conn = mgcp_conn_get_rtp(endp, conn_id);
1229 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001230 vty_out(vty, "Conn ID %s is invalid.%s",
1231 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001232 return CMD_WARNING;
1233 }
1234
1235 if (strcmp(argv[3], "in") == 0)
1236 tap = &conn->tap_in;
1237 else if (strcmp(argv[3], "out") == 0)
1238 tap = &conn->tap_out;
1239 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001240 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1241 return CMD_WARNING;
1242 }
1243
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001244 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001245 inet_aton(argv[4], &tap->forward.sin_addr);
1246 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001247 tap->enabled = 1;
1248 return CMD_SUCCESS;
1249}
1250
1251DEFUN(free_endp, free_endp_cmd,
1252 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001253 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001254{
Philipp Maier14b27a82020-06-02 20:15:30 +02001255 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001256 struct mgcp_endpoint *endp;
1257
1258 trunk = find_trunk(g_cfg, atoi(argv[0]));
1259 if (!trunk) {
1260 vty_out(vty, "%%Trunk %d not found in the config.%s",
1261 atoi(argv[0]), VTY_NEWLINE);
1262 return CMD_WARNING;
1263 }
1264
1265 if (!trunk->endpoints) {
1266 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1267 trunk->trunk_nr, VTY_NEWLINE);
1268 return CMD_WARNING;
1269 }
1270
1271 int endp_no = strtoul(argv[1], NULL, 16);
1272 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1273 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001274 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001275 return CMD_WARNING;
1276 }
1277
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001278 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001279 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001280 return CMD_SUCCESS;
1281}
1282
1283DEFUN(reset_endp, reset_endp_cmd,
1284 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001285 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001286{
Philipp Maier14b27a82020-06-02 20:15:30 +02001287 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001288 struct mgcp_endpoint *endp;
1289 int endp_no, rc;
1290
1291 trunk = find_trunk(g_cfg, atoi(argv[0]));
1292 if (!trunk) {
1293 vty_out(vty, "%%Trunk %d not found in the config.%s",
1294 atoi(argv[0]), VTY_NEWLINE);
1295 return CMD_WARNING;
1296 }
1297
1298 if (!trunk->endpoints) {
1299 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1300 trunk->trunk_nr, VTY_NEWLINE);
1301 return CMD_WARNING;
1302 }
1303
1304 endp_no = strtoul(argv[1], NULL, 16);
1305 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1306 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001307 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001308 return CMD_WARNING;
1309 }
1310
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001311 endp = trunk->endpoints[endp_no];
1312 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001313 if (rc < 0) {
1314 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1315 return CMD_WARNING;
1316 }
1317 return CMD_SUCCESS;
1318}
1319
1320DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001321 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001322{
1323 int rc;
1324
1325 rc = mgcp_send_reset_all(g_cfg);
1326 if (rc < 0) {
1327 vty_out(vty, "Error %d during endpoint reset.%s",
1328 rc, VTY_NEWLINE);
1329 return CMD_WARNING;
1330 }
1331 return CMD_SUCCESS;
1332}
1333
1334#define OSMUX_STR "RTP multiplexing\n"
1335DEFUN(cfg_mgcp_osmux,
1336 cfg_mgcp_osmux_cmd,
1337 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001338 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001339{
1340 if (strcmp(argv[0], "off") == 0) {
1341 g_cfg->osmux = OSMUX_USAGE_OFF;
1342 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001343 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001344 g_cfg->osmux = OSMUX_USAGE_ON;
1345 else if (strcmp(argv[0], "only") == 0)
1346 g_cfg->osmux = OSMUX_USAGE_ONLY;
1347
Harald Weltec39b1bf2020-03-08 11:29:39 +01001348 if (g_cfg->virt_trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001349 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001350 return CMD_WARNING;
1351 }
1352
1353 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001354
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001355}
1356
1357DEFUN(cfg_mgcp_osmux_ip,
1358 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001359 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001360{
1361 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1362 return CMD_SUCCESS;
1363}
1364
1365DEFUN(cfg_mgcp_osmux_batch_factor,
1366 cfg_mgcp_osmux_batch_factor_cmd,
1367 "osmux batch-factor <1-8>",
1368 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1369{
1370 g_cfg->osmux_batch = atoi(argv[0]);
1371 return CMD_SUCCESS;
1372}
1373
1374DEFUN(cfg_mgcp_osmux_batch_size,
1375 cfg_mgcp_osmux_batch_size_cmd,
1376 "osmux batch-size <1-65535>",
1377 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1378{
1379 g_cfg->osmux_batch_size = atoi(argv[0]);
1380 return CMD_SUCCESS;
1381}
1382
1383DEFUN(cfg_mgcp_osmux_port,
1384 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001385 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001386{
1387 g_cfg->osmux_port = atoi(argv[0]);
1388 return CMD_SUCCESS;
1389}
1390
1391DEFUN(cfg_mgcp_osmux_dummy,
1392 cfg_mgcp_osmux_dummy_cmd,
1393 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001394 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1395 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001396{
1397 if (strcmp(argv[0], "on") == 0)
1398 g_cfg->osmux_dummy = 1;
1399 else if (strcmp(argv[0], "off") == 0)
1400 g_cfg->osmux_dummy = 0;
1401
1402 return CMD_SUCCESS;
1403}
1404
Philipp Maier12943ea2018-01-17 15:40:25 +01001405DEFUN(cfg_mgcp_domain,
1406 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001407 "domain NAME",
1408 "Set the domain part expected in MGCP messages' endpoint names\n"
1409 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001410{
1411 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1412 return CMD_SUCCESS;
1413}
1414
Oliver Smithe36b7752019-01-22 16:31:36 +01001415DEFUN(cfg_mgcp_conn_timeout,
1416 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001417 "conn-timeout <0-65534>",
1418 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1419 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001420 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1421 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001422 "Timeout value (sec.)\n")
1423{
1424 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1425 return CMD_SUCCESS;
1426}
1427
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001428int mgcp_vty_init(void)
1429{
1430 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001431 install_element_ve(&show_mgcp_endpoint_cmd);
1432 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001433 install_element(ENABLE_NODE, &loop_conn_cmd);
1434 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001435 install_element(ENABLE_NODE, &free_endp_cmd);
1436 install_element(ENABLE_NODE, &reset_endp_cmd);
1437 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1438
1439 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1440 install_node(&mgcp_node, config_write_mgcp);
1441
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001442 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001443 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1444 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1445 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001446 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001447 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001448 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001449 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001450 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001451 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001452 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1453 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001454 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1455 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1456 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1457 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1458 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1459 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1460 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1461 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1462 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001463 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1464 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1465 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1466 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1467 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1468 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001469 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001470 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1471 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1472 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1473 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1474 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1475 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1476 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1477 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001478 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1479 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001480 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1481 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1482 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1483 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1484 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1485 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1486 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1487 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1488 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1489 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1490 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1491 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1492 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001493 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001494 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001495
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001496 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1497 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001498 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1499 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1500 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1501 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1502 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1503 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1504 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1505 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1506 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1507 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1508 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1509 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1510 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001511 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1512 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001513 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1514 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1515 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1516 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1517 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1518 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1519 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1520 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1521 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1522
1523 return 0;
1524}
1525
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001526int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1527 enum mgcp_role role)
1528{
1529 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001530 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001531
1532 cfg->osmux_port = OSMUX_PORT;
1533 cfg->osmux_batch = 4;
1534 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1535
1536 g_cfg = cfg;
1537 rc = vty_read_config_file(config_file, NULL);
1538 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001539 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1540 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001541 return rc;
1542 }
1543
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001544 if (!g_cfg->source_addr) {
1545 fprintf(stderr, "You need to specify a bind address.\n");
1546 return -1;
1547 }
1548
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001549 if (mgcp_trunk_alloc_endpts(g_cfg->virt_trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001550 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001551 "Failed to initialize the virtual trunk (%d endpoints)\n",
Harald Weltec39b1bf2020-03-08 11:29:39 +01001552 g_cfg->virt_trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001553 return -1;
1554 }
1555
1556 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001557 if (mgcp_trunk_alloc_endpts(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001558 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001559 "Failed to initialize trunk %d (%d endpoints)\n",
1560 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001561 return -1;
1562 }
1563 }
1564 cfg->role = role;
1565
1566 return 0;
1567}