blob: 35b75fb2df6ea7444f17d72c7b7b91a9c128571e [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
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020046struct cmd_node mgcp_node = {
47 MGCP_NODE,
48 "%s(config-mgcp)# ",
49 1,
50};
51
52struct cmd_node trunk_node = {
53 TRUNK_NODE,
54 "%s(config-mgcp-trunk)# ",
55 1,
56};
57
58static int config_write_mgcp(struct vty *vty)
59{
Philipp Maier6fbbeec2020-07-01 23:00:54 +020060 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +020061 OSMO_ASSERT(trunk);
Harald Weltec39b1bf2020-03-08 11:29:39 +010062
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020063 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020064 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020065 if (g_cfg->local_ip)
66 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020067 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
68 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
69 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020070 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
71 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020072 if (g_cfg->net_ports.bind_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +020073 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020074 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010075 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020076 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010077 else
Philipp Maierf53796c2020-06-02 20:38:28 +020078 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
79 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010080 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020081 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010082 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020083 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010084 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020085 else
Philipp Maierf53796c2020-06-02 20:38:28 +020086 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020087
Harald Weltec39b1bf2020-03-08 11:29:39 +010088 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +020089 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020090 else
Philipp Maierf53796c2020-06-02 20:38:28 +020091 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010092 if (trunk->force_constant_ssrc
93 || trunk->force_aligned_timing
94 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +020095 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010096 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +020097 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020098 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010099 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200100 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200101 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100102 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100103 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200104 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200105 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100106 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200107 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100108 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200109 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100110 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200111 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100112 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200113 vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
114 vty_out(vty, " number endpoints %u%s",
Philipp Maier869b21c2020-07-03 16:04:16 +0200115 trunk->vty_number_endpoints, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200116 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100117 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200118 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200119 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200120 VTY_NEWLINE);
121 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200122 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200123 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200124
125 switch (g_cfg->osmux) {
126 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200127 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200128 break;
129 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200130 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200131 break;
132 case OSMUX_USAGE_OFF:
133 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200134 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200135 break;
136 }
137 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200138 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200139 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200140 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200141 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200142 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200143 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200144 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200145 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200146 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200147 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
148 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100149
150 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200151 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100152
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200153 return CMD_SUCCESS;
154}
155
Philipp Maiercede2a42018-07-03 14:14:21 +0200156static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200157{
Philipp Maiercede2a42018-07-03 14:14:21 +0200158 struct mgcp_rtp_state *state = &conn->state;
159 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200160 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100161 struct rate_ctr *tx_packets, *tx_bytes;
162 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200163 struct rate_ctr *dropped_packets;
164
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100165 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
166 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
167 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
168 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200169 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200170
171 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100172 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
173 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200174 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
175 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200176 " Payload Type: %d Rate: %u Channels: %d %s"
177 " Frame Duration: %u Frame Denominator: %u%s"
178 " FPP: %d Packet Duration: %u%s"
179 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
180 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100181 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
182 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200183 state->in_stream.err_ts_ctr->current,
184 state->out_stream.err_ts_ctr->current,
185 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200186 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200187 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200188 codec->frame_duration_num, codec->frame_duration_den,
189 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
190 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
191 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
192 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200193}
194
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200195static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200196 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200197{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200198 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200199
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200200 vty_out(vty, "%s trunk %d endpoint %s:%s",
201 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Philipp Maier8d6a1932020-06-18 12:19:31 +0200202 vty_out(vty, " Availability: %s%s",
203 mgcp_endp_avail(endp) ? "available" : "not in service", VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200204
205 if (llist_empty(&endp->conns)) {
206 vty_out(vty, " No active connections%s", VTY_NEWLINE);
207 return;
208 }
209
210 llist_for_each_entry(conn, &endp->conns, entry) {
211 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
212
213 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100214 if (endp->cfg->conn_timeout) {
215 struct timeval remaining;
216 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
217 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
218 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
219 }
220
Stefan Sperling12086582018-06-26 15:26:28 +0200221 /* FIXME: Also add verbosity for other
222 * connection types (E1) as soon as
223 * the implementation is available */
224 if (conn->type == MGCP_CONN_TYPE_RTP) {
225 dump_rtp_end(vty, &conn->u.rtp);
226 }
227 }
228 }
229}
230
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200231static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
232{
233 vty_out(vty, "%s", VTY_NEWLINE);
234 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
235
236 if (ratectr->mgcp_general_ctr_group) {
237 vty_out(vty, " %s:%s",
238 ratectr->mgcp_general_ctr_group->desc->
239 group_description, VTY_NEWLINE);
240 vty_out_rate_ctr_group_fmt(vty,
241 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
242 ratectr->mgcp_general_ctr_group);
243 }
244}
245
246static void dump_ratectr_trunk(struct vty *vty, struct mgcp_ratectr_trunk *ratectr)
247{
248 vty_out(vty, "%s", VTY_NEWLINE);
249 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
250
251 if (ratectr->mgcp_crcx_ctr_group) {
252 vty_out(vty, " %s:%s",
253 ratectr->mgcp_crcx_ctr_group->desc->group_description,
254 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_crcx_ctr_group);
258 }
259 if (ratectr->mgcp_dlcx_ctr_group) {
260 vty_out(vty, " %s:%s",
261 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
262 VTY_NEWLINE);
263 vty_out_rate_ctr_group_fmt(vty,
264 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
265 ratectr->mgcp_dlcx_ctr_group);
266 }
267 if (ratectr->mgcp_mdcx_ctr_group) {
268 vty_out(vty, " %s:%s",
269 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
270 VTY_NEWLINE);
271 vty_out_rate_ctr_group_fmt(vty,
272 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
273 ratectr->mgcp_mdcx_ctr_group);
274 }
275 if (ratectr->all_rtp_conn_stats) {
276 vty_out(vty, " %s:%s",
277 ratectr->all_rtp_conn_stats->desc->group_description,
278 VTY_NEWLINE);
279 vty_out_rate_ctr_group_fmt(vty,
280 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
281 ratectr->all_rtp_conn_stats);
282 }
283}
284
285
286static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200287{
288 int i;
289
290 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200291 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
Philipp Maier869b21c2020-07-03 16:04:16 +0200292 trunk->trunk_nr, trunk->number_endpoints, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200293
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200294 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200295 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
296 return;
297 }
298
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200299 for (i = 0; i < trunk->number_endpoints; ++i) {
300 struct mgcp_endpoint *endp = trunk->endpoints[i];
301 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
302 show_stats);
303 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200304 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200305 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200306
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200307 if (show_stats)
308 dump_ratectr_trunk(vty, &trunk->ratectr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200309}
310
Stefan Sperling12086582018-06-26 15:26:28 +0200311#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
312
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200313DEFUN(show_mcgp, show_mgcp_cmd,
314 "show mgcp [stats]",
315 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200316 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200317 "Include Statistics\n")
318{
Philipp Maier14b27a82020-06-02 20:15:30 +0200319 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200320 int show_stats = argc >= 1;
321
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200322 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200323 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200324
325 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200326 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200327 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200328
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200329 if (show_stats)
330 dump_ratectr_global(vty, &g_cfg->ratectr);
331
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200332 return CMD_SUCCESS;
333}
334
Stefan Sperling12086582018-06-26 15:26:28 +0200335static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200336dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200337{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200338 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200339
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200340 if (trunk) {
341 /* If a trunk is given, search on that specific trunk only */
342 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
343 if (!endp) {
344 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
345 return;
346 }
347 } else {
348 /* If no trunk is given, search on all possible trunks */
349 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
350 if (!endp) {
351 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
352 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200353 }
354 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200355
356 trunk = endp->trunk;
357 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200358}
359
360DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
361 "show mgcp endpoint NAME",
362 SHOW_STR
363 SHOW_MGCP_STR
364 "Display information about an endpoint\n" "The name of the endpoint\n")
365{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200366 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200367 return CMD_SUCCESS;
368}
369
370DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
371 "show mgcp trunk <0-64> endpoint NAME",
372 SHOW_STR
373 SHOW_MGCP_STR
374 "Display information about a trunk\n" "Trunk number\n"
375 "Display information about an endpoint\n" "The name of the endpoint\n")
376{
Philipp Maier14b27a82020-06-02 20:15:30 +0200377 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200378 int trunkidx = atoi(argv[0]);
379
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200380 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200381 if (!trunk) {
382 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
383 return CMD_WARNING;
384 }
385
386 dump_mgcp_endpoint(vty, trunk, argv[1]);
387 return CMD_SUCCESS;
388}
389
Philipp Maier87bd9be2017-08-22 16:35:41 +0200390DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200391{
392 vty->node = MGCP_NODE;
393 return CMD_SUCCESS;
394}
395
396DEFUN(cfg_mgcp_local_ip,
397 cfg_mgcp_local_ip_cmd,
398 "local ip A.B.C.D",
399 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200400 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200401{
402 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
403 return CMD_SUCCESS;
404}
405
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200406#define BIND_STR "Listen/Bind related socket option\n"
407DEFUN(cfg_mgcp_bind_ip,
408 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200409 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200410{
411 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
412 return CMD_SUCCESS;
413}
414
415DEFUN(cfg_mgcp_bind_port,
416 cfg_mgcp_bind_port_cmd,
417 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200418 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200419{
420 unsigned int port = atoi(argv[0]);
421 g_cfg->source_port = port;
422 return CMD_SUCCESS;
423}
424
425DEFUN(cfg_mgcp_bind_early,
426 cfg_mgcp_bind_early_cmd,
427 "bind early (0|1)",
428 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200429 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200430{
431 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
432 return CMD_WARNING;
433}
434
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200435#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200436#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200437#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200438#define RANGE_START_STR "Start of the range of ports\n"
439#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200440
Philipp Maierf1889d82017-11-08 14:59:39 +0100441DEFUN(cfg_mgcp_rtp_port_range,
442 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200443 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200444 RTP_STR "Range of ports to use for the NET side\n"
445 RANGE_START_STR RANGE_END_STR)
446{
Philipp Maiera19547b2018-05-22 13:44:34 +0200447 int start;
448 int end;
449
450 start = atoi(argv[0]);
451 end = atoi(argv[1]);
452
453 if (end < start) {
454 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
455 end, start, VTY_NEWLINE);
456 return CMD_WARNING;
457 }
458
459 if (start & 1) {
460 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
461 start, start & 0xFFFE, VTY_NEWLINE);
462 start &= 0xFFFE;
463 }
464
465 if ((end & 1) == 0) {
466 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
467 end, end | 1, VTY_NEWLINE);
468 end |= 1;
469 }
470
471 g_cfg->net_ports.range_start = start;
472 g_cfg->net_ports.range_end = end;
473 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
474
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200475 return CMD_SUCCESS;
476}
Philipp Maierf1889d82017-11-08 14:59:39 +0100477ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
478 cfg_mgcp_rtp_net_range_cmd,
479 "rtp net-range <0-65534> <0-65534>",
480 RTP_STR "Range of ports to use for the NET side\n"
481 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200482
Philipp Maierf1889d82017-11-08 14:59:39 +0100483DEFUN(cfg_mgcp_rtp_bind_ip,
484 cfg_mgcp_rtp_bind_ip_cmd,
485 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200486 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
487{
488 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
489 return CMD_SUCCESS;
490}
Philipp Maierf1889d82017-11-08 14:59:39 +0100491ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
492 cfg_mgcp_rtp_net_bind_ip_cmd,
493 "rtp net-bind-ip A.B.C.D",
494 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200495
Philipp Maierf1889d82017-11-08 14:59:39 +0100496DEFUN(cfg_mgcp_rtp_no_bind_ip,
497 cfg_mgcp_rtp_no_bind_ip_cmd,
498 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200499 NO_STR RTP_STR "Bind endpoints facing the Network\n"
500 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200501{
502 talloc_free(g_cfg->net_ports.bind_addr);
503 g_cfg->net_ports.bind_addr = NULL;
504 return CMD_SUCCESS;
505}
Philipp Maierf1889d82017-11-08 14:59:39 +0100506ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
507 cfg_mgcp_rtp_no_net_bind_ip_cmd,
508 "no rtp net-bind-ip",
509 NO_STR RTP_STR "Bind endpoints facing the Network\n"
510 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200511
Philipp Maier1cb1e382017-11-02 17:16:04 +0100512DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
513 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
514 "rtp ip-probing",
515 RTP_STR "automatic rtp bind ip selection\n")
516{
517 g_cfg->net_ports.bind_addr_probe = true;
518 return CMD_SUCCESS;
519}
520
521DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
522 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
523 "no rtp ip-probing",
524 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
525{
526 g_cfg->net_ports.bind_addr_probe = false;
527 return CMD_SUCCESS;
528}
529
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200530DEFUN(cfg_mgcp_rtp_ip_dscp,
531 cfg_mgcp_rtp_ip_dscp_cmd,
532 "rtp ip-dscp <0-255>",
533 RTP_STR
534 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
535{
536 int dscp = atoi(argv[0]);
537 g_cfg->endp_dscp = dscp;
538 return CMD_SUCCESS;
539}
540
541ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200542 "rtp ip-tos <0-255>",
543 RTP_STR
544 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
545#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200546DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200547 cfg_mgcp_rtp_force_ptime_cmd,
548 "rtp force-ptime (10|20|40)",
549 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200550 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200551{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200552 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200553 return CMD_SUCCESS;
554}
555
556DEFUN(cfg_mgcp_no_rtp_force_ptime,
557 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200558 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200559{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200560 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200561 return CMD_SUCCESS;
562}
563
564DEFUN(cfg_mgcp_sdp_fmtp_extra,
565 cfg_mgcp_sdp_fmtp_extra_cmd,
566 "sdp audio fmtp-extra .NAME",
567 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
568 "Extra Information\n")
569{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200570 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200571 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200572 char *txt = argv_concat(argv, argc, 0);
573 if (!txt)
574 return CMD_WARNING;
575
Philipp Maierd19de2e2020-06-03 13:55:33 +0200576 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200577 talloc_free(txt);
578 return CMD_SUCCESS;
579}
580
581DEFUN(cfg_mgcp_allow_transcoding,
582 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200583 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200584{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200585 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200586 OSMO_ASSERT(trunk);
587 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200588 return CMD_SUCCESS;
589}
590
591DEFUN(cfg_mgcp_no_allow_transcoding,
592 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200593 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200594{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200595 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200596 OSMO_ASSERT(trunk);
597 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200598 return CMD_SUCCESS;
599}
600
601#define SDP_STR "SDP File related options\n"
602#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200603DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200604 cfg_mgcp_sdp_payload_number_cmd,
605 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200606 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200607{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200608 return CMD_SUCCESS;
609}
610
Philipp Maier87bd9be2017-08-22 16:35:41 +0200611ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
612 cfg_mgcp_sdp_payload_number_cmd_old,
613 "sdp audio payload number <0-255>",
614 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200615
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200616DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200617 cfg_mgcp_sdp_payload_name_cmd,
618 "sdp audio-payload name NAME",
619 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
620{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200621 return CMD_SUCCESS;
622}
623
624ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200625 "sdp audio payload name NAME",
626 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200627
Philipp Maier21be42a2020-05-29 21:39:48 +0200628DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200629 cfg_mgcp_sdp_payload_send_ptime_cmd,
630 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200631 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200632{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200633 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200634 OSMO_ASSERT(trunk);
635 trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200636 return CMD_SUCCESS;
637}
638
639DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
640 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
641 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200642 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200643{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200644 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200645 OSMO_ASSERT(trunk);
646 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200647 return CMD_SUCCESS;
648}
649
650DEFUN(cfg_mgcp_sdp_payload_send_name,
651 cfg_mgcp_sdp_payload_send_name_cmd,
652 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200653 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200654{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200655 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200656 OSMO_ASSERT(trunk);
657 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200658 return CMD_SUCCESS;
659}
660
661DEFUN(cfg_mgcp_no_sdp_payload_send_name,
662 cfg_mgcp_no_sdp_payload_send_name_cmd,
663 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200664 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200665{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200666 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200667 OSMO_ASSERT(trunk);
668 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200669 return CMD_SUCCESS;
670}
671
672DEFUN(cfg_mgcp_loop,
673 cfg_mgcp_loop_cmd,
674 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200675 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200676{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200677 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200678 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200679 if (g_cfg->osmux) {
680 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
681 return CMD_WARNING;
682 }
Philipp Maierd19de2e2020-06-03 13:55:33 +0200683 trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200684 return CMD_SUCCESS;
685}
686
687DEFUN(cfg_mgcp_force_realloc,
688 cfg_mgcp_force_realloc_cmd,
689 "force-realloc (0|1)",
690 "Force endpoint reallocation when the endpoint is still seized\n"
691 "Don't force reallocation\n" "force reallocation\n")
692{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200693 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200694 OSMO_ASSERT(trunk);
695 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200696 return CMD_SUCCESS;
697}
698
Philipp Maier87bd9be2017-08-22 16:35:41 +0200699DEFUN(cfg_mgcp_rtp_accept_all,
700 cfg_mgcp_rtp_accept_all_cmd,
701 "rtp-accept-all (0|1)",
702 "Accept all RTP packets, even when the originating IP/Port does not match\n"
703 "enable filter\n" "disable filter\n")
704{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200705 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200706 OSMO_ASSERT(trunk);
707 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,
Philipp Maier869b21c2020-07-03 16:04:16 +0200713 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200714 "Number options\n" "Endpoints available\n" "Number endpoints\n")
715{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200716 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200717 OSMO_ASSERT(trunk);
Philipp Maier869b21c2020-07-03 16:04:16 +0200718 trunk->vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200719 return CMD_SUCCESS;
720}
721
Philipp Maier87bd9be2017-08-22 16:35:41 +0200722DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200723{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200724 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200725 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200726 return CMD_SUCCESS;
727}
728
729DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200730 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200731{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200732 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200733 OSMO_ASSERT(trunk);
734 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200735 return CMD_SUCCESS;
736}
737
738DEFUN(cfg_mgcp_patch_rtp_ssrc,
739 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200740 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200741{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200742 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200743 OSMO_ASSERT(trunk);
744 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200745 return CMD_SUCCESS;
746}
747
748DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
749 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200750 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200751{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200752 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200753 OSMO_ASSERT(trunk);
754 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200755 return CMD_SUCCESS;
756}
757
758DEFUN(cfg_mgcp_patch_rtp_ts,
759 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200760 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200761{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200762 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200763 OSMO_ASSERT(trunk);
764 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200765 return CMD_SUCCESS;
766}
767
768DEFUN(cfg_mgcp_no_patch_rtp_ts,
769 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200770 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200771{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200772 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200773 OSMO_ASSERT(trunk);
774 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200775 return CMD_SUCCESS;
776}
777
Philipp Maier9fc8a022019-02-20 12:26:52 +0100778DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
779 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
780 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
781{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200782 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200783 OSMO_ASSERT(trunk);
784 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100785 return CMD_SUCCESS;
786}
787
788DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
789 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
790 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
791{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200792 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200793 OSMO_ASSERT(trunk);
794 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100795 return CMD_SUCCESS;
796}
797
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200798DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200799 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200800{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200801 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200802 OSMO_ASSERT(trunk);
803 trunk->force_constant_ssrc = 0;
804 trunk->force_aligned_timing = 0;
805 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200806 return CMD_SUCCESS;
807}
808
809DEFUN(cfg_mgcp_rtp_keepalive,
810 cfg_mgcp_rtp_keepalive_cmd,
811 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200812 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200813{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200814 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200815 OSMO_ASSERT(trunk);
816 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200817 return CMD_SUCCESS;
818}
819
820DEFUN(cfg_mgcp_rtp_keepalive_once,
821 cfg_mgcp_rtp_keepalive_once_cmd,
822 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200823 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200824{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200825 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200826 OSMO_ASSERT(trunk);
827 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200828 return CMD_SUCCESS;
829}
830
831DEFUN(cfg_mgcp_no_rtp_keepalive,
832 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200833 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200834{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200835 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200836 OSMO_ASSERT(trunk);
837 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200838 return CMD_SUCCESS;
839}
840
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200841#define CALL_AGENT_STR "Callagent information\n"
842DEFUN(cfg_mgcp_agent_addr,
843 cfg_mgcp_agent_addr_cmd,
844 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200845 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200846{
847 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
848 return CMD_SUCCESS;
849}
850
851ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200852 "call agent ip A.B.C.D",
853 CALL_AGENT_STR CALL_AGENT_STR IP_STR
854 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200855
Philipp Maier21be42a2020-05-29 21:39:48 +0200856DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200857 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200858{
Philipp Maier14b27a82020-06-02 20:15:30 +0200859 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200860 int index = atoi(argv[0]);
861
Philipp Maierd19de2e2020-06-03 13:55:33 +0200862 /* Due to historical reasons, the trunk id number 0 is reserved for the
863 * virtual trunk. This trunk is configured with separate VTY
864 * parameters, so we restrict the access to trunks with id numbers
865 * greater than 0. */
866
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200867 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100868 if (!trunk) {
869 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200870 if (!trunk) {
871 vty_out(vty, "%%Unable to allocate trunk %u.%s",
872 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100873 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200874 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200875 }
876
877 vty->node = TRUNK_NODE;
878 vty->index = trunk;
879 return CMD_SUCCESS;
880}
881
882static int config_write_trunk(struct vty *vty)
883{
Philipp Maier14b27a82020-06-02 20:15:30 +0200884 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200885
886 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200887
888 /* Due to historical reasons, the virtual trunk is configured
889 using separate VTY parameters, so we omit writing the trunk
890 config of trunk 0 here. The configuration for the virtual
891 trunk is written by config_write_mgcp(). */
892
893 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
894 continue;
895
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200896 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200897 vty_out(vty, " %ssdp audio-payload send-ptime%s",
898 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
899 vty_out(vty, " %ssdp audio-payload send-name%s",
900 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
901
902 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
903 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
904 else if (trunk->keepalive_interval)
905 vty_out(vty, " rtp keep-alive %d%s",
906 trunk->keepalive_interval, VTY_NEWLINE);
907 else
908 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200909 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200910 vty_out(vty, " force-realloc %d%s",
911 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200912 vty_out(vty, " rtp-accept-all %d%s",
913 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200914 if (trunk->omit_rtcp)
915 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
916 else
917 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100918 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200919 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200920 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200921 trunk->force_constant_ssrc ? "" : "no ",
922 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200923 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200924 trunk->force_aligned_timing ? "" : "no ",
925 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100926 vty_out(vty, " %srtp-patch rfc5993hr%s",
927 trunk->rfc5993_hr_convert ? "" : "no ",
928 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200929 } else
930 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
931 if (trunk->audio_fmtp_extra)
932 vty_out(vty, " sdp audio fmtp-extra %s%s",
933 trunk->audio_fmtp_extra, VTY_NEWLINE);
934 vty_out(vty, " %sallow-transcoding%s",
935 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
936 }
937
938 return CMD_SUCCESS;
939}
940
941DEFUN(cfg_trunk_sdp_fmtp_extra,
942 cfg_trunk_sdp_fmtp_extra_cmd,
943 "sdp audio fmtp-extra .NAME",
944 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
945 "Extra Information\n")
946{
Philipp Maier14b27a82020-06-02 20:15:30 +0200947 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200948 char *txt = argv_concat(argv, argc, 0);
949 if (!txt)
950 return CMD_WARNING;
951
952 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
953 talloc_free(txt);
954 return CMD_SUCCESS;
955}
956
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200957DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200958 cfg_trunk_payload_number_cmd,
959 "sdp audio-payload number <0-255>",
960 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
961{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200962 return CMD_SUCCESS;
963}
964
965ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200966 "sdp audio payload number <0-255>",
967 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200968
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200969DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200970 cfg_trunk_payload_name_cmd,
971 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200972 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200973{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200974 return CMD_SUCCESS;
975}
976
977ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200978 "sdp audio payload name NAME",
979 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200980
Philipp Maier21be42a2020-05-29 21:39:48 +0200981DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200982 cfg_trunk_loop_cmd,
983 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200984 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200985{
Philipp Maier14b27a82020-06-02 20:15:30 +0200986 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200987
988 if (g_cfg->osmux) {
989 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
990 return CMD_WARNING;
991 }
992 trunk->audio_loop = atoi(argv[0]);
993 return CMD_SUCCESS;
994}
995
996DEFUN(cfg_trunk_sdp_payload_send_ptime,
997 cfg_trunk_sdp_payload_send_ptime_cmd,
998 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200999 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000{
Philipp Maier14b27a82020-06-02 20:15:30 +02001001 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001002 trunk->audio_send_ptime = 1;
1003 return CMD_SUCCESS;
1004}
1005
1006DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1007 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1008 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001009 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
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->audio_send_ptime = 0;
1013 return CMD_SUCCESS;
1014}
1015
1016DEFUN(cfg_trunk_sdp_payload_send_name,
1017 cfg_trunk_sdp_payload_send_name_cmd,
1018 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001019 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001020{
Philipp Maier14b27a82020-06-02 20:15:30 +02001021 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001022 trunk->audio_send_name = 1;
1023 return CMD_SUCCESS;
1024}
1025
1026DEFUN(cfg_trunk_no_sdp_payload_send_name,
1027 cfg_trunk_no_sdp_payload_send_name_cmd,
1028 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001029 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001030{
Philipp Maier14b27a82020-06-02 20:15:30 +02001031 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001032 trunk->audio_send_name = 0;
1033 return CMD_SUCCESS;
1034}
1035
Philipp Maier87bd9be2017-08-22 16:35:41 +02001036DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001037{
Philipp Maier14b27a82020-06-02 20:15:30 +02001038 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001039 trunk->omit_rtcp = 1;
1040 return CMD_SUCCESS;
1041}
1042
1043DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001044 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
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->omit_rtcp = 0;
1048 return CMD_SUCCESS;
1049}
1050
1051DEFUN(cfg_trunk_patch_rtp_ssrc,
1052 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001053 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\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_constant_ssrc = 1;
1057 return CMD_SUCCESS;
1058}
1059
1060DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1061 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001062 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001063{
Philipp Maier14b27a82020-06-02 20:15:30 +02001064 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001065 trunk->force_constant_ssrc = 0;
1066 return CMD_SUCCESS;
1067}
1068
1069DEFUN(cfg_trunk_patch_rtp_ts,
1070 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001071 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001072{
Philipp Maier14b27a82020-06-02 20:15:30 +02001073 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001074 trunk->force_aligned_timing = 1;
1075 return CMD_SUCCESS;
1076}
1077
1078DEFUN(cfg_trunk_no_patch_rtp_ts,
1079 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001080 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001081{
Philipp Maier14b27a82020-06-02 20:15:30 +02001082 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001083 trunk->force_aligned_timing = 0;
1084 return CMD_SUCCESS;
1085}
1086
Philipp Maier9fc8a022019-02-20 12:26:52 +01001087DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1088 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1089 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1090{
Philipp Maier14b27a82020-06-02 20:15:30 +02001091 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001092 trunk->rfc5993_hr_convert = true;
1093 return CMD_SUCCESS;
1094}
1095
1096DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1097 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1098 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1099{
Philipp Maier14b27a82020-06-02 20:15:30 +02001100 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001101 trunk->rfc5993_hr_convert = false;
1102 return CMD_SUCCESS;
1103}
1104
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001105DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001106 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001107{
Philipp Maier14b27a82020-06-02 20:15:30 +02001108 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001109 trunk->force_constant_ssrc = 0;
1110 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001111 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001112 return CMD_SUCCESS;
1113}
1114
1115DEFUN(cfg_trunk_rtp_keepalive,
1116 cfg_trunk_rtp_keepalive_cmd,
1117 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001118 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001119{
Philipp Maier14b27a82020-06-02 20:15:30 +02001120 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001121 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1122 return CMD_SUCCESS;
1123}
1124
1125DEFUN(cfg_trunk_rtp_keepalive_once,
1126 cfg_trunk_rtp_keepalive_once_cmd,
1127 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001128 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\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 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1132 return CMD_SUCCESS;
1133}
1134
1135DEFUN(cfg_trunk_no_rtp_keepalive,
1136 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001137 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001138{
Philipp Maier14b27a82020-06-02 20:15:30 +02001139 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001140 mgcp_trunk_set_keepalive(trunk, 0);
1141 return CMD_SUCCESS;
1142}
1143
1144DEFUN(cfg_trunk_allow_transcoding,
1145 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001146 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001147{
Philipp Maier14b27a82020-06-02 20:15:30 +02001148 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001149 trunk->no_audio_transcoding = 0;
1150 return CMD_SUCCESS;
1151}
1152
1153DEFUN(cfg_trunk_no_allow_transcoding,
1154 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001155 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001156{
Philipp Maier14b27a82020-06-02 20:15:30 +02001157 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001158 trunk->no_audio_transcoding = 1;
1159 return CMD_SUCCESS;
1160}
1161
Philipp Maier87bd9be2017-08-22 16:35:41 +02001162DEFUN(loop_conn,
1163 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001164 "loop-endpoint <0-64> NAME (0|1)",
1165 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001166 "The name in hex of the endpoint\n" "Disable the loop\n"
1167 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001168{
Philipp Maier14b27a82020-06-02 20:15:30 +02001169 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001170 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001171 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001172
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001173 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001174 if (!trunk) {
1175 vty_out(vty, "%%Trunk %d not found in the config.%s",
1176 atoi(argv[0]), VTY_NEWLINE);
1177 return CMD_WARNING;
1178 }
1179
1180 if (!trunk->endpoints) {
1181 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1182 trunk->trunk_nr, VTY_NEWLINE);
1183 return CMD_WARNING;
1184 }
1185
1186 int endp_no = strtoul(argv[1], NULL, 16);
1187 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1188 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001189 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001190 return CMD_WARNING;
1191 }
1192
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001193 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001194 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001195 llist_for_each_entry(conn, &endp->conns, entry) {
1196 if (conn->type == MGCP_CONN_TYPE_RTP)
1197 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1198 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1199 else {
1200 /* FIXME: Introduce support for other connection (E1)
1201 * types when implementation is available */
1202 vty_out(vty, "%%Can't enable SSRC patching,"
1203 "connection %s is not an RTP connection.%s",
1204 mgcp_conn_dump(conn), VTY_NEWLINE);
1205 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001206
Philipp Maier87bd9be2017-08-22 16:35:41 +02001207 if (loop)
1208 conn->mode = MGCP_CONN_LOOPBACK;
1209 else
1210 conn->mode = conn->mode_orig;
1211 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001212
1213 return CMD_SUCCESS;
1214}
1215
Philipp Maier87bd9be2017-08-22 16:35:41 +02001216DEFUN(tap_rtp,
1217 tap_rtp_cmd,
1218 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001219 "Forward data on endpoint to a different system\n" "Trunk number\n"
1220 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001221 "The connection id in hex\n"
1222 "Forward incoming data\n"
1223 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001224 "destination IP of the data\n" "destination port\n")
1225{
1226 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001227 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001228 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001229 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001230 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001231
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001232 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001233 if (!trunk) {
1234 vty_out(vty, "%%Trunk %d not found in the config.%s",
1235 atoi(argv[0]), VTY_NEWLINE);
1236 return CMD_WARNING;
1237 }
1238
1239 if (!trunk->endpoints) {
1240 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1241 trunk->trunk_nr, VTY_NEWLINE);
1242 return CMD_WARNING;
1243 }
1244
1245 int endp_no = strtoul(argv[1], NULL, 16);
1246 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1247 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001248 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001249 return CMD_WARNING;
1250 }
1251
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001252 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001253
Philipp Maier01d24a32017-11-21 17:26:09 +01001254 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001255 conn = mgcp_conn_get_rtp(endp, conn_id);
1256 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001257 vty_out(vty, "Conn ID %s is invalid.%s",
1258 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001259 return CMD_WARNING;
1260 }
1261
1262 if (strcmp(argv[3], "in") == 0)
1263 tap = &conn->tap_in;
1264 else if (strcmp(argv[3], "out") == 0)
1265 tap = &conn->tap_out;
1266 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001267 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1268 return CMD_WARNING;
1269 }
1270
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001271 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001272 inet_aton(argv[4], &tap->forward.sin_addr);
1273 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001274 tap->enabled = 1;
1275 return CMD_SUCCESS;
1276}
1277
1278DEFUN(free_endp, free_endp_cmd,
1279 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001280 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001281{
Philipp Maier14b27a82020-06-02 20:15:30 +02001282 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001283 struct mgcp_endpoint *endp;
1284
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001285 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001286 if (!trunk) {
1287 vty_out(vty, "%%Trunk %d not found in the config.%s",
1288 atoi(argv[0]), VTY_NEWLINE);
1289 return CMD_WARNING;
1290 }
1291
1292 if (!trunk->endpoints) {
1293 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1294 trunk->trunk_nr, VTY_NEWLINE);
1295 return CMD_WARNING;
1296 }
1297
1298 int endp_no = strtoul(argv[1], NULL, 16);
1299 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1300 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001301 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001302 return CMD_WARNING;
1303 }
1304
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001305 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001306 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001307 return CMD_SUCCESS;
1308}
1309
1310DEFUN(reset_endp, reset_endp_cmd,
1311 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001312 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001313{
Philipp Maier14b27a82020-06-02 20:15:30 +02001314 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001315 struct mgcp_endpoint *endp;
1316 int endp_no, rc;
1317
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001318 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001319 if (!trunk) {
1320 vty_out(vty, "%%Trunk %d not found in the config.%s",
1321 atoi(argv[0]), VTY_NEWLINE);
1322 return CMD_WARNING;
1323 }
1324
1325 if (!trunk->endpoints) {
1326 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1327 trunk->trunk_nr, VTY_NEWLINE);
1328 return CMD_WARNING;
1329 }
1330
1331 endp_no = strtoul(argv[1], NULL, 16);
1332 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1333 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001334 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001335 return CMD_WARNING;
1336 }
1337
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001338 endp = trunk->endpoints[endp_no];
1339 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001340 if (rc < 0) {
1341 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1342 return CMD_WARNING;
1343 }
1344 return CMD_SUCCESS;
1345}
1346
1347DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001348 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001349{
1350 int rc;
1351
1352 rc = mgcp_send_reset_all(g_cfg);
1353 if (rc < 0) {
1354 vty_out(vty, "Error %d during endpoint reset.%s",
1355 rc, VTY_NEWLINE);
1356 return CMD_WARNING;
1357 }
1358 return CMD_SUCCESS;
1359}
1360
1361#define OSMUX_STR "RTP multiplexing\n"
1362DEFUN(cfg_mgcp_osmux,
1363 cfg_mgcp_osmux_cmd,
1364 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001365 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001366{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001367 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001368 OSMO_ASSERT(trunk);
1369
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001370 if (strcmp(argv[0], "off") == 0) {
1371 g_cfg->osmux = OSMUX_USAGE_OFF;
1372 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001373 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001374 g_cfg->osmux = OSMUX_USAGE_ON;
1375 else if (strcmp(argv[0], "only") == 0)
1376 g_cfg->osmux = OSMUX_USAGE_ONLY;
1377
Philipp Maierd19de2e2020-06-03 13:55:33 +02001378 if (trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001379 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001380 return CMD_WARNING;
1381 }
1382
1383 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001384
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001385}
1386
1387DEFUN(cfg_mgcp_osmux_ip,
1388 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001389 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001390{
1391 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1392 return CMD_SUCCESS;
1393}
1394
1395DEFUN(cfg_mgcp_osmux_batch_factor,
1396 cfg_mgcp_osmux_batch_factor_cmd,
1397 "osmux batch-factor <1-8>",
1398 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1399{
1400 g_cfg->osmux_batch = atoi(argv[0]);
1401 return CMD_SUCCESS;
1402}
1403
1404DEFUN(cfg_mgcp_osmux_batch_size,
1405 cfg_mgcp_osmux_batch_size_cmd,
1406 "osmux batch-size <1-65535>",
1407 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1408{
1409 g_cfg->osmux_batch_size = atoi(argv[0]);
1410 return CMD_SUCCESS;
1411}
1412
1413DEFUN(cfg_mgcp_osmux_port,
1414 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001415 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001416{
1417 g_cfg->osmux_port = atoi(argv[0]);
1418 return CMD_SUCCESS;
1419}
1420
1421DEFUN(cfg_mgcp_osmux_dummy,
1422 cfg_mgcp_osmux_dummy_cmd,
1423 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001424 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1425 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001426{
1427 if (strcmp(argv[0], "on") == 0)
1428 g_cfg->osmux_dummy = 1;
1429 else if (strcmp(argv[0], "off") == 0)
1430 g_cfg->osmux_dummy = 0;
1431
1432 return CMD_SUCCESS;
1433}
1434
Philipp Maier12943ea2018-01-17 15:40:25 +01001435DEFUN(cfg_mgcp_domain,
1436 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001437 "domain NAME",
1438 "Set the domain part expected in MGCP messages' endpoint names\n"
1439 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001440{
1441 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1442 return CMD_SUCCESS;
1443}
1444
Oliver Smithe36b7752019-01-22 16:31:36 +01001445DEFUN(cfg_mgcp_conn_timeout,
1446 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001447 "conn-timeout <0-65534>",
1448 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1449 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001450 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1451 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001452 "Timeout value (sec.)\n")
1453{
1454 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1455 return CMD_SUCCESS;
1456}
1457
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001458int mgcp_vty_init(void)
1459{
1460 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001461 install_element_ve(&show_mgcp_endpoint_cmd);
1462 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001463 install_element(ENABLE_NODE, &loop_conn_cmd);
1464 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001465 install_element(ENABLE_NODE, &free_endp_cmd);
1466 install_element(ENABLE_NODE, &reset_endp_cmd);
1467 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1468
1469 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1470 install_node(&mgcp_node, config_write_mgcp);
1471
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001472 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001473 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1474 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1475 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001476 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001477 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001478 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001479 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001480 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001481 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001482 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1483 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001484 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1485 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1486 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1487 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1488 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1489 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1490 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1491 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1492 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001493 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1494 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1495 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1496 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1497 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1498 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001499 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001500 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1501 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1502 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1503 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1504 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1505 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1506 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1507 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001508 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1509 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001510 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1511 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1512 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1513 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1514 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1515 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1516 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1517 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1518 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1519 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1520 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1521 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1522 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001523 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001524 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001525
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001526 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1527 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001528 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1529 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1530 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1531 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1532 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1533 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1534 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1535 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1536 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1537 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1538 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1539 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1540 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001541 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1542 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001543 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1544 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1545 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1546 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1547 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1548 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1549 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1550 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1551 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1552
1553 return 0;
1554}
1555
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001556int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1557 enum mgcp_role role)
1558{
1559 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001560 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001561
1562 cfg->osmux_port = OSMUX_PORT;
1563 cfg->osmux_batch = 4;
1564 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1565
1566 g_cfg = cfg;
1567 rc = vty_read_config_file(config_file, NULL);
1568 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001569 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1570 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001571 return rc;
1572 }
1573
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001574 if (!g_cfg->source_addr) {
1575 fprintf(stderr, "You need to specify a bind address.\n");
1576 return -1;
1577 }
1578
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001579 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001580 if (mgcp_trunk_alloc_endpts(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001581 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001582 "Failed to initialize trunk %d (%d endpoints)\n",
1583 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001584 return -1;
1585 }
1586 }
1587 cfg->role = role;
1588
1589 return 0;
1590}