blob: 938eef5fc83cd5c3aa35d14d429316e974d04a00 [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 Maierd19de2e2020-06-03 13:55:33 +020060 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
61 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",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100115 trunk->vty_number_endpoints - 1, 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);
Stefan Sperling12086582018-06-26 15:26:28 +0200202
203 if (llist_empty(&endp->conns)) {
204 vty_out(vty, " No active connections%s", VTY_NEWLINE);
205 return;
206 }
207
208 llist_for_each_entry(conn, &endp->conns, entry) {
209 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
210
211 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100212 if (endp->cfg->conn_timeout) {
213 struct timeval remaining;
214 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
215 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
216 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
217 }
218
Stefan Sperling12086582018-06-26 15:26:28 +0200219 /* FIXME: Also add verbosity for other
220 * connection types (E1) as soon as
221 * the implementation is available */
222 if (conn->type == MGCP_CONN_TYPE_RTP) {
223 dump_rtp_end(vty, &conn->u.rtp);
224 }
225 }
226 }
227}
228
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200229static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
230{
231 vty_out(vty, "%s", VTY_NEWLINE);
232 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
233
234 if (ratectr->mgcp_general_ctr_group) {
235 vty_out(vty, " %s:%s",
236 ratectr->mgcp_general_ctr_group->desc->
237 group_description, VTY_NEWLINE);
238 vty_out_rate_ctr_group_fmt(vty,
239 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
240 ratectr->mgcp_general_ctr_group);
241 }
242}
243
244static void dump_ratectr_trunk(struct vty *vty, struct mgcp_ratectr_trunk *ratectr)
245{
246 vty_out(vty, "%s", VTY_NEWLINE);
247 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
248
249 if (ratectr->mgcp_crcx_ctr_group) {
250 vty_out(vty, " %s:%s",
251 ratectr->mgcp_crcx_ctr_group->desc->group_description,
252 VTY_NEWLINE);
253 vty_out_rate_ctr_group_fmt(vty,
254 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
255 ratectr->mgcp_crcx_ctr_group);
256 }
257 if (ratectr->mgcp_dlcx_ctr_group) {
258 vty_out(vty, " %s:%s",
259 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
260 VTY_NEWLINE);
261 vty_out_rate_ctr_group_fmt(vty,
262 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
263 ratectr->mgcp_dlcx_ctr_group);
264 }
265 if (ratectr->mgcp_mdcx_ctr_group) {
266 vty_out(vty, " %s:%s",
267 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
268 VTY_NEWLINE);
269 vty_out_rate_ctr_group_fmt(vty,
270 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
271 ratectr->mgcp_mdcx_ctr_group);
272 }
273 if (ratectr->all_rtp_conn_stats) {
274 vty_out(vty, " %s:%s",
275 ratectr->all_rtp_conn_stats->desc->group_description,
276 VTY_NEWLINE);
277 vty_out_rate_ctr_group_fmt(vty,
278 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
279 ratectr->all_rtp_conn_stats);
280 }
281}
282
283
284static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200285{
286 int i;
287
288 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200289 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
290 trunk->trunk_nr, trunk->number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200291
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200292 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200293 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
294 return;
295 }
296
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200297 for (i = 0; i < trunk->number_endpoints; ++i) {
298 struct mgcp_endpoint *endp = trunk->endpoints[i];
299 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
300 show_stats);
301 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200302 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200303 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200304
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200305 if (show_stats)
306 dump_ratectr_trunk(vty, &trunk->ratectr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200307}
308
Stefan Sperling12086582018-06-26 15:26:28 +0200309#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
310
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200311DEFUN(show_mcgp, show_mgcp_cmd,
312 "show mgcp [stats]",
313 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200314 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200315 "Include Statistics\n")
316{
Philipp Maier14b27a82020-06-02 20:15:30 +0200317 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200318 int show_stats = argc >= 1;
319
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200320 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200321 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200322
323 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200324 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200325 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200326
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200327 if (show_stats)
328 dump_ratectr_global(vty, &g_cfg->ratectr);
329
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200330 return CMD_SUCCESS;
331}
332
Stefan Sperling12086582018-06-26 15:26:28 +0200333static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200334dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200335{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200336 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200337
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200338 if (trunk) {
339 /* If a trunk is given, search on that specific trunk only */
340 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
341 if (!endp) {
342 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
343 return;
344 }
345 } else {
346 /* If no trunk is given, search on all possible trunks */
347 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
348 if (!endp) {
349 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
350 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200351 }
352 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200353
354 trunk = endp->trunk;
355 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200356}
357
358DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
359 "show mgcp endpoint NAME",
360 SHOW_STR
361 SHOW_MGCP_STR
362 "Display information about an endpoint\n" "The name of the endpoint\n")
363{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200364 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200365 return CMD_SUCCESS;
366}
367
368DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
369 "show mgcp trunk <0-64> endpoint NAME",
370 SHOW_STR
371 SHOW_MGCP_STR
372 "Display information about a trunk\n" "Trunk number\n"
373 "Display information about an endpoint\n" "The name of the endpoint\n")
374{
Philipp Maier14b27a82020-06-02 20:15:30 +0200375 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200376 int trunkidx = atoi(argv[0]);
377
Philipp Maierd19de2e2020-06-03 13:55:33 +0200378 trunk = mgcp_trunk_by_num(g_cfg, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200379 if (!trunk) {
380 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
381 return CMD_WARNING;
382 }
383
384 dump_mgcp_endpoint(vty, trunk, argv[1]);
385 return CMD_SUCCESS;
386}
387
Philipp Maier87bd9be2017-08-22 16:35:41 +0200388DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200389{
390 vty->node = MGCP_NODE;
391 return CMD_SUCCESS;
392}
393
394DEFUN(cfg_mgcp_local_ip,
395 cfg_mgcp_local_ip_cmd,
396 "local ip A.B.C.D",
397 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200398 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200399{
400 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
401 return CMD_SUCCESS;
402}
403
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200404#define BIND_STR "Listen/Bind related socket option\n"
405DEFUN(cfg_mgcp_bind_ip,
406 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200407 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200408{
409 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
410 return CMD_SUCCESS;
411}
412
413DEFUN(cfg_mgcp_bind_port,
414 cfg_mgcp_bind_port_cmd,
415 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200416 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200417{
418 unsigned int port = atoi(argv[0]);
419 g_cfg->source_port = port;
420 return CMD_SUCCESS;
421}
422
423DEFUN(cfg_mgcp_bind_early,
424 cfg_mgcp_bind_early_cmd,
425 "bind early (0|1)",
426 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200427 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200428{
429 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
430 return CMD_WARNING;
431}
432
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200433#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200434#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200435#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200436#define RANGE_START_STR "Start of the range of ports\n"
437#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200438
Philipp Maierf1889d82017-11-08 14:59:39 +0100439DEFUN(cfg_mgcp_rtp_port_range,
440 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200441 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200442 RTP_STR "Range of ports to use for the NET side\n"
443 RANGE_START_STR RANGE_END_STR)
444{
Philipp Maiera19547b2018-05-22 13:44:34 +0200445 int start;
446 int end;
447
448 start = atoi(argv[0]);
449 end = atoi(argv[1]);
450
451 if (end < start) {
452 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
453 end, start, VTY_NEWLINE);
454 return CMD_WARNING;
455 }
456
457 if (start & 1) {
458 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
459 start, start & 0xFFFE, VTY_NEWLINE);
460 start &= 0xFFFE;
461 }
462
463 if ((end & 1) == 0) {
464 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
465 end, end | 1, VTY_NEWLINE);
466 end |= 1;
467 }
468
469 g_cfg->net_ports.range_start = start;
470 g_cfg->net_ports.range_end = end;
471 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
472
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200473 return CMD_SUCCESS;
474}
Philipp Maierf1889d82017-11-08 14:59:39 +0100475ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
476 cfg_mgcp_rtp_net_range_cmd,
477 "rtp net-range <0-65534> <0-65534>",
478 RTP_STR "Range of ports to use for the NET side\n"
479 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200480
Philipp Maierf1889d82017-11-08 14:59:39 +0100481DEFUN(cfg_mgcp_rtp_bind_ip,
482 cfg_mgcp_rtp_bind_ip_cmd,
483 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200484 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
485{
486 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
487 return CMD_SUCCESS;
488}
Philipp Maierf1889d82017-11-08 14:59:39 +0100489ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
490 cfg_mgcp_rtp_net_bind_ip_cmd,
491 "rtp net-bind-ip A.B.C.D",
492 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200493
Philipp Maierf1889d82017-11-08 14:59:39 +0100494DEFUN(cfg_mgcp_rtp_no_bind_ip,
495 cfg_mgcp_rtp_no_bind_ip_cmd,
496 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200497 NO_STR RTP_STR "Bind endpoints facing the Network\n"
498 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200499{
500 talloc_free(g_cfg->net_ports.bind_addr);
501 g_cfg->net_ports.bind_addr = NULL;
502 return CMD_SUCCESS;
503}
Philipp Maierf1889d82017-11-08 14:59:39 +0100504ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
505 cfg_mgcp_rtp_no_net_bind_ip_cmd,
506 "no rtp net-bind-ip",
507 NO_STR RTP_STR "Bind endpoints facing the Network\n"
508 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200509
Philipp Maier1cb1e382017-11-02 17:16:04 +0100510DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
511 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
512 "rtp ip-probing",
513 RTP_STR "automatic rtp bind ip selection\n")
514{
515 g_cfg->net_ports.bind_addr_probe = true;
516 return CMD_SUCCESS;
517}
518
519DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
520 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
521 "no rtp ip-probing",
522 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
523{
524 g_cfg->net_ports.bind_addr_probe = false;
525 return CMD_SUCCESS;
526}
527
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200528DEFUN(cfg_mgcp_rtp_ip_dscp,
529 cfg_mgcp_rtp_ip_dscp_cmd,
530 "rtp ip-dscp <0-255>",
531 RTP_STR
532 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
533{
534 int dscp = atoi(argv[0]);
535 g_cfg->endp_dscp = dscp;
536 return CMD_SUCCESS;
537}
538
539ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200540 "rtp ip-tos <0-255>",
541 RTP_STR
542 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
543#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200544DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200545 cfg_mgcp_rtp_force_ptime_cmd,
546 "rtp force-ptime (10|20|40)",
547 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200548 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200549{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200550 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200551 return CMD_SUCCESS;
552}
553
554DEFUN(cfg_mgcp_no_rtp_force_ptime,
555 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200556 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200557{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200558 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200559 return CMD_SUCCESS;
560}
561
562DEFUN(cfg_mgcp_sdp_fmtp_extra,
563 cfg_mgcp_sdp_fmtp_extra_cmd,
564 "sdp audio fmtp-extra .NAME",
565 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
566 "Extra Information\n")
567{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200568 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
569 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200570 char *txt = argv_concat(argv, argc, 0);
571 if (!txt)
572 return CMD_WARNING;
573
Philipp Maierd19de2e2020-06-03 13:55:33 +0200574 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200575 talloc_free(txt);
576 return CMD_SUCCESS;
577}
578
579DEFUN(cfg_mgcp_allow_transcoding,
580 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200581 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200582{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200583 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
584 OSMO_ASSERT(trunk);
585 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200586 return CMD_SUCCESS;
587}
588
589DEFUN(cfg_mgcp_no_allow_transcoding,
590 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200591 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200592{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200593 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
594 OSMO_ASSERT(trunk);
595 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200596 return CMD_SUCCESS;
597}
598
599#define SDP_STR "SDP File related options\n"
600#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200601DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200602 cfg_mgcp_sdp_payload_number_cmd,
603 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200604 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200605{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200606 return CMD_SUCCESS;
607}
608
Philipp Maier87bd9be2017-08-22 16:35:41 +0200609ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
610 cfg_mgcp_sdp_payload_number_cmd_old,
611 "sdp audio payload number <0-255>",
612 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200613
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200614DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200615 cfg_mgcp_sdp_payload_name_cmd,
616 "sdp audio-payload name NAME",
617 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
618{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200619 return CMD_SUCCESS;
620}
621
622ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200623 "sdp audio payload name NAME",
624 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200625
Philipp Maier21be42a2020-05-29 21:39:48 +0200626DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200627 cfg_mgcp_sdp_payload_send_ptime_cmd,
628 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200629 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200630{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200631 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
632 OSMO_ASSERT(trunk);
633 trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200634 return CMD_SUCCESS;
635}
636
637DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
638 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
639 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200640 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200641{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200642 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
643 OSMO_ASSERT(trunk);
644 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200645 return CMD_SUCCESS;
646}
647
648DEFUN(cfg_mgcp_sdp_payload_send_name,
649 cfg_mgcp_sdp_payload_send_name_cmd,
650 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200651 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200652{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200653 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
654 OSMO_ASSERT(trunk);
655 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200656 return CMD_SUCCESS;
657}
658
659DEFUN(cfg_mgcp_no_sdp_payload_send_name,
660 cfg_mgcp_no_sdp_payload_send_name_cmd,
661 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200662 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200663{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200664 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
665 OSMO_ASSERT(trunk);
666 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200667 return CMD_SUCCESS;
668}
669
670DEFUN(cfg_mgcp_loop,
671 cfg_mgcp_loop_cmd,
672 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200673 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200674{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200675 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
676 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200677 if (g_cfg->osmux) {
678 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
679 return CMD_WARNING;
680 }
Philipp Maierd19de2e2020-06-03 13:55:33 +0200681 trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200682 return CMD_SUCCESS;
683}
684
685DEFUN(cfg_mgcp_force_realloc,
686 cfg_mgcp_force_realloc_cmd,
687 "force-realloc (0|1)",
688 "Force endpoint reallocation when the endpoint is still seized\n"
689 "Don't force reallocation\n" "force reallocation\n")
690{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200691 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
692 OSMO_ASSERT(trunk);
693 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200694 return CMD_SUCCESS;
695}
696
Philipp Maier87bd9be2017-08-22 16:35:41 +0200697DEFUN(cfg_mgcp_rtp_accept_all,
698 cfg_mgcp_rtp_accept_all_cmd,
699 "rtp-accept-all (0|1)",
700 "Accept all RTP packets, even when the originating IP/Port does not match\n"
701 "enable filter\n" "disable filter\n")
702{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200703 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
704 OSMO_ASSERT(trunk);
705 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200706 return CMD_SUCCESS;
707}
708
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200709DEFUN(cfg_mgcp_number_endp,
710 cfg_mgcp_number_endp_cmd,
711 "number endpoints <0-65534>",
712 "Number options\n" "Endpoints available\n" "Number endpoints\n")
713{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200714 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
715 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200716 /* + 1 as we start counting at one */
Philipp Maierd19de2e2020-06-03 13:55:33 +0200717 trunk->vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200718 return CMD_SUCCESS;
719}
720
Philipp Maier87bd9be2017-08-22 16:35:41 +0200721DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200722{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200723 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, 0);
724 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200725 return CMD_SUCCESS;
726}
727
728DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200729 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200731 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
732 OSMO_ASSERT(trunk);
733 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200734 return CMD_SUCCESS;
735}
736
737DEFUN(cfg_mgcp_patch_rtp_ssrc,
738 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200739 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200740{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200741 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
742 OSMO_ASSERT(trunk);
743 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200744 return CMD_SUCCESS;
745}
746
747DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
748 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200749 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200750{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200751 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
752 OSMO_ASSERT(trunk);
753 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200754 return CMD_SUCCESS;
755}
756
757DEFUN(cfg_mgcp_patch_rtp_ts,
758 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200759 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200760{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200761 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
762 OSMO_ASSERT(trunk);
763 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200764 return CMD_SUCCESS;
765}
766
767DEFUN(cfg_mgcp_no_patch_rtp_ts,
768 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200769 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200770{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200771 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
772 OSMO_ASSERT(trunk);
773 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200774 return CMD_SUCCESS;
775}
776
Philipp Maier9fc8a022019-02-20 12:26:52 +0100777DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
778 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
779 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
780{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200781 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
782 OSMO_ASSERT(trunk);
783 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100784 return CMD_SUCCESS;
785}
786
787DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
788 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
789 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
790{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200791 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
792 OSMO_ASSERT(trunk);
793 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100794 return CMD_SUCCESS;
795}
796
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200797DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200798 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200799{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200800 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
801 OSMO_ASSERT(trunk);
802 trunk->force_constant_ssrc = 0;
803 trunk->force_aligned_timing = 0;
804 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200805 return CMD_SUCCESS;
806}
807
808DEFUN(cfg_mgcp_rtp_keepalive,
809 cfg_mgcp_rtp_keepalive_cmd,
810 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200811 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200812{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200813 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
814 OSMO_ASSERT(trunk);
815 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200816 return CMD_SUCCESS;
817}
818
819DEFUN(cfg_mgcp_rtp_keepalive_once,
820 cfg_mgcp_rtp_keepalive_once_cmd,
821 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200822 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200823{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200824 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
825 OSMO_ASSERT(trunk);
826 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200827 return CMD_SUCCESS;
828}
829
830DEFUN(cfg_mgcp_no_rtp_keepalive,
831 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200832 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200833{
Philipp Maierd19de2e2020-06-03 13:55:33 +0200834 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
835 OSMO_ASSERT(trunk);
836 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200837 return CMD_SUCCESS;
838}
839
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200840#define CALL_AGENT_STR "Callagent information\n"
841DEFUN(cfg_mgcp_agent_addr,
842 cfg_mgcp_agent_addr_cmd,
843 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200844 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200845{
846 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
847 return CMD_SUCCESS;
848}
849
850ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200851 "call agent ip A.B.C.D",
852 CALL_AGENT_STR CALL_AGENT_STR IP_STR
853 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200854
Philipp Maier21be42a2020-05-29 21:39:48 +0200855DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200856 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200857{
Philipp Maier14b27a82020-06-02 20:15:30 +0200858 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200859 int index = atoi(argv[0]);
860
Philipp Maierd19de2e2020-06-03 13:55:33 +0200861 /* Due to historical reasons, the trunk id number 0 is reserved for the
862 * virtual trunk. This trunk is configured with separate VTY
863 * parameters, so we restrict the access to trunks with id numbers
864 * greater than 0. */
865
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200866 trunk = mgcp_trunk_by_num(g_cfg, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100867 if (!trunk) {
868 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200869 if (!trunk) {
870 vty_out(vty, "%%Unable to allocate trunk %u.%s",
871 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100872 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200873 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200874 }
875
876 vty->node = TRUNK_NODE;
877 vty->index = trunk;
878 return CMD_SUCCESS;
879}
880
881static int config_write_trunk(struct vty *vty)
882{
Philipp Maier14b27a82020-06-02 20:15:30 +0200883 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200884
885 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200886
887 /* Due to historical reasons, the virtual trunk is configured
888 using separate VTY parameters, so we omit writing the trunk
889 config of trunk 0 here. The configuration for the virtual
890 trunk is written by config_write_mgcp(). */
891
892 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
893 continue;
894
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200895 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200896 vty_out(vty, " %ssdp audio-payload send-ptime%s",
897 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
898 vty_out(vty, " %ssdp audio-payload send-name%s",
899 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
900
901 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
902 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
903 else if (trunk->keepalive_interval)
904 vty_out(vty, " rtp keep-alive %d%s",
905 trunk->keepalive_interval, VTY_NEWLINE);
906 else
907 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200908 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200909 vty_out(vty, " force-realloc %d%s",
910 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200911 vty_out(vty, " rtp-accept-all %d%s",
912 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200913 if (trunk->omit_rtcp)
914 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
915 else
916 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100917 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200918 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200919 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200920 trunk->force_constant_ssrc ? "" : "no ",
921 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200922 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200923 trunk->force_aligned_timing ? "" : "no ",
924 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100925 vty_out(vty, " %srtp-patch rfc5993hr%s",
926 trunk->rfc5993_hr_convert ? "" : "no ",
927 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200928 } else
929 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
930 if (trunk->audio_fmtp_extra)
931 vty_out(vty, " sdp audio fmtp-extra %s%s",
932 trunk->audio_fmtp_extra, VTY_NEWLINE);
933 vty_out(vty, " %sallow-transcoding%s",
934 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
935 }
936
937 return CMD_SUCCESS;
938}
939
940DEFUN(cfg_trunk_sdp_fmtp_extra,
941 cfg_trunk_sdp_fmtp_extra_cmd,
942 "sdp audio fmtp-extra .NAME",
943 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
944 "Extra Information\n")
945{
Philipp Maier14b27a82020-06-02 20:15:30 +0200946 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200947 char *txt = argv_concat(argv, argc, 0);
948 if (!txt)
949 return CMD_WARNING;
950
951 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
952 talloc_free(txt);
953 return CMD_SUCCESS;
954}
955
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200956DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200957 cfg_trunk_payload_number_cmd,
958 "sdp audio-payload number <0-255>",
959 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
960{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200961 return CMD_SUCCESS;
962}
963
964ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200965 "sdp audio payload number <0-255>",
966 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200967
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200968DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200969 cfg_trunk_payload_name_cmd,
970 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200971 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200972{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200973 return CMD_SUCCESS;
974}
975
976ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200977 "sdp audio payload name NAME",
978 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200979
Philipp Maier21be42a2020-05-29 21:39:48 +0200980DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200981 cfg_trunk_loop_cmd,
982 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200983 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200984{
Philipp Maier14b27a82020-06-02 20:15:30 +0200985 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200986
987 if (g_cfg->osmux) {
988 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
989 return CMD_WARNING;
990 }
991 trunk->audio_loop = atoi(argv[0]);
992 return CMD_SUCCESS;
993}
994
995DEFUN(cfg_trunk_sdp_payload_send_ptime,
996 cfg_trunk_sdp_payload_send_ptime_cmd,
997 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200998 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200999{
Philipp Maier14b27a82020-06-02 20:15:30 +02001000 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001001 trunk->audio_send_ptime = 1;
1002 return CMD_SUCCESS;
1003}
1004
1005DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1006 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1007 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001008 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001009{
Philipp Maier14b27a82020-06-02 20:15:30 +02001010 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001011 trunk->audio_send_ptime = 0;
1012 return CMD_SUCCESS;
1013}
1014
1015DEFUN(cfg_trunk_sdp_payload_send_name,
1016 cfg_trunk_sdp_payload_send_name_cmd,
1017 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001018 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001019{
Philipp Maier14b27a82020-06-02 20:15:30 +02001020 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001021 trunk->audio_send_name = 1;
1022 return CMD_SUCCESS;
1023}
1024
1025DEFUN(cfg_trunk_no_sdp_payload_send_name,
1026 cfg_trunk_no_sdp_payload_send_name_cmd,
1027 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001028 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001029{
Philipp Maier14b27a82020-06-02 20:15:30 +02001030 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001031 trunk->audio_send_name = 0;
1032 return CMD_SUCCESS;
1033}
1034
Philipp Maier87bd9be2017-08-22 16:35:41 +02001035DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001036{
Philipp Maier14b27a82020-06-02 20:15:30 +02001037 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001038 trunk->omit_rtcp = 1;
1039 return CMD_SUCCESS;
1040}
1041
1042DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001043 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001044{
Philipp Maier14b27a82020-06-02 20:15:30 +02001045 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001046 trunk->omit_rtcp = 0;
1047 return CMD_SUCCESS;
1048}
1049
1050DEFUN(cfg_trunk_patch_rtp_ssrc,
1051 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001052 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001053{
Philipp Maier14b27a82020-06-02 20:15:30 +02001054 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001055 trunk->force_constant_ssrc = 1;
1056 return CMD_SUCCESS;
1057}
1058
1059DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1060 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001061 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001062{
Philipp Maier14b27a82020-06-02 20:15:30 +02001063 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001064 trunk->force_constant_ssrc = 0;
1065 return CMD_SUCCESS;
1066}
1067
1068DEFUN(cfg_trunk_patch_rtp_ts,
1069 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001070 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001071{
Philipp Maier14b27a82020-06-02 20:15:30 +02001072 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001073 trunk->force_aligned_timing = 1;
1074 return CMD_SUCCESS;
1075}
1076
1077DEFUN(cfg_trunk_no_patch_rtp_ts,
1078 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001079 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001080{
Philipp Maier14b27a82020-06-02 20:15:30 +02001081 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001082 trunk->force_aligned_timing = 0;
1083 return CMD_SUCCESS;
1084}
1085
Philipp Maier9fc8a022019-02-20 12:26:52 +01001086DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1087 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1088 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1089{
Philipp Maier14b27a82020-06-02 20:15:30 +02001090 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001091 trunk->rfc5993_hr_convert = true;
1092 return CMD_SUCCESS;
1093}
1094
1095DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1096 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1097 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1098{
Philipp Maier14b27a82020-06-02 20:15:30 +02001099 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001100 trunk->rfc5993_hr_convert = false;
1101 return CMD_SUCCESS;
1102}
1103
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001104DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001105 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001106{
Philipp Maier14b27a82020-06-02 20:15:30 +02001107 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001108 trunk->force_constant_ssrc = 0;
1109 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001110 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001111 return CMD_SUCCESS;
1112}
1113
1114DEFUN(cfg_trunk_rtp_keepalive,
1115 cfg_trunk_rtp_keepalive_cmd,
1116 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001117 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001118{
Philipp Maier14b27a82020-06-02 20:15:30 +02001119 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001120 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1121 return CMD_SUCCESS;
1122}
1123
1124DEFUN(cfg_trunk_rtp_keepalive_once,
1125 cfg_trunk_rtp_keepalive_once_cmd,
1126 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001127 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001128{
Philipp Maier14b27a82020-06-02 20:15:30 +02001129 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001130 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1131 return CMD_SUCCESS;
1132}
1133
1134DEFUN(cfg_trunk_no_rtp_keepalive,
1135 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001136 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001137{
Philipp Maier14b27a82020-06-02 20:15:30 +02001138 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001139 mgcp_trunk_set_keepalive(trunk, 0);
1140 return CMD_SUCCESS;
1141}
1142
1143DEFUN(cfg_trunk_allow_transcoding,
1144 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001145 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001146{
Philipp Maier14b27a82020-06-02 20:15:30 +02001147 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001148 trunk->no_audio_transcoding = 0;
1149 return CMD_SUCCESS;
1150}
1151
1152DEFUN(cfg_trunk_no_allow_transcoding,
1153 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001154 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001155{
Philipp Maier14b27a82020-06-02 20:15:30 +02001156 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001157 trunk->no_audio_transcoding = 1;
1158 return CMD_SUCCESS;
1159}
1160
Philipp Maier87bd9be2017-08-22 16:35:41 +02001161DEFUN(loop_conn,
1162 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001163 "loop-endpoint <0-64> NAME (0|1)",
1164 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001165 "The name in hex of the endpoint\n" "Disable the loop\n"
1166 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001167{
Philipp Maier14b27a82020-06-02 20:15:30 +02001168 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001169 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001170 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001171
Philipp Maierd19de2e2020-06-03 13:55:33 +02001172 trunk = mgcp_trunk_by_num(g_cfg, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001173 if (!trunk) {
1174 vty_out(vty, "%%Trunk %d not found in the config.%s",
1175 atoi(argv[0]), VTY_NEWLINE);
1176 return CMD_WARNING;
1177 }
1178
1179 if (!trunk->endpoints) {
1180 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1181 trunk->trunk_nr, VTY_NEWLINE);
1182 return CMD_WARNING;
1183 }
1184
1185 int endp_no = strtoul(argv[1], NULL, 16);
1186 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1187 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001188 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001189 return CMD_WARNING;
1190 }
1191
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001192 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001193 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001194 llist_for_each_entry(conn, &endp->conns, entry) {
1195 if (conn->type == MGCP_CONN_TYPE_RTP)
1196 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1197 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1198 else {
1199 /* FIXME: Introduce support for other connection (E1)
1200 * types when implementation is available */
1201 vty_out(vty, "%%Can't enable SSRC patching,"
1202 "connection %s is not an RTP connection.%s",
1203 mgcp_conn_dump(conn), VTY_NEWLINE);
1204 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001205
Philipp Maier87bd9be2017-08-22 16:35:41 +02001206 if (loop)
1207 conn->mode = MGCP_CONN_LOOPBACK;
1208 else
1209 conn->mode = conn->mode_orig;
1210 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001211
1212 return CMD_SUCCESS;
1213}
1214
Philipp Maier87bd9be2017-08-22 16:35:41 +02001215DEFUN(tap_rtp,
1216 tap_rtp_cmd,
1217 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001218 "Forward data on endpoint to a different system\n" "Trunk number\n"
1219 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001220 "The connection id in hex\n"
1221 "Forward incoming data\n"
1222 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001223 "destination IP of the data\n" "destination port\n")
1224{
1225 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001226 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001227 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001228 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001229 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001230
Philipp Maierd19de2e2020-06-03 13:55:33 +02001231 trunk = mgcp_trunk_by_num(g_cfg, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001232 if (!trunk) {
1233 vty_out(vty, "%%Trunk %d not found in the config.%s",
1234 atoi(argv[0]), VTY_NEWLINE);
1235 return CMD_WARNING;
1236 }
1237
1238 if (!trunk->endpoints) {
1239 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1240 trunk->trunk_nr, VTY_NEWLINE);
1241 return CMD_WARNING;
1242 }
1243
1244 int endp_no = strtoul(argv[1], NULL, 16);
1245 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1246 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001247 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001248 return CMD_WARNING;
1249 }
1250
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001251 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001252
Philipp Maier01d24a32017-11-21 17:26:09 +01001253 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001254 conn = mgcp_conn_get_rtp(endp, conn_id);
1255 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001256 vty_out(vty, "Conn ID %s is invalid.%s",
1257 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001258 return CMD_WARNING;
1259 }
1260
1261 if (strcmp(argv[3], "in") == 0)
1262 tap = &conn->tap_in;
1263 else if (strcmp(argv[3], "out") == 0)
1264 tap = &conn->tap_out;
1265 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001266 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1267 return CMD_WARNING;
1268 }
1269
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001270 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001271 inet_aton(argv[4], &tap->forward.sin_addr);
1272 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001273 tap->enabled = 1;
1274 return CMD_SUCCESS;
1275}
1276
1277DEFUN(free_endp, free_endp_cmd,
1278 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001279 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001280{
Philipp Maier14b27a82020-06-02 20:15:30 +02001281 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001282 struct mgcp_endpoint *endp;
1283
Philipp Maierd19de2e2020-06-03 13:55:33 +02001284 trunk = mgcp_trunk_by_num(g_cfg, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001285 if (!trunk) {
1286 vty_out(vty, "%%Trunk %d not found in the config.%s",
1287 atoi(argv[0]), VTY_NEWLINE);
1288 return CMD_WARNING;
1289 }
1290
1291 if (!trunk->endpoints) {
1292 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1293 trunk->trunk_nr, VTY_NEWLINE);
1294 return CMD_WARNING;
1295 }
1296
1297 int endp_no = strtoul(argv[1], NULL, 16);
1298 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1299 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001300 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001301 return CMD_WARNING;
1302 }
1303
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001304 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001305 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001306 return CMD_SUCCESS;
1307}
1308
1309DEFUN(reset_endp, reset_endp_cmd,
1310 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001311 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001312{
Philipp Maier14b27a82020-06-02 20:15:30 +02001313 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001314 struct mgcp_endpoint *endp;
1315 int endp_no, rc;
1316
Philipp Maierd19de2e2020-06-03 13:55:33 +02001317 trunk = mgcp_trunk_by_num(g_cfg, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001318 if (!trunk) {
1319 vty_out(vty, "%%Trunk %d not found in the config.%s",
1320 atoi(argv[0]), VTY_NEWLINE);
1321 return CMD_WARNING;
1322 }
1323
1324 if (!trunk->endpoints) {
1325 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1326 trunk->trunk_nr, VTY_NEWLINE);
1327 return CMD_WARNING;
1328 }
1329
1330 endp_no = strtoul(argv[1], NULL, 16);
1331 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1332 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001333 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001334 return CMD_WARNING;
1335 }
1336
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001337 endp = trunk->endpoints[endp_no];
1338 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001339 if (rc < 0) {
1340 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1341 return CMD_WARNING;
1342 }
1343 return CMD_SUCCESS;
1344}
1345
1346DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001347 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001348{
1349 int rc;
1350
1351 rc = mgcp_send_reset_all(g_cfg);
1352 if (rc < 0) {
1353 vty_out(vty, "Error %d during endpoint reset.%s",
1354 rc, VTY_NEWLINE);
1355 return CMD_WARNING;
1356 }
1357 return CMD_SUCCESS;
1358}
1359
1360#define OSMUX_STR "RTP multiplexing\n"
1361DEFUN(cfg_mgcp_osmux,
1362 cfg_mgcp_osmux_cmd,
1363 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001364 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001365{
Philipp Maierd19de2e2020-06-03 13:55:33 +02001366 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_VIRT_TRUNK_ID);
1367 OSMO_ASSERT(trunk);
1368
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001369 if (strcmp(argv[0], "off") == 0) {
1370 g_cfg->osmux = OSMUX_USAGE_OFF;
1371 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001372 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001373 g_cfg->osmux = OSMUX_USAGE_ON;
1374 else if (strcmp(argv[0], "only") == 0)
1375 g_cfg->osmux = OSMUX_USAGE_ONLY;
1376
Philipp Maierd19de2e2020-06-03 13:55:33 +02001377 if (trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001378 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001379 return CMD_WARNING;
1380 }
1381
1382 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001383
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001384}
1385
1386DEFUN(cfg_mgcp_osmux_ip,
1387 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001388 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001389{
1390 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1391 return CMD_SUCCESS;
1392}
1393
1394DEFUN(cfg_mgcp_osmux_batch_factor,
1395 cfg_mgcp_osmux_batch_factor_cmd,
1396 "osmux batch-factor <1-8>",
1397 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1398{
1399 g_cfg->osmux_batch = atoi(argv[0]);
1400 return CMD_SUCCESS;
1401}
1402
1403DEFUN(cfg_mgcp_osmux_batch_size,
1404 cfg_mgcp_osmux_batch_size_cmd,
1405 "osmux batch-size <1-65535>",
1406 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1407{
1408 g_cfg->osmux_batch_size = atoi(argv[0]);
1409 return CMD_SUCCESS;
1410}
1411
1412DEFUN(cfg_mgcp_osmux_port,
1413 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001414 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001415{
1416 g_cfg->osmux_port = atoi(argv[0]);
1417 return CMD_SUCCESS;
1418}
1419
1420DEFUN(cfg_mgcp_osmux_dummy,
1421 cfg_mgcp_osmux_dummy_cmd,
1422 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001423 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1424 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001425{
1426 if (strcmp(argv[0], "on") == 0)
1427 g_cfg->osmux_dummy = 1;
1428 else if (strcmp(argv[0], "off") == 0)
1429 g_cfg->osmux_dummy = 0;
1430
1431 return CMD_SUCCESS;
1432}
1433
Philipp Maier12943ea2018-01-17 15:40:25 +01001434DEFUN(cfg_mgcp_domain,
1435 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001436 "domain NAME",
1437 "Set the domain part expected in MGCP messages' endpoint names\n"
1438 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001439{
1440 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1441 return CMD_SUCCESS;
1442}
1443
Oliver Smithe36b7752019-01-22 16:31:36 +01001444DEFUN(cfg_mgcp_conn_timeout,
1445 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001446 "conn-timeout <0-65534>",
1447 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1448 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001449 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1450 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001451 "Timeout value (sec.)\n")
1452{
1453 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1454 return CMD_SUCCESS;
1455}
1456
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001457int mgcp_vty_init(void)
1458{
1459 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001460 install_element_ve(&show_mgcp_endpoint_cmd);
1461 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001462 install_element(ENABLE_NODE, &loop_conn_cmd);
1463 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001464 install_element(ENABLE_NODE, &free_endp_cmd);
1465 install_element(ENABLE_NODE, &reset_endp_cmd);
1466 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1467
1468 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1469 install_node(&mgcp_node, config_write_mgcp);
1470
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001471 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001472 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1473 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1474 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001475 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001476 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001477 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001478 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001479 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001480 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001481 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1482 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001483 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1484 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1485 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1486 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1487 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1488 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1489 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1490 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1491 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001492 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1493 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1494 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1495 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1496 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1497 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001498 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001499 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1500 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1501 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1502 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1503 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1504 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1505 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1506 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001507 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1508 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001509 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1510 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1511 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1512 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1513 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1514 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1515 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1516 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1517 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1518 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1519 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1520 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1521 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001522 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001523 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001524
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001525 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1526 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001527 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1528 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1529 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1530 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1531 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1532 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1533 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1534 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1535 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1536 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1537 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1538 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1539 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001540 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1541 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001542 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1543 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1544 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1545 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1546 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1547 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1548 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1549 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1550 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1551
1552 return 0;
1553}
1554
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001555int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1556 enum mgcp_role role)
1557{
1558 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001559 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001560
1561 cfg->osmux_port = OSMUX_PORT;
1562 cfg->osmux_batch = 4;
1563 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1564
1565 g_cfg = cfg;
1566 rc = vty_read_config_file(config_file, NULL);
1567 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001568 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1569 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001570 return rc;
1571 }
1572
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001573 if (!g_cfg->source_addr) {
1574 fprintf(stderr, "You need to specify a bind address.\n");
1575 return -1;
1576 }
1577
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001578 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001579 if (mgcp_trunk_alloc_endpts(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001580 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001581 "Failed to initialize trunk %d (%d endpoints)\n",
1582 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001583 return -1;
1584 }
1585 }
1586 cfg->role = role;
1587
1588 return 0;
1589}