blob: b8ec2416adb4e6d12d63af8b31bdc4884fd747b7 [file] [log] [blame]
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
5 * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
6 * (C) 2009-2011 by On-Waves
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020024#include <osmocom/core/talloc.h>
Stefan Sperling1e174872018-10-25 18:36:10 +020025#include <osmocom/vty/misc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020026#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020027#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020028#include <osmocom/mgcp/mgcp_internal.h>
29#include <osmocom/mgcp/vty.h>
30#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010031#include <osmocom/mgcp/mgcp_endp.h>
Philipp Maierc66ab2c2020-06-02 20:55:34 +020032#include <osmocom/mgcp/mgcp_trunk.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020033
34#include <string.h>
Philipp Maierbca0ef62018-07-09 17:20:51 +020035#include <inttypes.h>
Stefan Sperling12086582018-06-26 15:26:28 +020036#include <limits.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020037
38#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
39#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
40#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
Philipp Maier9fc8a022019-02-20 12:26:52 +010041#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"
42
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020043
44static struct mgcp_config *g_cfg = NULL;
45
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020046struct cmd_node mgcp_node = {
47 MGCP_NODE,
48 "%s(config-mgcp)# ",
49 1,
50};
51
52struct cmd_node trunk_node = {
53 TRUNK_NODE,
54 "%s(config-mgcp-trunk)# ",
55 1,
56};
57
58static int config_write_mgcp(struct vty *vty)
59{
Philipp Maier6fbbeec2020-07-01 23:00:54 +020060 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +020061 OSMO_ASSERT(trunk);
Harald Weltec39b1bf2020-03-08 11:29:39 +010062
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020063 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020064 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020065 if (g_cfg->local_ip)
66 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020067 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
68 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
69 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020070 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
71 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020072 if (g_cfg->net_ports.bind_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +020073 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020074 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010075 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020076 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010077 else
Philipp Maierf53796c2020-06-02 20:38:28 +020078 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
79 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010080 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020081 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010082 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020083 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010084 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020085 else
Philipp Maierf53796c2020-06-02 20:38:28 +020086 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020087
Harald Weltec39b1bf2020-03-08 11:29:39 +010088 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +020089 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020090 else
Philipp Maierf53796c2020-06-02 20:38:28 +020091 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010092 if (trunk->force_constant_ssrc
93 || trunk->force_aligned_timing
94 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +020095 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010096 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +020097 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020098 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010099 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200100 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200101 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100102 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100103 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200104 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200105 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100106 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200107 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100108 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200109 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100110 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200111 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100112 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200113 vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
114 vty_out(vty, " number endpoints %u%s",
Philipp Maier889fe7f2020-07-06 17:44:12 +0200115 trunk->v.vty_number_endpoints, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200116 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100117 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200118 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200119 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200120 VTY_NEWLINE);
121 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200122 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200123 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200124
125 switch (g_cfg->osmux) {
126 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200127 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200128 break;
129 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200130 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200131 break;
132 case OSMUX_USAGE_OFF:
133 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200134 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200135 break;
136 }
137 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200138 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200139 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200140 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200141 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200142 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200143 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200144 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200145 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200146 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200147 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
148 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100149
150 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200151 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100152
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200153 return CMD_SUCCESS;
154}
155
Philipp Maiercede2a42018-07-03 14:14:21 +0200156static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200157{
Philipp Maiercede2a42018-07-03 14:14:21 +0200158 struct mgcp_rtp_state *state = &conn->state;
159 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200160 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100161 struct rate_ctr *tx_packets, *tx_bytes;
162 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200163 struct rate_ctr *dropped_packets;
164
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100165 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
166 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
167 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
168 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200169 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200170
171 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100172 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
173 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200174 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
175 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200176 " Payload Type: %d Rate: %u Channels: %d %s"
177 " Frame Duration: %u Frame Denominator: %u%s"
178 " FPP: %d Packet Duration: %u%s"
179 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
180 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100181 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
182 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200183 state->in_stream.err_ts_ctr->current,
184 state->out_stream.err_ts_ctr->current,
185 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200186 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200187 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200188 codec->frame_duration_num, codec->frame_duration_den,
189 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
190 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
191 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
192 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200193}
194
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200195static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200196 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200197{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200198 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200199
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200200 vty_out(vty, "%s trunk %d endpoint %s:%s",
201 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Philipp Maier8d6a1932020-06-18 12:19:31 +0200202 vty_out(vty, " Availability: %s%s",
203 mgcp_endp_avail(endp) ? "available" : "not in service", VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200204
205 if (llist_empty(&endp->conns)) {
206 vty_out(vty, " No active connections%s", VTY_NEWLINE);
207 return;
208 }
209
210 llist_for_each_entry(conn, &endp->conns, entry) {
211 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
212
213 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100214 if (endp->cfg->conn_timeout) {
215 struct timeval remaining;
216 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
217 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
218 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
219 }
220
Stefan Sperling12086582018-06-26 15:26:28 +0200221 /* FIXME: Also add verbosity for other
222 * connection types (E1) as soon as
223 * the implementation is available */
224 if (conn->type == MGCP_CONN_TYPE_RTP) {
225 dump_rtp_end(vty, &conn->u.rtp);
226 }
227 }
228 }
229}
230
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200231static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
232{
233 vty_out(vty, "%s", VTY_NEWLINE);
234 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
235
236 if (ratectr->mgcp_general_ctr_group) {
237 vty_out(vty, " %s:%s",
238 ratectr->mgcp_general_ctr_group->desc->
239 group_description, VTY_NEWLINE);
240 vty_out_rate_ctr_group_fmt(vty,
241 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
242 ratectr->mgcp_general_ctr_group);
243 }
244}
245
Philipp Maier889fe7f2020-07-06 17:44:12 +0200246static void dump_ratectr_trunk(struct vty *vty, struct mgcp_trunk *trunk)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200247{
Philipp Maier889fe7f2020-07-06 17:44:12 +0200248 struct mgcp_ratectr_trunk *ratectr = &trunk->ratectr;
249
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200250 vty_out(vty, "%s", VTY_NEWLINE);
251 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
252
253 if (ratectr->mgcp_crcx_ctr_group) {
254 vty_out(vty, " %s:%s",
255 ratectr->mgcp_crcx_ctr_group->desc->group_description,
256 VTY_NEWLINE);
257 vty_out_rate_ctr_group_fmt(vty,
258 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
259 ratectr->mgcp_crcx_ctr_group);
260 }
261 if (ratectr->mgcp_dlcx_ctr_group) {
262 vty_out(vty, " %s:%s",
263 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
264 VTY_NEWLINE);
265 vty_out_rate_ctr_group_fmt(vty,
266 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
267 ratectr->mgcp_dlcx_ctr_group);
268 }
269 if (ratectr->mgcp_mdcx_ctr_group) {
270 vty_out(vty, " %s:%s",
271 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
272 VTY_NEWLINE);
273 vty_out_rate_ctr_group_fmt(vty,
274 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
275 ratectr->mgcp_mdcx_ctr_group);
276 }
277 if (ratectr->all_rtp_conn_stats) {
278 vty_out(vty, " %s:%s",
279 ratectr->all_rtp_conn_stats->desc->group_description,
280 VTY_NEWLINE);
281 vty_out_rate_ctr_group_fmt(vty,
282 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
283 ratectr->all_rtp_conn_stats);
284 }
Philipp Maier889fe7f2020-07-06 17:44:12 +0200285
286 if (ratectr->e1_stats && trunk->trunk_type == MGCP_TRUNK_E1) {
287 vty_out(vty, " %s:%s",
288 ratectr->e1_stats->desc->group_description,
289 VTY_NEWLINE);
290 vty_out_rate_ctr_group_fmt(vty,
291 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
292 ratectr->e1_stats);
293 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200294}
295
296
297static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200298{
299 int i;
300
301 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200302 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
Philipp Maier869b21c2020-07-03 16:04:16 +0200303 trunk->trunk_nr, trunk->number_endpoints, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200304
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200305 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200306 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
307 return;
308 }
309
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200310 for (i = 0; i < trunk->number_endpoints; ++i) {
311 struct mgcp_endpoint *endp = trunk->endpoints[i];
312 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
313 show_stats);
314 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200315 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200316 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200317
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200318 if (show_stats)
Philipp Maier889fe7f2020-07-06 17:44:12 +0200319 dump_ratectr_trunk(vty, trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200320}
321
Stefan Sperling12086582018-06-26 15:26:28 +0200322#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
323
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200324DEFUN(show_mcgp, show_mgcp_cmd,
325 "show mgcp [stats]",
326 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200327 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200328 "Include Statistics\n")
329{
Philipp Maier14b27a82020-06-02 20:15:30 +0200330 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200331 int show_stats = argc >= 1;
332
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200333 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200334 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200335
336 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200337 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200338 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200339
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200340 if (show_stats)
341 dump_ratectr_global(vty, &g_cfg->ratectr);
342
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200343 return CMD_SUCCESS;
344}
345
Stefan Sperling12086582018-06-26 15:26:28 +0200346static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200347dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200348{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200349 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200350
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200351 if (trunk) {
352 /* If a trunk is given, search on that specific trunk only */
353 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
354 if (!endp) {
355 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
356 return;
357 }
358 } else {
359 /* If no trunk is given, search on all possible trunks */
360 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
361 if (!endp) {
362 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
363 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200364 }
365 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200366
367 trunk = endp->trunk;
368 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200369}
370
371DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
372 "show mgcp endpoint NAME",
373 SHOW_STR
374 SHOW_MGCP_STR
375 "Display information about an endpoint\n" "The name of the endpoint\n")
376{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200377 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200378 return CMD_SUCCESS;
379}
380
381DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
382 "show mgcp trunk <0-64> endpoint NAME",
383 SHOW_STR
384 SHOW_MGCP_STR
385 "Display information about a trunk\n" "Trunk number\n"
386 "Display information about an endpoint\n" "The name of the endpoint\n")
387{
Philipp Maier14b27a82020-06-02 20:15:30 +0200388 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200389 int trunkidx = atoi(argv[0]);
390
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200391 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200392 if (!trunk) {
393 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
394 return CMD_WARNING;
395 }
396
397 dump_mgcp_endpoint(vty, trunk, argv[1]);
398 return CMD_SUCCESS;
399}
400
Philipp Maier87bd9be2017-08-22 16:35:41 +0200401DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200402{
403 vty->node = MGCP_NODE;
404 return CMD_SUCCESS;
405}
406
407DEFUN(cfg_mgcp_local_ip,
408 cfg_mgcp_local_ip_cmd,
409 "local ip A.B.C.D",
410 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200411 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200412{
413 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
414 return CMD_SUCCESS;
415}
416
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200417#define BIND_STR "Listen/Bind related socket option\n"
418DEFUN(cfg_mgcp_bind_ip,
419 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200420 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200421{
422 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
423 return CMD_SUCCESS;
424}
425
426DEFUN(cfg_mgcp_bind_port,
427 cfg_mgcp_bind_port_cmd,
428 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200429 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200430{
431 unsigned int port = atoi(argv[0]);
432 g_cfg->source_port = port;
433 return CMD_SUCCESS;
434}
435
436DEFUN(cfg_mgcp_bind_early,
437 cfg_mgcp_bind_early_cmd,
438 "bind early (0|1)",
439 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200440 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200441{
442 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
443 return CMD_WARNING;
444}
445
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200446#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200447#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200448#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200449#define RANGE_START_STR "Start of the range of ports\n"
450#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200451
Philipp Maierf1889d82017-11-08 14:59:39 +0100452DEFUN(cfg_mgcp_rtp_port_range,
453 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200454 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200455 RTP_STR "Range of ports to use for the NET side\n"
456 RANGE_START_STR RANGE_END_STR)
457{
Philipp Maiera19547b2018-05-22 13:44:34 +0200458 int start;
459 int end;
460
461 start = atoi(argv[0]);
462 end = atoi(argv[1]);
463
464 if (end < start) {
465 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
466 end, start, VTY_NEWLINE);
467 return CMD_WARNING;
468 }
469
470 if (start & 1) {
471 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
472 start, start & 0xFFFE, VTY_NEWLINE);
473 start &= 0xFFFE;
474 }
475
476 if ((end & 1) == 0) {
477 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
478 end, end | 1, VTY_NEWLINE);
479 end |= 1;
480 }
481
482 g_cfg->net_ports.range_start = start;
483 g_cfg->net_ports.range_end = end;
484 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
485
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200486 return CMD_SUCCESS;
487}
Philipp Maierf1889d82017-11-08 14:59:39 +0100488ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
489 cfg_mgcp_rtp_net_range_cmd,
490 "rtp net-range <0-65534> <0-65534>",
491 RTP_STR "Range of ports to use for the NET side\n"
492 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200493
Philipp Maierf1889d82017-11-08 14:59:39 +0100494DEFUN(cfg_mgcp_rtp_bind_ip,
495 cfg_mgcp_rtp_bind_ip_cmd,
496 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200497 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
498{
499 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
500 return CMD_SUCCESS;
501}
Philipp Maierf1889d82017-11-08 14:59:39 +0100502ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
503 cfg_mgcp_rtp_net_bind_ip_cmd,
504 "rtp net-bind-ip A.B.C.D",
505 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200506
Philipp Maierf1889d82017-11-08 14:59:39 +0100507DEFUN(cfg_mgcp_rtp_no_bind_ip,
508 cfg_mgcp_rtp_no_bind_ip_cmd,
509 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200510 NO_STR RTP_STR "Bind endpoints facing the Network\n"
511 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200512{
513 talloc_free(g_cfg->net_ports.bind_addr);
514 g_cfg->net_ports.bind_addr = NULL;
515 return CMD_SUCCESS;
516}
Philipp Maierf1889d82017-11-08 14:59:39 +0100517ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
518 cfg_mgcp_rtp_no_net_bind_ip_cmd,
519 "no rtp net-bind-ip",
520 NO_STR RTP_STR "Bind endpoints facing the Network\n"
521 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200522
Philipp Maier1cb1e382017-11-02 17:16:04 +0100523DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
524 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
525 "rtp ip-probing",
526 RTP_STR "automatic rtp bind ip selection\n")
527{
528 g_cfg->net_ports.bind_addr_probe = true;
529 return CMD_SUCCESS;
530}
531
532DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
533 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
534 "no rtp ip-probing",
535 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
536{
537 g_cfg->net_ports.bind_addr_probe = false;
538 return CMD_SUCCESS;
539}
540
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200541DEFUN(cfg_mgcp_rtp_ip_dscp,
542 cfg_mgcp_rtp_ip_dscp_cmd,
543 "rtp ip-dscp <0-255>",
544 RTP_STR
545 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
546{
547 int dscp = atoi(argv[0]);
548 g_cfg->endp_dscp = dscp;
549 return CMD_SUCCESS;
550}
551
552ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200553 "rtp ip-tos <0-255>",
554 RTP_STR
555 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
556#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200557DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200558 cfg_mgcp_rtp_force_ptime_cmd,
559 "rtp force-ptime (10|20|40)",
560 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200561 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200562{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200563 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200564 return CMD_SUCCESS;
565}
566
567DEFUN(cfg_mgcp_no_rtp_force_ptime,
568 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200569 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200570{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200571 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200572 return CMD_SUCCESS;
573}
574
575DEFUN(cfg_mgcp_sdp_fmtp_extra,
576 cfg_mgcp_sdp_fmtp_extra_cmd,
577 "sdp audio fmtp-extra .NAME",
578 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
579 "Extra Information\n")
580{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200581 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200582 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200583 char *txt = argv_concat(argv, argc, 0);
584 if (!txt)
585 return CMD_WARNING;
586
Philipp Maierd19de2e2020-06-03 13:55:33 +0200587 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200588 talloc_free(txt);
589 return CMD_SUCCESS;
590}
591
592DEFUN(cfg_mgcp_allow_transcoding,
593 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200594 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200595{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200596 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200597 OSMO_ASSERT(trunk);
598 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200599 return CMD_SUCCESS;
600}
601
602DEFUN(cfg_mgcp_no_allow_transcoding,
603 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200604 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200605{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200606 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200607 OSMO_ASSERT(trunk);
608 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200609 return CMD_SUCCESS;
610}
611
612#define SDP_STR "SDP File related options\n"
613#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200614DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200615 cfg_mgcp_sdp_payload_number_cmd,
616 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200617 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200618{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200619 return CMD_SUCCESS;
620}
621
Philipp Maier87bd9be2017-08-22 16:35:41 +0200622ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
623 cfg_mgcp_sdp_payload_number_cmd_old,
624 "sdp audio payload number <0-255>",
625 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200626
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200627DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200628 cfg_mgcp_sdp_payload_name_cmd,
629 "sdp audio-payload name NAME",
630 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
631{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200632 return CMD_SUCCESS;
633}
634
635ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200636 "sdp audio payload name NAME",
637 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200638
Philipp Maier21be42a2020-05-29 21:39:48 +0200639DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200640 cfg_mgcp_sdp_payload_send_ptime_cmd,
641 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200642 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200643{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200644 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200645 OSMO_ASSERT(trunk);
646 trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200647 return CMD_SUCCESS;
648}
649
650DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
651 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
652 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200653 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200654{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200655 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200656 OSMO_ASSERT(trunk);
657 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200658 return CMD_SUCCESS;
659}
660
661DEFUN(cfg_mgcp_sdp_payload_send_name,
662 cfg_mgcp_sdp_payload_send_name_cmd,
663 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200664 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200665{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200666 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200667 OSMO_ASSERT(trunk);
668 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200669 return CMD_SUCCESS;
670}
671
672DEFUN(cfg_mgcp_no_sdp_payload_send_name,
673 cfg_mgcp_no_sdp_payload_send_name_cmd,
674 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200675 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200676{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200677 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200678 OSMO_ASSERT(trunk);
679 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200680 return CMD_SUCCESS;
681}
682
683DEFUN(cfg_mgcp_loop,
684 cfg_mgcp_loop_cmd,
685 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200686 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200687{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200688 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200689 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200690 if (g_cfg->osmux) {
691 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
692 return CMD_WARNING;
693 }
Philipp Maierd19de2e2020-06-03 13:55:33 +0200694 trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200695 return CMD_SUCCESS;
696}
697
698DEFUN(cfg_mgcp_force_realloc,
699 cfg_mgcp_force_realloc_cmd,
700 "force-realloc (0|1)",
701 "Force endpoint reallocation when the endpoint is still seized\n"
702 "Don't force reallocation\n" "force reallocation\n")
703{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200704 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200705 OSMO_ASSERT(trunk);
706 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200707 return CMD_SUCCESS;
708}
709
Philipp Maier87bd9be2017-08-22 16:35:41 +0200710DEFUN(cfg_mgcp_rtp_accept_all,
711 cfg_mgcp_rtp_accept_all_cmd,
712 "rtp-accept-all (0|1)",
713 "Accept all RTP packets, even when the originating IP/Port does not match\n"
714 "enable filter\n" "disable filter\n")
715{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200716 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200717 OSMO_ASSERT(trunk);
718 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200719 return CMD_SUCCESS;
720}
721
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200722DEFUN(cfg_mgcp_number_endp,
723 cfg_mgcp_number_endp_cmd,
Philipp Maier869b21c2020-07-03 16:04:16 +0200724 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200725 "Number options\n" "Endpoints available\n" "Number endpoints\n")
726{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200727 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200728 OSMO_ASSERT(trunk);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200729 trunk->v.vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730 return CMD_SUCCESS;
731}
732
Philipp Maier87bd9be2017-08-22 16:35:41 +0200733DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200734{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200735 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200736 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200737 return CMD_SUCCESS;
738}
739
740DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200741 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200742{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200743 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200744 OSMO_ASSERT(trunk);
745 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200746 return CMD_SUCCESS;
747}
748
749DEFUN(cfg_mgcp_patch_rtp_ssrc,
750 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200751 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200752{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200753 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200754 OSMO_ASSERT(trunk);
755 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200756 return CMD_SUCCESS;
757}
758
759DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
760 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200761 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200762{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200763 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200764 OSMO_ASSERT(trunk);
765 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200766 return CMD_SUCCESS;
767}
768
769DEFUN(cfg_mgcp_patch_rtp_ts,
770 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200771 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200772{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200773 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200774 OSMO_ASSERT(trunk);
775 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200776 return CMD_SUCCESS;
777}
778
779DEFUN(cfg_mgcp_no_patch_rtp_ts,
780 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200781 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200782{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200783 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200784 OSMO_ASSERT(trunk);
785 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200786 return CMD_SUCCESS;
787}
788
Philipp Maier9fc8a022019-02-20 12:26:52 +0100789DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
790 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
791 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
792{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200793 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200794 OSMO_ASSERT(trunk);
795 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100796 return CMD_SUCCESS;
797}
798
799DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
800 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
801 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
802{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200803 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200804 OSMO_ASSERT(trunk);
805 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100806 return CMD_SUCCESS;
807}
808
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200809DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200810 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200811{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200812 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200813 OSMO_ASSERT(trunk);
814 trunk->force_constant_ssrc = 0;
815 trunk->force_aligned_timing = 0;
816 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200817 return CMD_SUCCESS;
818}
819
820DEFUN(cfg_mgcp_rtp_keepalive,
821 cfg_mgcp_rtp_keepalive_cmd,
822 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200823 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200824{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200825 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200826 OSMO_ASSERT(trunk);
827 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200828 return CMD_SUCCESS;
829}
830
831DEFUN(cfg_mgcp_rtp_keepalive_once,
832 cfg_mgcp_rtp_keepalive_once_cmd,
833 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200834 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200835{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200836 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200837 OSMO_ASSERT(trunk);
838 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200839 return CMD_SUCCESS;
840}
841
842DEFUN(cfg_mgcp_no_rtp_keepalive,
843 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200844 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200845{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200846 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200847 OSMO_ASSERT(trunk);
848 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200849 return CMD_SUCCESS;
850}
851
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200852#define CALL_AGENT_STR "Callagent information\n"
853DEFUN(cfg_mgcp_agent_addr,
854 cfg_mgcp_agent_addr_cmd,
855 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200856 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200857{
858 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
859 return CMD_SUCCESS;
860}
861
862ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200863 "call agent ip A.B.C.D",
864 CALL_AGENT_STR CALL_AGENT_STR IP_STR
865 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200866
Philipp Maier21be42a2020-05-29 21:39:48 +0200867DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200868 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200869{
Philipp Maier14b27a82020-06-02 20:15:30 +0200870 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200871 int index = atoi(argv[0]);
872
Philipp Maierd19de2e2020-06-03 13:55:33 +0200873 /* Due to historical reasons, the trunk id number 0 is reserved for the
874 * virtual trunk. This trunk is configured with separate VTY
875 * parameters, so we restrict the access to trunks with id numbers
876 * greater than 0. */
877
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200878 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100879 if (!trunk) {
880 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200881 if (!trunk) {
882 vty_out(vty, "%%Unable to allocate trunk %u.%s",
883 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100884 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200885 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200886 }
887
888 vty->node = TRUNK_NODE;
889 vty->index = trunk;
890 return CMD_SUCCESS;
891}
892
893static int config_write_trunk(struct vty *vty)
894{
Philipp Maier14b27a82020-06-02 20:15:30 +0200895 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200896
897 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200898
899 /* Due to historical reasons, the virtual trunk is configured
900 using separate VTY parameters, so we omit writing the trunk
901 config of trunk 0 here. The configuration for the virtual
902 trunk is written by config_write_mgcp(). */
903
904 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
905 continue;
906
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200907 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200908 vty_out(vty, " line %u%s", trunk->e1.vty_line_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200909 vty_out(vty, " %ssdp audio-payload send-ptime%s",
910 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
911 vty_out(vty, " %ssdp audio-payload send-name%s",
912 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
913
914 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
915 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
916 else if (trunk->keepalive_interval)
917 vty_out(vty, " rtp keep-alive %d%s",
918 trunk->keepalive_interval, VTY_NEWLINE);
919 else
920 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200921 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200922 vty_out(vty, " force-realloc %d%s",
923 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200924 vty_out(vty, " rtp-accept-all %d%s",
925 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200926 if (trunk->omit_rtcp)
927 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
928 else
929 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100930 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200931 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200932 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200933 trunk->force_constant_ssrc ? "" : "no ",
934 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200935 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200936 trunk->force_aligned_timing ? "" : "no ",
937 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100938 vty_out(vty, " %srtp-patch rfc5993hr%s",
939 trunk->rfc5993_hr_convert ? "" : "no ",
940 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200941 } else
942 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
943 if (trunk->audio_fmtp_extra)
944 vty_out(vty, " sdp audio fmtp-extra %s%s",
945 trunk->audio_fmtp_extra, VTY_NEWLINE);
946 vty_out(vty, " %sallow-transcoding%s",
947 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
948 }
949
950 return CMD_SUCCESS;
951}
952
953DEFUN(cfg_trunk_sdp_fmtp_extra,
954 cfg_trunk_sdp_fmtp_extra_cmd,
955 "sdp audio fmtp-extra .NAME",
956 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
957 "Extra Information\n")
958{
Philipp Maier14b27a82020-06-02 20:15:30 +0200959 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200960 char *txt = argv_concat(argv, argc, 0);
961 if (!txt)
962 return CMD_WARNING;
963
964 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
965 talloc_free(txt);
966 return CMD_SUCCESS;
967}
968
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200969DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200970 cfg_trunk_payload_number_cmd,
971 "sdp audio-payload number <0-255>",
972 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
973{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200974 return CMD_SUCCESS;
975}
976
977ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200978 "sdp audio payload number <0-255>",
979 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200980
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200981DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200982 cfg_trunk_payload_name_cmd,
983 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200984 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200985{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200986 return CMD_SUCCESS;
987}
988
989ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200990 "sdp audio payload name NAME",
991 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200992
Philipp Maier21be42a2020-05-29 21:39:48 +0200993DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200994 cfg_trunk_loop_cmd,
995 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200996 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200997{
Philipp Maier14b27a82020-06-02 20:15:30 +0200998 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200999
1000 if (g_cfg->osmux) {
1001 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
1002 return CMD_WARNING;
1003 }
1004 trunk->audio_loop = atoi(argv[0]);
1005 return CMD_SUCCESS;
1006}
1007
1008DEFUN(cfg_trunk_sdp_payload_send_ptime,
1009 cfg_trunk_sdp_payload_send_ptime_cmd,
1010 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001011 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001012{
Philipp Maier14b27a82020-06-02 20:15:30 +02001013 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001014 trunk->audio_send_ptime = 1;
1015 return CMD_SUCCESS;
1016}
1017
1018DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1019 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1020 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001021 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001022{
Philipp Maier14b27a82020-06-02 20:15:30 +02001023 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001024 trunk->audio_send_ptime = 0;
1025 return CMD_SUCCESS;
1026}
1027
1028DEFUN(cfg_trunk_sdp_payload_send_name,
1029 cfg_trunk_sdp_payload_send_name_cmd,
1030 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001031 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001032{
Philipp Maier14b27a82020-06-02 20:15:30 +02001033 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001034 trunk->audio_send_name = 1;
1035 return CMD_SUCCESS;
1036}
1037
1038DEFUN(cfg_trunk_no_sdp_payload_send_name,
1039 cfg_trunk_no_sdp_payload_send_name_cmd,
1040 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001041 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001042{
Philipp Maier14b27a82020-06-02 20:15:30 +02001043 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001044 trunk->audio_send_name = 0;
1045 return CMD_SUCCESS;
1046}
1047
Philipp Maier87bd9be2017-08-22 16:35:41 +02001048DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001049{
Philipp Maier14b27a82020-06-02 20:15:30 +02001050 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001051 trunk->omit_rtcp = 1;
1052 return CMD_SUCCESS;
1053}
1054
1055DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001056 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001057{
Philipp Maier14b27a82020-06-02 20:15:30 +02001058 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001059 trunk->omit_rtcp = 0;
1060 return CMD_SUCCESS;
1061}
1062
1063DEFUN(cfg_trunk_patch_rtp_ssrc,
1064 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001065 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001066{
Philipp Maier14b27a82020-06-02 20:15:30 +02001067 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001068 trunk->force_constant_ssrc = 1;
1069 return CMD_SUCCESS;
1070}
1071
1072DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1073 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001074 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001075{
Philipp Maier14b27a82020-06-02 20:15:30 +02001076 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001077 trunk->force_constant_ssrc = 0;
1078 return CMD_SUCCESS;
1079}
1080
1081DEFUN(cfg_trunk_patch_rtp_ts,
1082 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001083 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001084{
Philipp Maier14b27a82020-06-02 20:15:30 +02001085 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001086 trunk->force_aligned_timing = 1;
1087 return CMD_SUCCESS;
1088}
1089
1090DEFUN(cfg_trunk_no_patch_rtp_ts,
1091 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001092 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001093{
Philipp Maier14b27a82020-06-02 20:15:30 +02001094 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001095 trunk->force_aligned_timing = 0;
1096 return CMD_SUCCESS;
1097}
1098
Philipp Maier9fc8a022019-02-20 12:26:52 +01001099DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1100 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1101 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1102{
Philipp Maier14b27a82020-06-02 20:15:30 +02001103 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001104 trunk->rfc5993_hr_convert = true;
1105 return CMD_SUCCESS;
1106}
1107
1108DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1109 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1110 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1111{
Philipp Maier14b27a82020-06-02 20:15:30 +02001112 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001113 trunk->rfc5993_hr_convert = false;
1114 return CMD_SUCCESS;
1115}
1116
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001117DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001118 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001119{
Philipp Maier14b27a82020-06-02 20:15:30 +02001120 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001121 trunk->force_constant_ssrc = 0;
1122 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001123 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001124 return CMD_SUCCESS;
1125}
1126
1127DEFUN(cfg_trunk_rtp_keepalive,
1128 cfg_trunk_rtp_keepalive_cmd,
1129 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001130 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001131{
Philipp Maier14b27a82020-06-02 20:15:30 +02001132 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001133 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1134 return CMD_SUCCESS;
1135}
1136
1137DEFUN(cfg_trunk_rtp_keepalive_once,
1138 cfg_trunk_rtp_keepalive_once_cmd,
1139 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001140 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001141{
Philipp Maier14b27a82020-06-02 20:15:30 +02001142 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001143 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1144 return CMD_SUCCESS;
1145}
1146
1147DEFUN(cfg_trunk_no_rtp_keepalive,
1148 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001149 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001150{
Philipp Maier14b27a82020-06-02 20:15:30 +02001151 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001152 mgcp_trunk_set_keepalive(trunk, 0);
1153 return CMD_SUCCESS;
1154}
1155
1156DEFUN(cfg_trunk_allow_transcoding,
1157 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001158 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001159{
Philipp Maier14b27a82020-06-02 20:15:30 +02001160 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001161 trunk->no_audio_transcoding = 0;
1162 return CMD_SUCCESS;
1163}
1164
1165DEFUN(cfg_trunk_no_allow_transcoding,
1166 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001167 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001168{
Philipp Maier14b27a82020-06-02 20:15:30 +02001169 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001170 trunk->no_audio_transcoding = 1;
1171 return CMD_SUCCESS;
1172}
1173
Philipp Maier889fe7f2020-07-06 17:44:12 +02001174#define LINE_STR "Configure trunk for given Line\nE1/T1 Line Number\n"
1175
1176DEFUN(cfg_trunk_line,
1177 cfg_trunk_line_cmd,
1178 "line <0-255>",
1179 LINE_STR)
1180{
1181 struct mgcp_trunk *trunk = vty->index;
1182 int line_nr = atoi(argv[0]);
1183 trunk->e1.vty_line_nr = line_nr;
1184 return CMD_SUCCESS;
1185}
1186
Philipp Maier87bd9be2017-08-22 16:35:41 +02001187DEFUN(loop_conn,
1188 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001189 "loop-endpoint <0-64> NAME (0|1)",
1190 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001191 "The name in hex of the endpoint\n" "Disable the loop\n"
1192 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001193{
Philipp Maier14b27a82020-06-02 20:15:30 +02001194 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001195 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001196 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001197
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001198 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001199 if (!trunk) {
1200 vty_out(vty, "%%Trunk %d not found in the config.%s",
1201 atoi(argv[0]), VTY_NEWLINE);
1202 return CMD_WARNING;
1203 }
1204
1205 if (!trunk->endpoints) {
1206 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1207 trunk->trunk_nr, VTY_NEWLINE);
1208 return CMD_WARNING;
1209 }
1210
1211 int endp_no = strtoul(argv[1], NULL, 16);
1212 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1213 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001214 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001215 return CMD_WARNING;
1216 }
1217
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001218 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001219 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001220 llist_for_each_entry(conn, &endp->conns, entry) {
1221 if (conn->type == MGCP_CONN_TYPE_RTP)
1222 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1223 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1224 else {
1225 /* FIXME: Introduce support for other connection (E1)
1226 * types when implementation is available */
1227 vty_out(vty, "%%Can't enable SSRC patching,"
1228 "connection %s is not an RTP connection.%s",
1229 mgcp_conn_dump(conn), VTY_NEWLINE);
1230 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001231
Philipp Maier87bd9be2017-08-22 16:35:41 +02001232 if (loop)
1233 conn->mode = MGCP_CONN_LOOPBACK;
1234 else
1235 conn->mode = conn->mode_orig;
1236 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001237
1238 return CMD_SUCCESS;
1239}
1240
Philipp Maier87bd9be2017-08-22 16:35:41 +02001241DEFUN(tap_rtp,
1242 tap_rtp_cmd,
1243 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001244 "Forward data on endpoint to a different system\n" "Trunk number\n"
1245 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001246 "The connection id in hex\n"
1247 "Forward incoming data\n"
1248 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001249 "destination IP of the data\n" "destination port\n")
1250{
1251 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001252 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001253 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001254 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001255 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001256
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001257 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001258 if (!trunk) {
1259 vty_out(vty, "%%Trunk %d not found in the config.%s",
1260 atoi(argv[0]), VTY_NEWLINE);
1261 return CMD_WARNING;
1262 }
1263
1264 if (!trunk->endpoints) {
1265 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1266 trunk->trunk_nr, VTY_NEWLINE);
1267 return CMD_WARNING;
1268 }
1269
1270 int endp_no = strtoul(argv[1], NULL, 16);
1271 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1272 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001273 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001274 return CMD_WARNING;
1275 }
1276
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001277 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001278
Philipp Maier01d24a32017-11-21 17:26:09 +01001279 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001280 conn = mgcp_conn_get_rtp(endp, conn_id);
1281 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001282 vty_out(vty, "Conn ID %s is invalid.%s",
1283 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001284 return CMD_WARNING;
1285 }
1286
1287 if (strcmp(argv[3], "in") == 0)
1288 tap = &conn->tap_in;
1289 else if (strcmp(argv[3], "out") == 0)
1290 tap = &conn->tap_out;
1291 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001292 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1293 return CMD_WARNING;
1294 }
1295
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001296 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001297 inet_aton(argv[4], &tap->forward.sin_addr);
1298 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001299 tap->enabled = 1;
1300 return CMD_SUCCESS;
1301}
1302
1303DEFUN(free_endp, free_endp_cmd,
1304 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001305 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001306{
Philipp Maier14b27a82020-06-02 20:15:30 +02001307 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001308 struct mgcp_endpoint *endp;
1309
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001310 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001311 if (!trunk) {
1312 vty_out(vty, "%%Trunk %d not found in the config.%s",
1313 atoi(argv[0]), VTY_NEWLINE);
1314 return CMD_WARNING;
1315 }
1316
1317 if (!trunk->endpoints) {
1318 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1319 trunk->trunk_nr, VTY_NEWLINE);
1320 return CMD_WARNING;
1321 }
1322
1323 int endp_no = strtoul(argv[1], NULL, 16);
1324 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1325 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001326 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001327 return CMD_WARNING;
1328 }
1329
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001330 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001331 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001332 return CMD_SUCCESS;
1333}
1334
1335DEFUN(reset_endp, reset_endp_cmd,
1336 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001337 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001338{
Philipp Maier14b27a82020-06-02 20:15:30 +02001339 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001340 struct mgcp_endpoint *endp;
1341 int endp_no, rc;
1342
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001343 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001344 if (!trunk) {
1345 vty_out(vty, "%%Trunk %d not found in the config.%s",
1346 atoi(argv[0]), VTY_NEWLINE);
1347 return CMD_WARNING;
1348 }
1349
1350 if (!trunk->endpoints) {
1351 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1352 trunk->trunk_nr, VTY_NEWLINE);
1353 return CMD_WARNING;
1354 }
1355
1356 endp_no = strtoul(argv[1], NULL, 16);
1357 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1358 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001359 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001360 return CMD_WARNING;
1361 }
1362
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001363 endp = trunk->endpoints[endp_no];
1364 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001365 if (rc < 0) {
1366 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1367 return CMD_WARNING;
1368 }
1369 return CMD_SUCCESS;
1370}
1371
1372DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001373 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001374{
1375 int rc;
1376
1377 rc = mgcp_send_reset_all(g_cfg);
1378 if (rc < 0) {
1379 vty_out(vty, "Error %d during endpoint reset.%s",
1380 rc, VTY_NEWLINE);
1381 return CMD_WARNING;
1382 }
1383 return CMD_SUCCESS;
1384}
1385
1386#define OSMUX_STR "RTP multiplexing\n"
1387DEFUN(cfg_mgcp_osmux,
1388 cfg_mgcp_osmux_cmd,
1389 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001390 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001391{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001392 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001393 OSMO_ASSERT(trunk);
1394
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001395 if (strcmp(argv[0], "off") == 0) {
1396 g_cfg->osmux = OSMUX_USAGE_OFF;
1397 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001398 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001399 g_cfg->osmux = OSMUX_USAGE_ON;
1400 else if (strcmp(argv[0], "only") == 0)
1401 g_cfg->osmux = OSMUX_USAGE_ONLY;
1402
Philipp Maierd19de2e2020-06-03 13:55:33 +02001403 if (trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001404 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001405 return CMD_WARNING;
1406 }
1407
1408 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001409
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001410}
1411
1412DEFUN(cfg_mgcp_osmux_ip,
1413 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001414 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001415{
1416 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1417 return CMD_SUCCESS;
1418}
1419
1420DEFUN(cfg_mgcp_osmux_batch_factor,
1421 cfg_mgcp_osmux_batch_factor_cmd,
1422 "osmux batch-factor <1-8>",
1423 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1424{
1425 g_cfg->osmux_batch = atoi(argv[0]);
1426 return CMD_SUCCESS;
1427}
1428
1429DEFUN(cfg_mgcp_osmux_batch_size,
1430 cfg_mgcp_osmux_batch_size_cmd,
1431 "osmux batch-size <1-65535>",
1432 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1433{
1434 g_cfg->osmux_batch_size = atoi(argv[0]);
1435 return CMD_SUCCESS;
1436}
1437
1438DEFUN(cfg_mgcp_osmux_port,
1439 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001440 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001441{
1442 g_cfg->osmux_port = atoi(argv[0]);
1443 return CMD_SUCCESS;
1444}
1445
1446DEFUN(cfg_mgcp_osmux_dummy,
1447 cfg_mgcp_osmux_dummy_cmd,
1448 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001449 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1450 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001451{
1452 if (strcmp(argv[0], "on") == 0)
1453 g_cfg->osmux_dummy = 1;
1454 else if (strcmp(argv[0], "off") == 0)
1455 g_cfg->osmux_dummy = 0;
1456
1457 return CMD_SUCCESS;
1458}
1459
Philipp Maier12943ea2018-01-17 15:40:25 +01001460DEFUN(cfg_mgcp_domain,
1461 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001462 "domain NAME",
1463 "Set the domain part expected in MGCP messages' endpoint names\n"
1464 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001465{
1466 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1467 return CMD_SUCCESS;
1468}
1469
Oliver Smithe36b7752019-01-22 16:31:36 +01001470DEFUN(cfg_mgcp_conn_timeout,
1471 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001472 "conn-timeout <0-65534>",
1473 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1474 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001475 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1476 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001477 "Timeout value (sec.)\n")
1478{
1479 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1480 return CMD_SUCCESS;
1481}
1482
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001483int mgcp_vty_init(void)
1484{
1485 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001486 install_element_ve(&show_mgcp_endpoint_cmd);
1487 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001488 install_element(ENABLE_NODE, &loop_conn_cmd);
1489 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001490 install_element(ENABLE_NODE, &free_endp_cmd);
1491 install_element(ENABLE_NODE, &reset_endp_cmd);
1492 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1493
1494 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1495 install_node(&mgcp_node, config_write_mgcp);
1496
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001497 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001498 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1499 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1500 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001501 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001502 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001503 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001504 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001505 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001506 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001507 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1508 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001509 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1510 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1511 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1512 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1513 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1514 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1515 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1516 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1517 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001518 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1519 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1520 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1521 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1522 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1523 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001524 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001525 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1526 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1527 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1528 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1529 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1530 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1531 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1532 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001533 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1534 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001535 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1536 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1537 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1538 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1539 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1540 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1541 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1542 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1543 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1544 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1545 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1546 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1547 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001548 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001549 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001550
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001551 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1552 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001553 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1554 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1555 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1556 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1557 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1558 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1559 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1560 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1561 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1562 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1563 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1564 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1565 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001566 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1567 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001568 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1569 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1570 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1571 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1572 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1573 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1574 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1575 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1576 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001577 install_element(TRUNK_NODE, &cfg_trunk_line_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001578
1579 return 0;
1580}
1581
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001582int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1583 enum mgcp_role role)
1584{
1585 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001586 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001587
1588 cfg->osmux_port = OSMUX_PORT;
1589 cfg->osmux_batch = 4;
1590 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1591
1592 g_cfg = cfg;
1593 rc = vty_read_config_file(config_file, NULL);
1594 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001595 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1596 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001597 return rc;
1598 }
1599
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001600 if (!g_cfg->source_addr) {
1601 fprintf(stderr, "You need to specify a bind address.\n");
1602 return -1;
1603 }
1604
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001605 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier889fe7f2020-07-06 17:44:12 +02001606 if (mgcp_trunk_equip(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001607 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001608 "Failed to initialize trunk %d (%d endpoints)\n",
1609 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001610 return -1;
1611 }
1612 }
1613 cfg->role = role;
1614
1615 return 0;
1616}