blob: d2d4b23a5fb49e7a7e7c25f199640ab98e465e2a [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 Maier993ea6b2020-08-04 18:26:50 +020028#include <osmocom/mgcp/osmux.h>
29#include <osmocom/mgcp/mgcp_protocol.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020030#include <osmocom/mgcp/vty.h>
31#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010032#include <osmocom/mgcp/mgcp_endp.h>
Philipp Maierc66ab2c2020-06-02 20:55:34 +020033#include <osmocom/mgcp/mgcp_trunk.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020034
35#include <string.h>
Philipp Maierbca0ef62018-07-09 17:20:51 +020036#include <inttypes.h>
Stefan Sperling12086582018-06-26 15:26:28 +020037#include <limits.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020038
39#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
40#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
41#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
Philipp Maier9fc8a022019-02-20 12:26:52 +010042#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"
43
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020044
45static struct mgcp_config *g_cfg = NULL;
46
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020047struct cmd_node mgcp_node = {
48 MGCP_NODE,
49 "%s(config-mgcp)# ",
50 1,
51};
52
53struct cmd_node trunk_node = {
54 TRUNK_NODE,
55 "%s(config-mgcp-trunk)# ",
56 1,
57};
58
59static int config_write_mgcp(struct vty *vty)
60{
Philipp Maier6fbbeec2020-07-01 23:00:54 +020061 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +020062 OSMO_ASSERT(trunk);
Harald Weltec39b1bf2020-03-08 11:29:39 +010063
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020064 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020065 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020066 if (g_cfg->local_ip)
67 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020068 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
69 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
70 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020071 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
72 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020073 if (g_cfg->net_ports.bind_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +020074 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020075 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010076 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020077 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010078 else
Philipp Maierf53796c2020-06-02 20:38:28 +020079 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
80 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010081 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020082 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010083 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020084 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010085 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020086 else
Philipp Maierf53796c2020-06-02 20:38:28 +020087 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020088
Harald Weltec39b1bf2020-03-08 11:29:39 +010089 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +020090 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020091 else
Philipp Maierf53796c2020-06-02 20:38:28 +020092 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010093 if (trunk->force_constant_ssrc
94 || trunk->force_aligned_timing
95 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +020096 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010097 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +020098 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020099 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100100 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200101 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200102 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100103 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100104 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200105 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200106 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100107 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200108 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100109 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200110 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100111 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200112 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100113 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200114 vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
115 vty_out(vty, " number endpoints %u%s",
Philipp Maier889fe7f2020-07-06 17:44:12 +0200116 trunk->v.vty_number_endpoints, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200117 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100118 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200119 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200120 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200121 VTY_NEWLINE);
122 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200123 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200124 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200125
126 switch (g_cfg->osmux) {
127 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200128 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200129 break;
130 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200131 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200132 break;
133 case OSMUX_USAGE_OFF:
134 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200135 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200136 break;
137 }
138 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200139 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200140 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200141 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200142 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200143 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200144 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200145 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200146 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200147 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200148 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
149 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100150
151 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200152 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100153
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200154 return CMD_SUCCESS;
155}
156
Philipp Maiercede2a42018-07-03 14:14:21 +0200157static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200158{
Philipp Maiercede2a42018-07-03 14:14:21 +0200159 struct mgcp_rtp_state *state = &conn->state;
160 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200161 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100162 struct rate_ctr *tx_packets, *tx_bytes;
163 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200164 struct rate_ctr *dropped_packets;
165
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100166 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
167 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
168 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
169 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200170 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200171
172 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100173 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
174 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200175 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
176 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200177 " Payload Type: %d Rate: %u Channels: %d %s"
178 " Frame Duration: %u Frame Denominator: %u%s"
179 " FPP: %d Packet Duration: %u%s"
180 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
181 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100182 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
183 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200184 state->in_stream.err_ts_ctr->current,
185 state->out_stream.err_ts_ctr->current,
186 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200187 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200188 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200189 codec->frame_duration_num, codec->frame_duration_den,
190 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
191 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
192 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
193 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200194}
195
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200196static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200197 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200198{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200199 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200200
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200201 vty_out(vty, "%s trunk %d endpoint %s:%s",
202 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Philipp Maier8d6a1932020-06-18 12:19:31 +0200203 vty_out(vty, " Availability: %s%s",
204 mgcp_endp_avail(endp) ? "available" : "not in service", VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200205
206 if (llist_empty(&endp->conns)) {
207 vty_out(vty, " No active connections%s", VTY_NEWLINE);
208 return;
209 }
210
211 llist_for_each_entry(conn, &endp->conns, entry) {
212 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
213
214 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100215 if (endp->cfg->conn_timeout) {
216 struct timeval remaining;
217 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
218 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
219 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
220 }
221
Stefan Sperling12086582018-06-26 15:26:28 +0200222 /* FIXME: Also add verbosity for other
223 * connection types (E1) as soon as
224 * the implementation is available */
225 if (conn->type == MGCP_CONN_TYPE_RTP) {
226 dump_rtp_end(vty, &conn->u.rtp);
227 }
228 }
229 }
230}
231
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200232static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
233{
234 vty_out(vty, "%s", VTY_NEWLINE);
235 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
236
237 if (ratectr->mgcp_general_ctr_group) {
238 vty_out(vty, " %s:%s",
239 ratectr->mgcp_general_ctr_group->desc->
240 group_description, VTY_NEWLINE);
241 vty_out_rate_ctr_group_fmt(vty,
242 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
243 ratectr->mgcp_general_ctr_group);
244 }
245}
246
Philipp Maier889fe7f2020-07-06 17:44:12 +0200247static void dump_ratectr_trunk(struct vty *vty, struct mgcp_trunk *trunk)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200248{
Philipp Maier889fe7f2020-07-06 17:44:12 +0200249 struct mgcp_ratectr_trunk *ratectr = &trunk->ratectr;
250
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200251 vty_out(vty, "%s", VTY_NEWLINE);
252 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
253
254 if (ratectr->mgcp_crcx_ctr_group) {
255 vty_out(vty, " %s:%s",
256 ratectr->mgcp_crcx_ctr_group->desc->group_description,
257 VTY_NEWLINE);
258 vty_out_rate_ctr_group_fmt(vty,
259 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
260 ratectr->mgcp_crcx_ctr_group);
261 }
262 if (ratectr->mgcp_dlcx_ctr_group) {
263 vty_out(vty, " %s:%s",
264 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
265 VTY_NEWLINE);
266 vty_out_rate_ctr_group_fmt(vty,
267 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
268 ratectr->mgcp_dlcx_ctr_group);
269 }
270 if (ratectr->mgcp_mdcx_ctr_group) {
271 vty_out(vty, " %s:%s",
272 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
273 VTY_NEWLINE);
274 vty_out_rate_ctr_group_fmt(vty,
275 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
276 ratectr->mgcp_mdcx_ctr_group);
277 }
278 if (ratectr->all_rtp_conn_stats) {
279 vty_out(vty, " %s:%s",
280 ratectr->all_rtp_conn_stats->desc->group_description,
281 VTY_NEWLINE);
282 vty_out_rate_ctr_group_fmt(vty,
283 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
284 ratectr->all_rtp_conn_stats);
285 }
Philipp Maier889fe7f2020-07-06 17:44:12 +0200286
287 if (ratectr->e1_stats && trunk->trunk_type == MGCP_TRUNK_E1) {
288 vty_out(vty, " %s:%s",
289 ratectr->e1_stats->desc->group_description,
290 VTY_NEWLINE);
291 vty_out_rate_ctr_group_fmt(vty,
292 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
293 ratectr->e1_stats);
294 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200295}
296
297
298static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200299{
300 int i;
301
302 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200303 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
Philipp Maier869b21c2020-07-03 16:04:16 +0200304 trunk->trunk_nr, trunk->number_endpoints, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200305
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200306 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200307 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
308 return;
309 }
310
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200311 for (i = 0; i < trunk->number_endpoints; ++i) {
312 struct mgcp_endpoint *endp = trunk->endpoints[i];
313 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
314 show_stats);
315 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200316 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200317 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200318
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200319 if (show_stats)
Philipp Maier889fe7f2020-07-06 17:44:12 +0200320 dump_ratectr_trunk(vty, trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200321}
322
Stefan Sperling12086582018-06-26 15:26:28 +0200323#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
324
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200325DEFUN(show_mcgp, show_mgcp_cmd,
326 "show mgcp [stats]",
327 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200328 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200329 "Include Statistics\n")
330{
Philipp Maier14b27a82020-06-02 20:15:30 +0200331 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200332 int show_stats = argc >= 1;
333
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200334 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200335 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200336
337 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200338 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200339 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200340
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200341 if (show_stats)
342 dump_ratectr_global(vty, &g_cfg->ratectr);
343
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200344 return CMD_SUCCESS;
345}
346
Stefan Sperling12086582018-06-26 15:26:28 +0200347static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200348dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200349{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200350 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200351
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200352 if (trunk) {
353 /* If a trunk is given, search on that specific trunk only */
354 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
355 if (!endp) {
356 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
357 return;
358 }
359 } else {
360 /* If no trunk is given, search on all possible trunks */
361 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
362 if (!endp) {
363 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
364 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200365 }
366 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200367
368 trunk = endp->trunk;
369 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200370}
371
372DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
373 "show mgcp endpoint NAME",
374 SHOW_STR
375 SHOW_MGCP_STR
376 "Display information about an endpoint\n" "The name of the endpoint\n")
377{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200378 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200379 return CMD_SUCCESS;
380}
381
382DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
383 "show mgcp trunk <0-64> endpoint NAME",
384 SHOW_STR
385 SHOW_MGCP_STR
386 "Display information about a trunk\n" "Trunk number\n"
387 "Display information about an endpoint\n" "The name of the endpoint\n")
388{
Philipp Maier14b27a82020-06-02 20:15:30 +0200389 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200390 int trunkidx = atoi(argv[0]);
391
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200392 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200393 if (!trunk) {
394 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
395 return CMD_WARNING;
396 }
397
398 dump_mgcp_endpoint(vty, trunk, argv[1]);
399 return CMD_SUCCESS;
400}
401
Philipp Maier87bd9be2017-08-22 16:35:41 +0200402DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200403{
404 vty->node = MGCP_NODE;
405 return CMD_SUCCESS;
406}
407
408DEFUN(cfg_mgcp_local_ip,
409 cfg_mgcp_local_ip_cmd,
410 "local ip A.B.C.D",
411 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200412 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200413{
414 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
415 return CMD_SUCCESS;
416}
417
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200418#define BIND_STR "Listen/Bind related socket option\n"
419DEFUN(cfg_mgcp_bind_ip,
420 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200421 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200422{
423 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
424 return CMD_SUCCESS;
425}
426
427DEFUN(cfg_mgcp_bind_port,
428 cfg_mgcp_bind_port_cmd,
429 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200430 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200431{
432 unsigned int port = atoi(argv[0]);
433 g_cfg->source_port = port;
434 return CMD_SUCCESS;
435}
436
437DEFUN(cfg_mgcp_bind_early,
438 cfg_mgcp_bind_early_cmd,
439 "bind early (0|1)",
440 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200441 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200442{
443 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
444 return CMD_WARNING;
445}
446
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200447#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200448#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200449#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200450#define RANGE_START_STR "Start of the range of ports\n"
451#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200452
Philipp Maierf1889d82017-11-08 14:59:39 +0100453DEFUN(cfg_mgcp_rtp_port_range,
454 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200455 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200456 RTP_STR "Range of ports to use for the NET side\n"
457 RANGE_START_STR RANGE_END_STR)
458{
Philipp Maiera19547b2018-05-22 13:44:34 +0200459 int start;
460 int end;
461
462 start = atoi(argv[0]);
463 end = atoi(argv[1]);
464
465 if (end < start) {
466 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
467 end, start, VTY_NEWLINE);
468 return CMD_WARNING;
469 }
470
471 if (start & 1) {
472 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
473 start, start & 0xFFFE, VTY_NEWLINE);
474 start &= 0xFFFE;
475 }
476
477 if ((end & 1) == 0) {
478 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
479 end, end | 1, VTY_NEWLINE);
480 end |= 1;
481 }
482
483 g_cfg->net_ports.range_start = start;
484 g_cfg->net_ports.range_end = end;
485 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
486
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200487 return CMD_SUCCESS;
488}
Philipp Maierf1889d82017-11-08 14:59:39 +0100489ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
490 cfg_mgcp_rtp_net_range_cmd,
491 "rtp net-range <0-65534> <0-65534>",
492 RTP_STR "Range of ports to use for the NET side\n"
493 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200494
Philipp Maierf1889d82017-11-08 14:59:39 +0100495DEFUN(cfg_mgcp_rtp_bind_ip,
496 cfg_mgcp_rtp_bind_ip_cmd,
497 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200498 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
499{
500 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
501 return CMD_SUCCESS;
502}
Philipp Maierf1889d82017-11-08 14:59:39 +0100503ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
504 cfg_mgcp_rtp_net_bind_ip_cmd,
505 "rtp net-bind-ip A.B.C.D",
506 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200507
Philipp Maierf1889d82017-11-08 14:59:39 +0100508DEFUN(cfg_mgcp_rtp_no_bind_ip,
509 cfg_mgcp_rtp_no_bind_ip_cmd,
510 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200511 NO_STR RTP_STR "Bind endpoints facing the Network\n"
512 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200513{
514 talloc_free(g_cfg->net_ports.bind_addr);
515 g_cfg->net_ports.bind_addr = NULL;
516 return CMD_SUCCESS;
517}
Philipp Maierf1889d82017-11-08 14:59:39 +0100518ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
519 cfg_mgcp_rtp_no_net_bind_ip_cmd,
520 "no rtp net-bind-ip",
521 NO_STR RTP_STR "Bind endpoints facing the Network\n"
522 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200523
Philipp Maier1cb1e382017-11-02 17:16:04 +0100524DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
525 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
526 "rtp ip-probing",
527 RTP_STR "automatic rtp bind ip selection\n")
528{
529 g_cfg->net_ports.bind_addr_probe = true;
530 return CMD_SUCCESS;
531}
532
533DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
534 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
535 "no rtp ip-probing",
536 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
537{
538 g_cfg->net_ports.bind_addr_probe = false;
539 return CMD_SUCCESS;
540}
541
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200542DEFUN(cfg_mgcp_rtp_ip_dscp,
543 cfg_mgcp_rtp_ip_dscp_cmd,
544 "rtp ip-dscp <0-255>",
545 RTP_STR
546 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
547{
548 int dscp = atoi(argv[0]);
549 g_cfg->endp_dscp = dscp;
550 return CMD_SUCCESS;
551}
552
553ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200554 "rtp ip-tos <0-255>",
555 RTP_STR
556 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
557#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200558DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200559 cfg_mgcp_rtp_force_ptime_cmd,
560 "rtp force-ptime (10|20|40)",
561 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200562 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200563{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200564 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200565 return CMD_SUCCESS;
566}
567
568DEFUN(cfg_mgcp_no_rtp_force_ptime,
569 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200570 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200571{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200572 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200573 return CMD_SUCCESS;
574}
575
576DEFUN(cfg_mgcp_sdp_fmtp_extra,
577 cfg_mgcp_sdp_fmtp_extra_cmd,
578 "sdp audio fmtp-extra .NAME",
579 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
580 "Extra Information\n")
581{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200582 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200583 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200584 char *txt = argv_concat(argv, argc, 0);
585 if (!txt)
586 return CMD_WARNING;
587
Philipp Maierd19de2e2020-06-03 13:55:33 +0200588 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200589 talloc_free(txt);
590 return CMD_SUCCESS;
591}
592
593DEFUN(cfg_mgcp_allow_transcoding,
594 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200595 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200596{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200597 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200598 OSMO_ASSERT(trunk);
599 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200600 return CMD_SUCCESS;
601}
602
603DEFUN(cfg_mgcp_no_allow_transcoding,
604 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200605 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200606{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200607 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200608 OSMO_ASSERT(trunk);
609 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200610 return CMD_SUCCESS;
611}
612
613#define SDP_STR "SDP File related options\n"
614#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200615DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200616 cfg_mgcp_sdp_payload_number_cmd,
617 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200618 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200619{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200620 return CMD_SUCCESS;
621}
622
Philipp Maier87bd9be2017-08-22 16:35:41 +0200623ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
624 cfg_mgcp_sdp_payload_number_cmd_old,
625 "sdp audio payload number <0-255>",
626 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200627
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200628DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200629 cfg_mgcp_sdp_payload_name_cmd,
630 "sdp audio-payload name NAME",
631 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
632{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200633 return CMD_SUCCESS;
634}
635
636ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200637 "sdp audio payload name NAME",
638 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200639
Philipp Maier21be42a2020-05-29 21:39:48 +0200640DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200641 cfg_mgcp_sdp_payload_send_ptime_cmd,
642 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200643 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200644{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200645 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200646 OSMO_ASSERT(trunk);
647 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{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200656 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200657 OSMO_ASSERT(trunk);
658 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200659 return CMD_SUCCESS;
660}
661
662DEFUN(cfg_mgcp_sdp_payload_send_name,
663 cfg_mgcp_sdp_payload_send_name_cmd,
664 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200665 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200666{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200667 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200668 OSMO_ASSERT(trunk);
669 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200670 return CMD_SUCCESS;
671}
672
673DEFUN(cfg_mgcp_no_sdp_payload_send_name,
674 cfg_mgcp_no_sdp_payload_send_name_cmd,
675 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200676 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200677{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200678 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200679 OSMO_ASSERT(trunk);
680 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200681 return CMD_SUCCESS;
682}
683
684DEFUN(cfg_mgcp_loop,
685 cfg_mgcp_loop_cmd,
686 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200687 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200688{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200689 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200690 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200691 if (g_cfg->osmux) {
692 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
693 return CMD_WARNING;
694 }
Philipp Maierd19de2e2020-06-03 13:55:33 +0200695 trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200696 return CMD_SUCCESS;
697}
698
699DEFUN(cfg_mgcp_force_realloc,
700 cfg_mgcp_force_realloc_cmd,
701 "force-realloc (0|1)",
702 "Force endpoint reallocation when the endpoint is still seized\n"
703 "Don't force reallocation\n" "force reallocation\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->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200708 return CMD_SUCCESS;
709}
710
Philipp Maier87bd9be2017-08-22 16:35:41 +0200711DEFUN(cfg_mgcp_rtp_accept_all,
712 cfg_mgcp_rtp_accept_all_cmd,
713 "rtp-accept-all (0|1)",
714 "Accept all RTP packets, even when the originating IP/Port does not match\n"
715 "enable filter\n" "disable filter\n")
716{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200717 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200718 OSMO_ASSERT(trunk);
719 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200720 return CMD_SUCCESS;
721}
722
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200723DEFUN(cfg_mgcp_number_endp,
724 cfg_mgcp_number_endp_cmd,
Philipp Maier869b21c2020-07-03 16:04:16 +0200725 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200726 "Number options\n" "Endpoints available\n" "Number endpoints\n")
727{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200728 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200729 OSMO_ASSERT(trunk);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200730 trunk->v.vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200731 return CMD_SUCCESS;
732}
733
Philipp Maier87bd9be2017-08-22 16:35:41 +0200734DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200735{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200736 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200737 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200738 return CMD_SUCCESS;
739}
740
741DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200742 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200743{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200744 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200745 OSMO_ASSERT(trunk);
746 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200747 return CMD_SUCCESS;
748}
749
750DEFUN(cfg_mgcp_patch_rtp_ssrc,
751 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200752 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200753{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200754 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200755 OSMO_ASSERT(trunk);
756 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200757 return CMD_SUCCESS;
758}
759
760DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
761 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200762 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200763{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200764 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200765 OSMO_ASSERT(trunk);
766 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200767 return CMD_SUCCESS;
768}
769
770DEFUN(cfg_mgcp_patch_rtp_ts,
771 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200772 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200773{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200774 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200775 OSMO_ASSERT(trunk);
776 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200777 return CMD_SUCCESS;
778}
779
780DEFUN(cfg_mgcp_no_patch_rtp_ts,
781 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200782 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200783{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200784 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200785 OSMO_ASSERT(trunk);
786 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200787 return CMD_SUCCESS;
788}
789
Philipp Maier9fc8a022019-02-20 12:26:52 +0100790DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
791 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
792 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
793{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200794 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200795 OSMO_ASSERT(trunk);
796 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100797 return CMD_SUCCESS;
798}
799
800DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
801 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
802 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
803{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200804 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200805 OSMO_ASSERT(trunk);
806 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100807 return CMD_SUCCESS;
808}
809
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200810DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200811 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200812{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200813 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200814 OSMO_ASSERT(trunk);
815 trunk->force_constant_ssrc = 0;
816 trunk->force_aligned_timing = 0;
817 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200818 return CMD_SUCCESS;
819}
820
821DEFUN(cfg_mgcp_rtp_keepalive,
822 cfg_mgcp_rtp_keepalive_cmd,
823 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200824 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200825{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200826 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200827 OSMO_ASSERT(trunk);
828 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200829 return CMD_SUCCESS;
830}
831
832DEFUN(cfg_mgcp_rtp_keepalive_once,
833 cfg_mgcp_rtp_keepalive_once_cmd,
834 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200835 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200836{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200837 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200838 OSMO_ASSERT(trunk);
839 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200840 return CMD_SUCCESS;
841}
842
843DEFUN(cfg_mgcp_no_rtp_keepalive,
844 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200845 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200846{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200847 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200848 OSMO_ASSERT(trunk);
849 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200850 return CMD_SUCCESS;
851}
852
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200853#define CALL_AGENT_STR "Callagent information\n"
854DEFUN(cfg_mgcp_agent_addr,
855 cfg_mgcp_agent_addr_cmd,
856 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200857 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200858{
859 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
860 return CMD_SUCCESS;
861}
862
863ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200864 "call agent ip A.B.C.D",
865 CALL_AGENT_STR CALL_AGENT_STR IP_STR
866 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200867
Philipp Maier21be42a2020-05-29 21:39:48 +0200868DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200869 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200870{
Philipp Maier14b27a82020-06-02 20:15:30 +0200871 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200872 int index = atoi(argv[0]);
873
Philipp Maierd19de2e2020-06-03 13:55:33 +0200874 /* Due to historical reasons, the trunk id number 0 is reserved for the
875 * virtual trunk. This trunk is configured with separate VTY
876 * parameters, so we restrict the access to trunks with id numbers
877 * greater than 0. */
878
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200879 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100880 if (!trunk) {
881 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200882 if (!trunk) {
883 vty_out(vty, "%%Unable to allocate trunk %u.%s",
884 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100885 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200886 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200887 }
888
889 vty->node = TRUNK_NODE;
890 vty->index = trunk;
891 return CMD_SUCCESS;
892}
893
894static int config_write_trunk(struct vty *vty)
895{
Philipp Maier14b27a82020-06-02 20:15:30 +0200896 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200897
898 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200899
900 /* Due to historical reasons, the virtual trunk is configured
901 using separate VTY parameters, so we omit writing the trunk
902 config of trunk 0 here. The configuration for the virtual
903 trunk is written by config_write_mgcp(). */
904
905 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
906 continue;
907
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200908 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200909 vty_out(vty, " line %u%s", trunk->e1.vty_line_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200910 vty_out(vty, " %ssdp audio-payload send-ptime%s",
911 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
912 vty_out(vty, " %ssdp audio-payload send-name%s",
913 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
914
915 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
916 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
917 else if (trunk->keepalive_interval)
918 vty_out(vty, " rtp keep-alive %d%s",
919 trunk->keepalive_interval, VTY_NEWLINE);
920 else
921 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200922 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200923 vty_out(vty, " force-realloc %d%s",
924 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200925 vty_out(vty, " rtp-accept-all %d%s",
926 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200927 if (trunk->omit_rtcp)
928 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
929 else
930 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100931 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200932 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200933 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200934 trunk->force_constant_ssrc ? "" : "no ",
935 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200936 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200937 trunk->force_aligned_timing ? "" : "no ",
938 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100939 vty_out(vty, " %srtp-patch rfc5993hr%s",
940 trunk->rfc5993_hr_convert ? "" : "no ",
941 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200942 } else
943 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
944 if (trunk->audio_fmtp_extra)
945 vty_out(vty, " sdp audio fmtp-extra %s%s",
946 trunk->audio_fmtp_extra, VTY_NEWLINE);
947 vty_out(vty, " %sallow-transcoding%s",
948 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
949 }
950
951 return CMD_SUCCESS;
952}
953
954DEFUN(cfg_trunk_sdp_fmtp_extra,
955 cfg_trunk_sdp_fmtp_extra_cmd,
956 "sdp audio fmtp-extra .NAME",
957 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
958 "Extra Information\n")
959{
Philipp Maier14b27a82020-06-02 20:15:30 +0200960 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200961 char *txt = argv_concat(argv, argc, 0);
962 if (!txt)
963 return CMD_WARNING;
964
965 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
966 talloc_free(txt);
967 return CMD_SUCCESS;
968}
969
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200970DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200971 cfg_trunk_payload_number_cmd,
972 "sdp audio-payload number <0-255>",
973 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
974{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200975 return CMD_SUCCESS;
976}
977
978ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200979 "sdp audio payload number <0-255>",
980 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200981
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200982DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200983 cfg_trunk_payload_name_cmd,
984 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200985 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200986{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200987 return CMD_SUCCESS;
988}
989
990ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200991 "sdp audio payload name NAME",
992 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200993
Philipp Maier21be42a2020-05-29 21:39:48 +0200994DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200995 cfg_trunk_loop_cmd,
996 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200997 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200998{
Philipp Maier14b27a82020-06-02 20:15:30 +0200999 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000
1001 if (g_cfg->osmux) {
1002 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
1003 return CMD_WARNING;
1004 }
1005 trunk->audio_loop = atoi(argv[0]);
1006 return CMD_SUCCESS;
1007}
1008
1009DEFUN(cfg_trunk_sdp_payload_send_ptime,
1010 cfg_trunk_sdp_payload_send_ptime_cmd,
1011 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001012 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001013{
Philipp Maier14b27a82020-06-02 20:15:30 +02001014 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001015 trunk->audio_send_ptime = 1;
1016 return CMD_SUCCESS;
1017}
1018
1019DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1020 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1021 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001022 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001023{
Philipp Maier14b27a82020-06-02 20:15:30 +02001024 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001025 trunk->audio_send_ptime = 0;
1026 return CMD_SUCCESS;
1027}
1028
1029DEFUN(cfg_trunk_sdp_payload_send_name,
1030 cfg_trunk_sdp_payload_send_name_cmd,
1031 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001032 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001033{
Philipp Maier14b27a82020-06-02 20:15:30 +02001034 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001035 trunk->audio_send_name = 1;
1036 return CMD_SUCCESS;
1037}
1038
1039DEFUN(cfg_trunk_no_sdp_payload_send_name,
1040 cfg_trunk_no_sdp_payload_send_name_cmd,
1041 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001042 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001043{
Philipp Maier14b27a82020-06-02 20:15:30 +02001044 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001045 trunk->audio_send_name = 0;
1046 return CMD_SUCCESS;
1047}
1048
Philipp Maier87bd9be2017-08-22 16:35:41 +02001049DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001050{
Philipp Maier14b27a82020-06-02 20:15:30 +02001051 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001052 trunk->omit_rtcp = 1;
1053 return CMD_SUCCESS;
1054}
1055
1056DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001057 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001058{
Philipp Maier14b27a82020-06-02 20:15:30 +02001059 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001060 trunk->omit_rtcp = 0;
1061 return CMD_SUCCESS;
1062}
1063
1064DEFUN(cfg_trunk_patch_rtp_ssrc,
1065 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001066 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001067{
Philipp Maier14b27a82020-06-02 20:15:30 +02001068 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001069 trunk->force_constant_ssrc = 1;
1070 return CMD_SUCCESS;
1071}
1072
1073DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1074 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001075 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001076{
Philipp Maier14b27a82020-06-02 20:15:30 +02001077 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001078 trunk->force_constant_ssrc = 0;
1079 return CMD_SUCCESS;
1080}
1081
1082DEFUN(cfg_trunk_patch_rtp_ts,
1083 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001084 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001085{
Philipp Maier14b27a82020-06-02 20:15:30 +02001086 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001087 trunk->force_aligned_timing = 1;
1088 return CMD_SUCCESS;
1089}
1090
1091DEFUN(cfg_trunk_no_patch_rtp_ts,
1092 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001093 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001094{
Philipp Maier14b27a82020-06-02 20:15:30 +02001095 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001096 trunk->force_aligned_timing = 0;
1097 return CMD_SUCCESS;
1098}
1099
Philipp Maier9fc8a022019-02-20 12:26:52 +01001100DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1101 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1102 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1103{
Philipp Maier14b27a82020-06-02 20:15:30 +02001104 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001105 trunk->rfc5993_hr_convert = true;
1106 return CMD_SUCCESS;
1107}
1108
1109DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1110 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1111 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1112{
Philipp Maier14b27a82020-06-02 20:15:30 +02001113 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001114 trunk->rfc5993_hr_convert = false;
1115 return CMD_SUCCESS;
1116}
1117
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001118DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001119 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
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->force_constant_ssrc = 0;
1123 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001124 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001125 return CMD_SUCCESS;
1126}
1127
1128DEFUN(cfg_trunk_rtp_keepalive,
1129 cfg_trunk_rtp_keepalive_cmd,
1130 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001131 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001132{
Philipp Maier14b27a82020-06-02 20:15:30 +02001133 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001134 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1135 return CMD_SUCCESS;
1136}
1137
1138DEFUN(cfg_trunk_rtp_keepalive_once,
1139 cfg_trunk_rtp_keepalive_once_cmd,
1140 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001141 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001142{
Philipp Maier14b27a82020-06-02 20:15:30 +02001143 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001144 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1145 return CMD_SUCCESS;
1146}
1147
1148DEFUN(cfg_trunk_no_rtp_keepalive,
1149 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001150 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001151{
Philipp Maier14b27a82020-06-02 20:15:30 +02001152 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001153 mgcp_trunk_set_keepalive(trunk, 0);
1154 return CMD_SUCCESS;
1155}
1156
1157DEFUN(cfg_trunk_allow_transcoding,
1158 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001159 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001160{
Philipp Maier14b27a82020-06-02 20:15:30 +02001161 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001162 trunk->no_audio_transcoding = 0;
1163 return CMD_SUCCESS;
1164}
1165
1166DEFUN(cfg_trunk_no_allow_transcoding,
1167 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001168 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001169{
Philipp Maier14b27a82020-06-02 20:15:30 +02001170 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001171 trunk->no_audio_transcoding = 1;
1172 return CMD_SUCCESS;
1173}
1174
Philipp Maier889fe7f2020-07-06 17:44:12 +02001175#define LINE_STR "Configure trunk for given Line\nE1/T1 Line Number\n"
1176
1177DEFUN(cfg_trunk_line,
1178 cfg_trunk_line_cmd,
1179 "line <0-255>",
1180 LINE_STR)
1181{
1182 struct mgcp_trunk *trunk = vty->index;
1183 int line_nr = atoi(argv[0]);
1184 trunk->e1.vty_line_nr = line_nr;
1185 return CMD_SUCCESS;
1186}
1187
Philipp Maier87bd9be2017-08-22 16:35:41 +02001188DEFUN(loop_conn,
1189 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001190 "loop-endpoint <0-64> NAME (0|1)",
1191 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001192 "The name in hex of the endpoint\n" "Disable the loop\n"
1193 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001194{
Philipp Maier14b27a82020-06-02 20:15:30 +02001195 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001196 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001197 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001198
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001199 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001200 if (!trunk) {
1201 vty_out(vty, "%%Trunk %d not found in the config.%s",
1202 atoi(argv[0]), VTY_NEWLINE);
1203 return CMD_WARNING;
1204 }
1205
1206 if (!trunk->endpoints) {
1207 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1208 trunk->trunk_nr, VTY_NEWLINE);
1209 return CMD_WARNING;
1210 }
1211
1212 int endp_no = strtoul(argv[1], NULL, 16);
1213 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1214 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001215 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001216 return CMD_WARNING;
1217 }
1218
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001219 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001220 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001221 llist_for_each_entry(conn, &endp->conns, entry) {
1222 if (conn->type == MGCP_CONN_TYPE_RTP)
1223 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1224 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1225 else {
1226 /* FIXME: Introduce support for other connection (E1)
1227 * types when implementation is available */
1228 vty_out(vty, "%%Can't enable SSRC patching,"
1229 "connection %s is not an RTP connection.%s",
1230 mgcp_conn_dump(conn), VTY_NEWLINE);
1231 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001232
Philipp Maier87bd9be2017-08-22 16:35:41 +02001233 if (loop)
1234 conn->mode = MGCP_CONN_LOOPBACK;
1235 else
1236 conn->mode = conn->mode_orig;
1237 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001238
1239 return CMD_SUCCESS;
1240}
1241
Philipp Maier87bd9be2017-08-22 16:35:41 +02001242DEFUN(tap_rtp,
1243 tap_rtp_cmd,
1244 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001245 "Forward data on endpoint to a different system\n" "Trunk number\n"
1246 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001247 "The connection id in hex\n"
1248 "Forward incoming data\n"
1249 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001250 "destination IP of the data\n" "destination port\n")
1251{
1252 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001253 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001254 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001255 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001256 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001257
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001258 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001259 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];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001279
Philipp Maier01d24a32017-11-21 17:26:09 +01001280 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001281 conn = mgcp_conn_get_rtp(endp, conn_id);
1282 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001283 vty_out(vty, "Conn ID %s is invalid.%s",
1284 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001285 return CMD_WARNING;
1286 }
1287
1288 if (strcmp(argv[3], "in") == 0)
1289 tap = &conn->tap_in;
1290 else if (strcmp(argv[3], "out") == 0)
1291 tap = &conn->tap_out;
1292 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001293 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1294 return CMD_WARNING;
1295 }
1296
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001297 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001298 inet_aton(argv[4], &tap->forward.sin_addr);
1299 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001300 tap->enabled = 1;
1301 return CMD_SUCCESS;
1302}
1303
1304DEFUN(free_endp, free_endp_cmd,
1305 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001306 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001307{
Philipp Maier14b27a82020-06-02 20:15:30 +02001308 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001309 struct mgcp_endpoint *endp;
1310
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001311 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001312 if (!trunk) {
1313 vty_out(vty, "%%Trunk %d not found in the config.%s",
1314 atoi(argv[0]), VTY_NEWLINE);
1315 return CMD_WARNING;
1316 }
1317
1318 if (!trunk->endpoints) {
1319 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1320 trunk->trunk_nr, VTY_NEWLINE);
1321 return CMD_WARNING;
1322 }
1323
1324 int endp_no = strtoul(argv[1], NULL, 16);
1325 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1326 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001327 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001328 return CMD_WARNING;
1329 }
1330
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001331 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001332 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001333 return CMD_SUCCESS;
1334}
1335
1336DEFUN(reset_endp, reset_endp_cmd,
1337 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001338 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001339{
Philipp Maier14b27a82020-06-02 20:15:30 +02001340 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001341 struct mgcp_endpoint *endp;
1342 int endp_no, rc;
1343
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001344 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001345 if (!trunk) {
1346 vty_out(vty, "%%Trunk %d not found in the config.%s",
1347 atoi(argv[0]), VTY_NEWLINE);
1348 return CMD_WARNING;
1349 }
1350
1351 if (!trunk->endpoints) {
1352 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1353 trunk->trunk_nr, VTY_NEWLINE);
1354 return CMD_WARNING;
1355 }
1356
1357 endp_no = strtoul(argv[1], NULL, 16);
1358 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1359 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001360 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001361 return CMD_WARNING;
1362 }
1363
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001364 endp = trunk->endpoints[endp_no];
1365 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001366 if (rc < 0) {
1367 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1368 return CMD_WARNING;
1369 }
1370 return CMD_SUCCESS;
1371}
1372
1373DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001374 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001375{
1376 int rc;
1377
1378 rc = mgcp_send_reset_all(g_cfg);
1379 if (rc < 0) {
1380 vty_out(vty, "Error %d during endpoint reset.%s",
1381 rc, VTY_NEWLINE);
1382 return CMD_WARNING;
1383 }
1384 return CMD_SUCCESS;
1385}
1386
1387#define OSMUX_STR "RTP multiplexing\n"
1388DEFUN(cfg_mgcp_osmux,
1389 cfg_mgcp_osmux_cmd,
1390 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001391 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001392{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001393 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001394 OSMO_ASSERT(trunk);
1395
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001396 if (strcmp(argv[0], "off") == 0) {
1397 g_cfg->osmux = OSMUX_USAGE_OFF;
1398 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001399 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001400 g_cfg->osmux = OSMUX_USAGE_ON;
1401 else if (strcmp(argv[0], "only") == 0)
1402 g_cfg->osmux = OSMUX_USAGE_ONLY;
1403
Philipp Maierd19de2e2020-06-03 13:55:33 +02001404 if (trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001405 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001406 return CMD_WARNING;
1407 }
1408
1409 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001410
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001411}
1412
1413DEFUN(cfg_mgcp_osmux_ip,
1414 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001415 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001416{
1417 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1418 return CMD_SUCCESS;
1419}
1420
1421DEFUN(cfg_mgcp_osmux_batch_factor,
1422 cfg_mgcp_osmux_batch_factor_cmd,
1423 "osmux batch-factor <1-8>",
1424 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1425{
1426 g_cfg->osmux_batch = atoi(argv[0]);
1427 return CMD_SUCCESS;
1428}
1429
1430DEFUN(cfg_mgcp_osmux_batch_size,
1431 cfg_mgcp_osmux_batch_size_cmd,
1432 "osmux batch-size <1-65535>",
1433 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1434{
1435 g_cfg->osmux_batch_size = atoi(argv[0]);
1436 return CMD_SUCCESS;
1437}
1438
1439DEFUN(cfg_mgcp_osmux_port,
1440 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001441 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001442{
1443 g_cfg->osmux_port = atoi(argv[0]);
1444 return CMD_SUCCESS;
1445}
1446
1447DEFUN(cfg_mgcp_osmux_dummy,
1448 cfg_mgcp_osmux_dummy_cmd,
1449 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001450 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1451 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001452{
1453 if (strcmp(argv[0], "on") == 0)
1454 g_cfg->osmux_dummy = 1;
1455 else if (strcmp(argv[0], "off") == 0)
1456 g_cfg->osmux_dummy = 0;
1457
1458 return CMD_SUCCESS;
1459}
1460
Philipp Maier12943ea2018-01-17 15:40:25 +01001461DEFUN(cfg_mgcp_domain,
1462 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001463 "domain NAME",
1464 "Set the domain part expected in MGCP messages' endpoint names\n"
1465 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001466{
1467 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1468 return CMD_SUCCESS;
1469}
1470
Oliver Smithe36b7752019-01-22 16:31:36 +01001471DEFUN(cfg_mgcp_conn_timeout,
1472 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001473 "conn-timeout <0-65534>",
1474 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1475 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001476 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1477 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001478 "Timeout value (sec.)\n")
1479{
1480 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1481 return CMD_SUCCESS;
1482}
1483
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001484int mgcp_vty_init(void)
1485{
1486 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001487 install_element_ve(&show_mgcp_endpoint_cmd);
1488 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001489 install_element(ENABLE_NODE, &loop_conn_cmd);
1490 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001491 install_element(ENABLE_NODE, &free_endp_cmd);
1492 install_element(ENABLE_NODE, &reset_endp_cmd);
1493 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1494
1495 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1496 install_node(&mgcp_node, config_write_mgcp);
1497
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001498 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001499 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1500 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1501 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001502 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001503 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001504 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001505 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001506 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001507 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001508 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1509 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001510 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1511 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1512 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1513 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1514 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1515 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1516 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1517 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1518 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001519 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1520 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1521 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1522 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1523 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1524 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001525 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001526 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1527 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1528 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1529 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1530 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1531 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1532 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1533 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001534 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1535 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001536 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1537 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1538 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1539 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1540 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1541 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1542 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1543 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1544 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1545 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1546 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1547 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1548 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001549 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001550 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001551
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001552 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1553 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001554 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1555 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1556 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1557 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1558 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1559 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1560 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1561 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1562 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1563 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1564 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1565 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1566 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001567 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1568 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001569 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1570 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1571 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1572 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1573 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1574 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1575 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1576 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1577 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001578 install_element(TRUNK_NODE, &cfg_trunk_line_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001579
1580 return 0;
1581}
1582
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001583int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1584 enum mgcp_role role)
1585{
1586 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001587 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001588
1589 cfg->osmux_port = OSMUX_PORT;
1590 cfg->osmux_batch = 4;
1591 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1592
1593 g_cfg = cfg;
1594 rc = vty_read_config_file(config_file, NULL);
1595 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001596 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1597 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001598 return rc;
1599 }
1600
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001601 if (!g_cfg->source_addr) {
1602 fprintf(stderr, "You need to specify a bind address.\n");
1603 return -1;
1604 }
1605
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001606 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier889fe7f2020-07-06 17:44:12 +02001607 if (mgcp_trunk_equip(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001608 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001609 "Failed to initialize trunk %d (%d endpoints)\n",
1610 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001611 return -1;
1612 }
1613 }
1614 cfg->role = role;
1615
1616 return 0;
1617}