blob: e404fb5888bacc74555a1eaa98f33ed82700c2e5 [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>
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +020025#include <osmocom/core/sockaddr_str.h>
Stefan Sperling1e174872018-10-25 18:36:10 +020026#include <osmocom/vty/misc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020027#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020028#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier993ea6b2020-08-04 18:26:50 +020029#include <osmocom/mgcp/osmux.h>
30#include <osmocom/mgcp/mgcp_protocol.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020031#include <osmocom/mgcp/vty.h>
32#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010033#include <osmocom/mgcp/mgcp_endp.h>
Philipp Maierc66ab2c2020-06-02 20:55:34 +020034#include <osmocom/mgcp/mgcp_trunk.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020035
36#include <string.h>
Philipp Maierbca0ef62018-07-09 17:20:51 +020037#include <inttypes.h>
Stefan Sperling12086582018-06-26 15:26:28 +020038#include <limits.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020039
40#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
41#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
42#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
Philipp Maier9fc8a022019-02-20 12:26:52 +010043#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"
44
Philipp Maier19c430f2020-09-22 15:52:50 +020045#define X(x) (1 << x)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020046
47static struct mgcp_config *g_cfg = NULL;
48
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020049struct cmd_node mgcp_node = {
50 MGCP_NODE,
51 "%s(config-mgcp)# ",
52 1,
53};
54
55struct cmd_node trunk_node = {
56 TRUNK_NODE,
57 "%s(config-mgcp-trunk)# ",
58 1,
59};
60
61static int config_write_mgcp(struct vty *vty)
62{
Philipp Maier6fbbeec2020-07-01 23:00:54 +020063 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +020064 OSMO_ASSERT(trunk);
Harald Weltec39b1bf2020-03-08 11:29:39 +010065
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020066 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020067 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Eric2764bdb2021-08-23 22:11:47 +020068 if (strlen(g_cfg->local_ip))
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020069 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020070 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
71 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
72 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020073 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
74 VTY_NEWLINE);
Eric2764bdb2021-08-23 22:11:47 +020075 if (strlen(g_cfg->net_ports.bind_addr_v4))
Philipp Maierf53796c2020-06-02 20:38:28 +020076 vty_out(vty, " rtp bind-ip %s%s",
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +020077 g_cfg->net_ports.bind_addr_v4, VTY_NEWLINE);
Eric2764bdb2021-08-23 22:11:47 +020078 if (strlen(g_cfg->net_ports.bind_addr_v6))
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +020079 vty_out(vty, " rtp bind-ip-v6 %s%s",
80 g_cfg->net_ports.bind_addr_v6, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010081 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020082 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010083 else
Philipp Maierf53796c2020-06-02 20:38:28 +020084 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
85 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Welte55a92292021-04-28 19:06:34 +020086 if (g_cfg->endp_priority)
87 vty_out(vty, " rtp socket-priority %d%s", g_cfg->endp_priority, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010088 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020089 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010090 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020091 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010092 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020093 else
Philipp Maierf53796c2020-06-02 20:38:28 +020094 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020095
Harald Weltec39b1bf2020-03-08 11:29:39 +010096 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +020097 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020098 else
Philipp Maierf53796c2020-06-02 20:38:28 +020099 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100100 if (trunk->force_constant_ssrc
101 || trunk->force_aligned_timing
102 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200103 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100104 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200105 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200106 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100107 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200108 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200109 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100110 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100111 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200112 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200113 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100114 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200115 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100116 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200117 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100118 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200119 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100120 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200121 vty_out(vty, " number endpoints %u%s",
Philipp Maier889fe7f2020-07-06 17:44:12 +0200122 trunk->v.vty_number_endpoints, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200123 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100124 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Eric2764bdb2021-08-23 22:11:47 +0200125 if (strlen(g_cfg->call_agent_addr))
Philipp Maierf53796c2020-06-02 20:38:28 +0200126 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200127 VTY_NEWLINE);
128 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200129 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200130 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200131
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200132 switch (g_cfg->osmux.usage) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200133 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200134 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200135 break;
136 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200137 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200138 break;
139 case OSMUX_USAGE_OFF:
140 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200141 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200142 break;
143 }
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200144 if (g_cfg->osmux.usage != OSMUX_USAGE_OFF) {
145 if (g_cfg->osmux.local_addr_v4)
Pau Espin Pedrol70c03f52022-10-04 16:49:41 +0200146 vty_out(vty, " osmux bind-ip %s%s",
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200147 g_cfg->osmux.local_addr_v4, VTY_NEWLINE);
148 if (g_cfg->osmux.local_addr_v6)
Pau Espin Pedrol70c03f52022-10-04 16:49:41 +0200149 vty_out(vty, " osmux bind-ip-v6 %s%s",
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200150 g_cfg->osmux.local_addr_v6, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200151 vty_out(vty, " osmux batch-factor %d%s",
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200152 g_cfg->osmux.batch_factor, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200153 vty_out(vty, " osmux batch-size %u%s",
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200154 g_cfg->osmux.batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200155 vty_out(vty, " osmux port %u%s",
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200156 g_cfg->osmux.local_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200157 vty_out(vty, " osmux dummy %s%s",
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200158 g_cfg->osmux.dummy_padding ? "on" : "off", VTY_NEWLINE);
Pau Espin Pedrol833281d2022-10-06 17:41:22 +0200159 vty_out(vty, " osmux peer-behind-nat %s%s",
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200160 g_cfg->osmux.peer_behind_nat ? "on" : "off", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200161 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100162
163 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200164 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100165
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200166 return CMD_SUCCESS;
167}
168
Philipp Maiercede2a42018-07-03 14:14:21 +0200169static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200170{
Philipp Maiercede2a42018-07-03 14:14:21 +0200171 struct mgcp_rtp_state *state = &conn->state;
172 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200173 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100174 struct rate_ctr *tx_packets, *tx_bytes;
175 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200176 struct rate_ctr *dropped_packets;
177
Pau Espin Pedroldaf5bce2022-09-22 19:14:24 +0200178 tx_packets = rate_ctr_group_get_ctr(conn->ctrg, RTP_PACKETS_TX_CTR);
179 tx_bytes = rate_ctr_group_get_ctr(conn->ctrg, RTP_OCTETS_TX_CTR);
180 rx_packets = rate_ctr_group_get_ctr(conn->ctrg, RTP_PACKETS_RX_CTR);
181 rx_bytes = rate_ctr_group_get_ctr(conn->ctrg, RTP_OCTETS_RX_CTR);
182 dropped_packets = rate_ctr_group_get_ctr(conn->ctrg, RTP_DROPPED_PACKETS_CTR);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200183
184 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100185 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
186 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200187 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
188 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200189 " Payload Type: %d Rate: %u Channels: %d %s"
190 " Frame Duration: %u Frame Denominator: %u%s"
191 " FPP: %d Packet Duration: %u%s"
192 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
193 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100194 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
195 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200196 state->in_stream.err_ts_ctr->current,
197 state->out_stream.err_ts_ctr->current,
Pau Espin Pedrol83df47c2022-09-21 20:07:59 +0200198 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200199 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200200 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200201 codec->frame_duration_num, codec->frame_duration_den,
202 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
203 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
204 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
205 end->force_output_ptime, VTY_NEWLINE);
Pau Espin Pedrolea7aaf22022-09-22 21:07:54 +0200206 if (mgcp_conn_rtp_is_osmux(conn)) {
207 struct rate_ctr *rx_chunks, *rx_octets, *rtp_tx, *rtp_tx_dropped, *octets_tx;
208 rx_chunks = rate_ctr_group_get_ctr(conn->osmux.ctrg, OSMUX_CHUNKS_RX_CTR);
209 rx_octets = rate_ctr_group_get_ctr(conn->osmux.ctrg, OSMUX_OCTETS_RX_CTR);
210 rtp_tx = rate_ctr_group_get_ctr(conn->osmux.ctrg, OSMUX_RTP_PACKETS_TX_CTR);
211 rtp_tx_dropped = rate_ctr_group_get_ctr(conn->osmux.ctrg, OSMUX_RTP_PACKETS_TX_DROPPED_CTR);
212 octets_tx = rate_ctr_group_get_ctr(conn->osmux.ctrg, OSMUX_AMR_OCTETS_TX_CTR);
213 vty_out(vty,
214 " Osmux:%s"
215 " State: %s%s"
216 " Local CID: %d%s"
217 " Remote CID: %d%s"
218 " Chunks received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
219 " RTP Packets encoded (Tx): %" PRIu64 " (%" PRIu64 " AMR octets total)%s"
220 " AMR payloads Dropped (Tx): %" PRIu64 "%s",
221 VTY_NEWLINE, osmux_state_str(conn->osmux.state), VTY_NEWLINE,
222 conn->osmux.local_cid_allocated ? conn->osmux.local_cid : -1, VTY_NEWLINE,
223 conn->osmux.remote_cid_present ? conn->osmux.remote_cid : -1, VTY_NEWLINE,
224 rx_chunks->current, rx_octets->current, VTY_NEWLINE,
225 rtp_tx->current, octets_tx->current, VTY_NEWLINE,
226 rtp_tx_dropped->current, VTY_NEWLINE
227 );
228
229 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200230}
231
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200232static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Philipp Maierd70eef62021-07-19 13:53:28 +0200233 unsigned int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200234{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200235 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200236
Philipp Maierd70eef62021-07-19 13:53:28 +0200237 vty_out(vty, "%s trunk %u endpoint %s:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200238 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Philipp Maier8d6a1932020-06-18 12:19:31 +0200239 vty_out(vty, " Availability: %s%s",
240 mgcp_endp_avail(endp) ? "available" : "not in service", VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200241
242 if (llist_empty(&endp->conns)) {
243 vty_out(vty, " No active connections%s", VTY_NEWLINE);
244 return;
245 }
246
247 llist_for_each_entry(conn, &endp->conns, entry) {
248 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
249
250 if (show_stats) {
Ericfbf78d12021-08-23 22:31:39 +0200251 if (endp->trunk->cfg->conn_timeout) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100252 struct timeval remaining;
253 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
254 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
255 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
256 }
257
Stefan Sperling12086582018-06-26 15:26:28 +0200258 /* FIXME: Also add verbosity for other
259 * connection types (E1) as soon as
260 * the implementation is available */
261 if (conn->type == MGCP_CONN_TYPE_RTP) {
262 dump_rtp_end(vty, &conn->u.rtp);
263 }
264 }
265 }
266}
267
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200268static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
269{
270 vty_out(vty, "%s", VTY_NEWLINE);
271 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
272
273 if (ratectr->mgcp_general_ctr_group) {
274 vty_out(vty, " %s:%s",
275 ratectr->mgcp_general_ctr_group->desc->
276 group_description, VTY_NEWLINE);
277 vty_out_rate_ctr_group_fmt(vty,
278 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
279 ratectr->mgcp_general_ctr_group);
280 }
281}
282
Philipp Maier889fe7f2020-07-06 17:44:12 +0200283static void dump_ratectr_trunk(struct vty *vty, struct mgcp_trunk *trunk)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200284{
Philipp Maier889fe7f2020-07-06 17:44:12 +0200285 struct mgcp_ratectr_trunk *ratectr = &trunk->ratectr;
286
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200287 vty_out(vty, "%s", VTY_NEWLINE);
288 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
289
290 if (ratectr->mgcp_crcx_ctr_group) {
291 vty_out(vty, " %s:%s",
292 ratectr->mgcp_crcx_ctr_group->desc->group_description,
293 VTY_NEWLINE);
294 vty_out_rate_ctr_group_fmt(vty,
295 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
296 ratectr->mgcp_crcx_ctr_group);
297 }
298 if (ratectr->mgcp_dlcx_ctr_group) {
299 vty_out(vty, " %s:%s",
300 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
301 VTY_NEWLINE);
302 vty_out_rate_ctr_group_fmt(vty,
303 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
304 ratectr->mgcp_dlcx_ctr_group);
305 }
306 if (ratectr->mgcp_mdcx_ctr_group) {
307 vty_out(vty, " %s:%s",
308 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
309 VTY_NEWLINE);
310 vty_out_rate_ctr_group_fmt(vty,
311 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
312 ratectr->mgcp_mdcx_ctr_group);
313 }
314 if (ratectr->all_rtp_conn_stats) {
315 vty_out(vty, " %s:%s",
316 ratectr->all_rtp_conn_stats->desc->group_description,
317 VTY_NEWLINE);
318 vty_out_rate_ctr_group_fmt(vty,
319 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
320 ratectr->all_rtp_conn_stats);
321 }
Pau Espin Pedrol582c2bf2022-09-22 17:53:44 +0200322 if (ratectr->all_osmux_conn_stats) {
323 vty_out(vty, " %s:%s",
324 ratectr->all_osmux_conn_stats->desc->group_description,
325 VTY_NEWLINE);
326 vty_out_rate_ctr_group_fmt(vty,
327 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
328 ratectr->all_osmux_conn_stats);
329 }
Philipp Maier889fe7f2020-07-06 17:44:12 +0200330
331 if (ratectr->e1_stats && trunk->trunk_type == MGCP_TRUNK_E1) {
332 vty_out(vty, " %s:%s",
333 ratectr->e1_stats->desc->group_description,
334 VTY_NEWLINE);
335 vty_out_rate_ctr_group_fmt(vty,
336 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
337 ratectr->e1_stats);
338 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200339}
340
341
Keithfe53edd2021-05-04 15:23:30 -0500342static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats, int active_only)
Stefan Sperling12086582018-06-26 15:26:28 +0200343{
344 int i;
Keithfe53edd2021-05-04 15:23:30 -0500345 int active_count = 0;
Stefan Sperling12086582018-06-26 15:26:28 +0200346
347 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200348 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
Philipp Maier869b21c2020-07-03 16:04:16 +0200349 trunk->trunk_nr, trunk->number_endpoints, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200350
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200351 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200352 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
353 return;
354 }
355
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200356 for (i = 0; i < trunk->number_endpoints; ++i) {
357 struct mgcp_endpoint *endp = trunk->endpoints[i];
Keithfe53edd2021-05-04 15:23:30 -0500358 if (!active_only || !llist_empty(&endp->conns)) {
359 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
360 show_stats);
361 if (i < trunk->number_endpoints - 1)
362 vty_out(vty, "%s", VTY_NEWLINE);
363 }
364 if (!llist_empty(&endp->conns))
365 active_count++;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200366 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200367
Keithfe53edd2021-05-04 15:23:30 -0500368 if (active_count == 0)
369 vty_out(vty, "No endpoints in use.%s", VTY_NEWLINE);
370
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200371 if (show_stats)
Philipp Maier889fe7f2020-07-06 17:44:12 +0200372 dump_ratectr_trunk(vty, trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200373}
374
Keithfe53edd2021-05-04 15:23:30 -0500375static int mgcp_show(struct vty *vty, int argc, const char **argv,
376 int show_stats, int active_only)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200377{
Philipp Maier14b27a82020-06-02 20:15:30 +0200378 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200379
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200380 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Keithfe53edd2021-05-04 15:23:30 -0500381 dump_trunk(vty, trunk, show_stats, active_only);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200382
Pau Espin Pedrol36413c02022-10-12 17:58:17 +0200383 if (g_cfg->osmux.usage != OSMUX_USAGE_OFF)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200384 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200385 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200386
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200387 if (show_stats)
388 dump_ratectr_global(vty, &g_cfg->ratectr);
389
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200390 return CMD_SUCCESS;
391}
392
Keithfe53edd2021-05-04 15:23:30 -0500393#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
394
395DEFUN(show_mgcp, show_mgcp_cmd,
396 "show mgcp [stats]",
397 SHOW_STR
398 SHOW_MGCP_STR
399 "Include statistics\n")
400{
401 int show_stats = argc >= 1;
402 return mgcp_show(vty, argc, argv, show_stats, 0);
403}
404
405DEFUN(show_mgcp_active, show_mgcp_active_cmd,
406 "show mgcp active",
407 SHOW_STR
408 SHOW_MGCP_STR
409 "Show only endpoints with active connections\n")
410{
411 return mgcp_show(vty, argc, argv, 0, 1);
412}
413
Stefan Sperling12086582018-06-26 15:26:28 +0200414static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200415dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200416{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200417 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200418
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200419 if (trunk) {
420 /* If a trunk is given, search on that specific trunk only */
421 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
422 if (!endp) {
Philipp Maierd70eef62021-07-19 13:53:28 +0200423 vty_out(vty, "endpoint %s not configured on trunk %u%s", epname, trunk->trunk_nr, VTY_NEWLINE);
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200424 return;
425 }
426 } else {
427 /* If no trunk is given, search on all possible trunks */
428 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
429 if (!endp) {
430 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
431 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200432 }
433 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200434
435 trunk = endp->trunk;
436 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200437}
438
439DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
440 "show mgcp endpoint NAME",
441 SHOW_STR
442 SHOW_MGCP_STR
443 "Display information about an endpoint\n" "The name of the endpoint\n")
444{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200445 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200446 return CMD_SUCCESS;
447}
448
449DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
450 "show mgcp trunk <0-64> endpoint NAME",
451 SHOW_STR
452 SHOW_MGCP_STR
453 "Display information about a trunk\n" "Trunk number\n"
454 "Display information about an endpoint\n" "The name of the endpoint\n")
455{
Philipp Maier14b27a82020-06-02 20:15:30 +0200456 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200457 int trunkidx = atoi(argv[0]);
458
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200459 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200460 if (!trunk) {
461 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
462 return CMD_WARNING;
463 }
464
465 dump_mgcp_endpoint(vty, trunk, argv[1]);
466 return CMD_SUCCESS;
467}
468
Philipp Maier87bd9be2017-08-22 16:35:41 +0200469DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200470{
471 vty->node = MGCP_NODE;
472 return CMD_SUCCESS;
473}
474
Philipp Maier19c430f2020-09-22 15:52:50 +0200475DEFUN_USRATTR(cfg_mgcp_local_ip,
476 cfg_mgcp_local_ip_cmd,
477 X(MGW_CMD_ATTR_NEWCONN),
478 "local ip " VTY_IPV46_CMD,
479 "Local options for the SDP record\n"
480 IP_STR
481 "IPv4 Address to use in SDP record\n"
482 "IPv6 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200483{
Eric2764bdb2021-08-23 22:11:47 +0200484 osmo_strlcpy(g_cfg->local_ip, argv[0], sizeof(g_cfg->local_ip));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200485 return CMD_SUCCESS;
486}
487
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200488#define BIND_STR "Listen/Bind related socket option\n"
489DEFUN(cfg_mgcp_bind_ip,
490 cfg_mgcp_bind_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200491 "bind ip " VTY_IPV46_CMD,
492 BIND_STR IP_STR
493 "IPv4 Address to bind to\n"
494 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200495{
Eric2764bdb2021-08-23 22:11:47 +0200496 osmo_strlcpy(g_cfg->source_addr, argv[0], sizeof(g_cfg->source_addr));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200497 return CMD_SUCCESS;
498}
499
500DEFUN(cfg_mgcp_bind_port,
501 cfg_mgcp_bind_port_cmd,
502 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200503 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200504{
505 unsigned int port = atoi(argv[0]);
506 g_cfg->source_port = port;
507 return CMD_SUCCESS;
508}
509
Philipp Maier8cfe7df2020-09-22 16:18:26 +0200510DEFUN_DEPRECATED(cfg_mgcp_bind_early,
511 cfg_mgcp_bind_early_cmd,
512 "bind early (0|1)",
513 BIND_STR
514 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200515{
Philipp Maier8cfe7df2020-09-22 16:18:26 +0200516 return CMD_SUCCESS;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200517}
518
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200519#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200520#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200521#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200522#define RANGE_START_STR "Start of the range of ports\n"
523#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200524
Philipp Maierf1889d82017-11-08 14:59:39 +0100525DEFUN(cfg_mgcp_rtp_port_range,
526 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200527 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200528 RTP_STR "Range of ports to use for the NET side\n"
529 RANGE_START_STR RANGE_END_STR)
530{
Philipp Maiera19547b2018-05-22 13:44:34 +0200531 int start;
532 int end;
533
534 start = atoi(argv[0]);
535 end = atoi(argv[1]);
536
537 if (end < start) {
538 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
539 end, start, VTY_NEWLINE);
540 return CMD_WARNING;
541 }
542
543 if (start & 1) {
544 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
545 start, start & 0xFFFE, VTY_NEWLINE);
546 start &= 0xFFFE;
547 }
548
549 if ((end & 1) == 0) {
550 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
551 end, end | 1, VTY_NEWLINE);
552 end |= 1;
553 }
554
555 g_cfg->net_ports.range_start = start;
556 g_cfg->net_ports.range_end = end;
557 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
558
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200559 return CMD_SUCCESS;
560}
Philipp Maierf1889d82017-11-08 14:59:39 +0100561ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
562 cfg_mgcp_rtp_net_range_cmd,
563 "rtp net-range <0-65534> <0-65534>",
564 RTP_STR "Range of ports to use for the NET side\n"
565 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200566
Philipp Maier19c430f2020-09-22 15:52:50 +0200567DEFUN_USRATTR(cfg_mgcp_rtp_bind_ip,
568 cfg_mgcp_rtp_bind_ip_cmd,
569 X(MGW_CMD_ATTR_NEWCONN),
570 "rtp bind-ip A.B.C.D",
571 RTP_STR "Bind endpoints facing the Network\n"
572 "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200573{
Eric2764bdb2021-08-23 22:11:47 +0200574 osmo_strlcpy(g_cfg->net_ports.bind_addr_v4, argv[0], sizeof(g_cfg->net_ports.bind_addr_v4));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200575 return CMD_SUCCESS;
576}
Philipp Maierf1889d82017-11-08 14:59:39 +0100577ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
578 cfg_mgcp_rtp_net_bind_ip_cmd,
579 "rtp net-bind-ip A.B.C.D",
580 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200581
Philipp Maier19c430f2020-09-22 15:52:50 +0200582DEFUN_USRATTR(cfg_mgcp_rtp_no_bind_ip,
583 cfg_mgcp_rtp_no_bind_ip_cmd,
584 X(MGW_CMD_ATTR_NEWCONN),
585 "no rtp bind-ip",
586 NO_STR RTP_STR "Bind endpoints facing the Network\n"
587 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200588{
Eric2764bdb2021-08-23 22:11:47 +0200589 osmo_strlcpy(g_cfg->net_ports.bind_addr_v4, "", sizeof(g_cfg->net_ports.bind_addr_v4));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200590 return CMD_SUCCESS;
591}
Philipp Maierf1889d82017-11-08 14:59:39 +0100592ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
593 cfg_mgcp_rtp_no_net_bind_ip_cmd,
594 "no rtp net-bind-ip",
595 NO_STR RTP_STR "Bind endpoints facing the Network\n"
596 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200597
Philipp Maier19c430f2020-09-22 15:52:50 +0200598DEFUN_USRATTR(cfg_mgcp_rtp_bind_ip_v6,
599 cfg_mgcp_rtp_bind_ip_v6_cmd,
600 X(MGW_CMD_ATTR_NEWCONN),
601 "rtp bind-ip-v6 " VTY_IPV6_CMD,
602 RTP_STR "Bind endpoints facing the Network\n"
603 "IPv6 Address to bind to\n")
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200604{
Eric2764bdb2021-08-23 22:11:47 +0200605 osmo_strlcpy(g_cfg->net_ports.bind_addr_v6, argv[0], sizeof(g_cfg->net_ports.bind_addr_v6));
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200606 return CMD_SUCCESS;
607}
608
Philipp Maier19c430f2020-09-22 15:52:50 +0200609DEFUN_USRATTR(cfg_mgcp_rtp_no_bind_ip_v6,
610 cfg_mgcp_rtp_no_bind_ip_v6_cmd,
611 X(MGW_CMD_ATTR_NEWCONN),
612 "no rtp bind-ip-v6",
613 NO_STR RTP_STR "Bind endpoints facing the Network\n"
614 "Address to bind to\n")
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200615{
Eric2764bdb2021-08-23 22:11:47 +0200616 osmo_strlcpy(g_cfg->net_ports.bind_addr_v6, "", sizeof(g_cfg->net_ports.bind_addr_v6));
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200617 return CMD_SUCCESS;
618}
619
Philipp Maier19c430f2020-09-22 15:52:50 +0200620DEFUN_USRATTR(cfg_mgcp_rtp_net_bind_ip_probing,
621 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
622 X(MGW_CMD_ATTR_NEWCONN),
623 "rtp ip-probing",
624 RTP_STR "automatic rtp bind ip selection\n")
Philipp Maier1cb1e382017-11-02 17:16:04 +0100625{
626 g_cfg->net_ports.bind_addr_probe = true;
627 return CMD_SUCCESS;
628}
629
Philipp Maier19c430f2020-09-22 15:52:50 +0200630DEFUN_USRATTR(cfg_mgcp_rtp_no_net_bind_ip_probing,
631 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
632 X(MGW_CMD_ATTR_NEWCONN),
633 "no rtp ip-probing",
634 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
Philipp Maier1cb1e382017-11-02 17:16:04 +0100635{
636 g_cfg->net_ports.bind_addr_probe = false;
637 return CMD_SUCCESS;
638}
639
Philipp Maier19c430f2020-09-22 15:52:50 +0200640DEFUN_USRATTR(cfg_mgcp_rtp_ip_dscp,
641 cfg_mgcp_rtp_ip_dscp_cmd,
642 X(MGW_CMD_ATTR_NEWCONN),
Harald Welte5936a9c2021-04-27 22:30:52 +0200643 "rtp ip-dscp <0-63>",
Philipp Maier19c430f2020-09-22 15:52:50 +0200644 RTP_STR
Harald Welte5936a9c2021-04-27 22:30:52 +0200645 "Use specified DSCP for the audio stream (including Osmux)\n" "The DSCP value\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200646{
647 int dscp = atoi(argv[0]);
648 g_cfg->endp_dscp = dscp;
649 return CMD_SUCCESS;
650}
651
Harald Welte55a92292021-04-28 19:06:34 +0200652DEFUN_USRATTR(cfg_mgcp_rtp_priority,
653 cfg_mgcp_rtp_priority_cmd,
654 X(MGW_CMD_ATTR_NEWCONN),
655 "rtp socket-priority <0-255>",
656 RTP_STR
657 "socket priority (values > 6 require CAP_NET_ADMIN)\n" "socket priority value\n")
658{
659 int prio = atoi(argv[0]);
660 g_cfg->endp_priority = prio;
661 return CMD_SUCCESS;
662}
663
Philipp Maier87bd9be2017-08-22 16:35:41 +0200664#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier19c430f2020-09-22 15:52:50 +0200665DEFUN_USRATTR(cfg_mgcp_rtp_force_ptime,
666 cfg_mgcp_rtp_force_ptime_cmd,
667 X(MGW_CMD_ATTR_NEWCONN),
668 "rtp force-ptime (10|20|40)",
669 RTP_STR FORCE_PTIME_STR
670 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200671{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200672 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200673 return CMD_SUCCESS;
674}
675
Philipp Maier19c430f2020-09-22 15:52:50 +0200676DEFUN_USRATTR(cfg_mgcp_no_rtp_force_ptime,
677 cfg_mgcp_no_rtp_force_ptime_cmd,
678 X(MGW_CMD_ATTR_NEWCONN),
679 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200680{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200681 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200682 return CMD_SUCCESS;
683}
684
Philipp Maier19c430f2020-09-22 15:52:50 +0200685DEFUN_USRATTR(cfg_mgcp_sdp_fmtp_extra,
686 cfg_mgcp_sdp_fmtp_extra_cmd,
687 X(MGW_CMD_ATTR_NEWCONN),
688 "sdp audio fmtp-extra .NAME",
689 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
690 "Extra Information\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200691{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200692 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200693 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200694 char *txt = argv_concat(argv, argc, 0);
695 if (!txt)
696 return CMD_WARNING;
697
Philipp Maierd19de2e2020-06-03 13:55:33 +0200698 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200699 talloc_free(txt);
700 return CMD_SUCCESS;
701}
702
Philipp Maier19c430f2020-09-22 15:52:50 +0200703DEFUN_USRATTR(cfg_mgcp_allow_transcoding,
704 cfg_mgcp_allow_transcoding_cmd,
705 X(MGW_CMD_ATTR_NEWCONN),
706 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200707{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200708 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200709 OSMO_ASSERT(trunk);
710 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200711 return CMD_SUCCESS;
712}
713
Philipp Maier19c430f2020-09-22 15:52:50 +0200714DEFUN_USRATTR(cfg_mgcp_no_allow_transcoding,
715 cfg_mgcp_no_allow_transcoding_cmd,
716 X(MGW_CMD_ATTR_NEWCONN),
717 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200718{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200719 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200720 OSMO_ASSERT(trunk);
721 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200722 return CMD_SUCCESS;
723}
724
725#define SDP_STR "SDP File related options\n"
726#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200727DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200728 cfg_mgcp_sdp_payload_number_cmd,
729 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200730 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200731{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200732 return CMD_SUCCESS;
733}
734
Philipp Maier87bd9be2017-08-22 16:35:41 +0200735ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
736 cfg_mgcp_sdp_payload_number_cmd_old,
737 "sdp audio payload number <0-255>",
738 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200739
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200740DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200741 cfg_mgcp_sdp_payload_name_cmd,
742 "sdp audio-payload name NAME",
743 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
744{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200745 return CMD_SUCCESS;
746}
747
748ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200749 "sdp audio payload name NAME",
750 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200751
Philipp Maier19c430f2020-09-22 15:52:50 +0200752DEFUN_USRATTR(cfg_mgcp_sdp_payload_send_ptime,
753 cfg_mgcp_sdp_payload_send_ptime_cmd,
754 X(MGW_CMD_ATTR_NEWCONN),
755 "sdp audio-payload send-ptime",
756 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200757{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200758 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200759 OSMO_ASSERT(trunk);
760 trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200761 return CMD_SUCCESS;
762}
763
Philipp Maier19c430f2020-09-22 15:52:50 +0200764DEFUN_USRATTR(cfg_mgcp_no_sdp_payload_send_ptime,
765 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
766 X(MGW_CMD_ATTR_NEWCONN),
767 "no sdp audio-payload send-ptime",
768 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200769{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200770 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200771 OSMO_ASSERT(trunk);
772 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200773 return CMD_SUCCESS;
774}
775
Philipp Maier19c430f2020-09-22 15:52:50 +0200776DEFUN_USRATTR(cfg_mgcp_sdp_payload_send_name,
777 cfg_mgcp_sdp_payload_send_name_cmd,
778 X(MGW_CMD_ATTR_NEWCONN),
779 "sdp audio-payload send-name",
780 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200781{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200782 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200783 OSMO_ASSERT(trunk);
784 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200785 return CMD_SUCCESS;
786}
787
Philipp Maier19c430f2020-09-22 15:52:50 +0200788DEFUN_USRATTR(cfg_mgcp_no_sdp_payload_send_name,
789 cfg_mgcp_no_sdp_payload_send_name_cmd,
790 X(MGW_CMD_ATTR_NEWCONN),
791 "no sdp audio-payload send-name",
792 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200793{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200794 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200795 OSMO_ASSERT(trunk);
796 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200797 return CMD_SUCCESS;
798}
799
Philipp Maierba94b6d2020-09-22 16:14:32 +0200800DEFUN_DEPRECATED(cfg_mgcp_loop,
801 cfg_mgcp_loop_cmd,
802 "loop (0|1)",
803 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200804{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200805 return CMD_SUCCESS;
806}
807
Philipp Maier19c430f2020-09-22 15:52:50 +0200808DEFUN_USRATTR(cfg_mgcp_force_realloc,
809 cfg_mgcp_force_realloc_cmd,
810 X(MGW_CMD_ATTR_NEWCONN),
811 "force-realloc (0|1)",
812 "Force endpoint reallocation when the endpoint is still seized\n"
813 "Don't force reallocation\n" "force reallocation\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200814{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200815 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200816 OSMO_ASSERT(trunk);
817 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200818 return CMD_SUCCESS;
819}
820
Philipp Maier19c430f2020-09-22 15:52:50 +0200821DEFUN_ATTR(cfg_mgcp_rtp_accept_all,
822 cfg_mgcp_rtp_accept_all_cmd,
823 "rtp-accept-all (0|1)",
824 "Accept all RTP packets, even when the originating IP/Port does not match\n"
825 "enable filter\n" "disable filter\n",
826 CMD_ATTR_IMMEDIATE)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200827{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200828 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200829 OSMO_ASSERT(trunk);
830 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200831 return CMD_SUCCESS;
832}
833
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200834DEFUN(cfg_mgcp_number_endp,
835 cfg_mgcp_number_endp_cmd,
Philipp Maier869b21c2020-07-03 16:04:16 +0200836 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200837 "Number options\n" "Endpoints available\n" "Number endpoints\n")
838{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200839 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200840 OSMO_ASSERT(trunk);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200841 trunk->v.vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200842 return CMD_SUCCESS;
843}
844
Philipp Maier19c430f2020-09-22 15:52:50 +0200845DEFUN_ATTR(cfg_mgcp_omit_rtcp,
846 cfg_mgcp_omit_rtcp_cmd,
847 "rtcp-omit", RTCP_OMIT_STR,
848 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200849{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200850 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200851 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200852 return CMD_SUCCESS;
853}
854
Philipp Maier19c430f2020-09-22 15:52:50 +0200855DEFUN_ATTR(cfg_mgcp_no_omit_rtcp,
856 cfg_mgcp_no_omit_rtcp_cmd,
857 "no rtcp-omit",
858 NO_STR RTCP_OMIT_STR,
859 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200860{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200861 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200862 OSMO_ASSERT(trunk);
863 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200864 return CMD_SUCCESS;
865}
866
Philipp Maier19c430f2020-09-22 15:52:50 +0200867DEFUN_USRATTR(cfg_mgcp_patch_rtp_ssrc,
868 cfg_mgcp_patch_rtp_ssrc_cmd,
869 X(MGW_CMD_ATTR_NEWCONN),
870 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200871{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200872 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200873 OSMO_ASSERT(trunk);
874 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200875 return CMD_SUCCESS;
876}
877
Philipp Maier19c430f2020-09-22 15:52:50 +0200878DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_ssrc,
879 cfg_mgcp_no_patch_rtp_ssrc_cmd,
880 X(MGW_CMD_ATTR_NEWCONN),
881 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200882{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200883 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200884 OSMO_ASSERT(trunk);
885 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200886 return CMD_SUCCESS;
887}
888
Philipp Maier19c430f2020-09-22 15:52:50 +0200889DEFUN_USRATTR(cfg_mgcp_patch_rtp_ts,
890 cfg_mgcp_patch_rtp_ts_cmd,
891 X(MGW_CMD_ATTR_NEWCONN),
892 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200893{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200894 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200895 OSMO_ASSERT(trunk);
896 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200897 return CMD_SUCCESS;
898}
899
Philipp Maier19c430f2020-09-22 15:52:50 +0200900DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_ts,
901 cfg_mgcp_no_patch_rtp_ts_cmd,
902 X(MGW_CMD_ATTR_NEWCONN),
903 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200904{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200905 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200906 OSMO_ASSERT(trunk);
907 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200908 return CMD_SUCCESS;
909}
910
Philipp Maier19c430f2020-09-22 15:52:50 +0200911DEFUN_USRATTR(cfg_mgcp_patch_rtp_rfc5993hr,
912 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
913 X(MGW_CMD_ATTR_NEWCONN),
914 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
Philipp Maier9fc8a022019-02-20 12:26:52 +0100915{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200916 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200917 OSMO_ASSERT(trunk);
918 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100919 return CMD_SUCCESS;
920}
921
Philipp Maier19c430f2020-09-22 15:52:50 +0200922DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_rfc5993hr,
923 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
924 X(MGW_CMD_ATTR_NEWCONN),
925 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
Philipp Maier9fc8a022019-02-20 12:26:52 +0100926{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200927 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200928 OSMO_ASSERT(trunk);
929 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100930 return CMD_SUCCESS;
931}
932
Philipp Maier19c430f2020-09-22 15:52:50 +0200933DEFUN_USRATTR(cfg_mgcp_no_patch_rtp,
934 cfg_mgcp_no_patch_rtp_cmd,
935 X(MGW_CMD_ATTR_NEWCONN),
936 "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200937{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200938 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200939 OSMO_ASSERT(trunk);
940 trunk->force_constant_ssrc = 0;
941 trunk->force_aligned_timing = 0;
942 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200943 return CMD_SUCCESS;
944}
945
Philipp Maier19c430f2020-09-22 15:52:50 +0200946DEFUN_ATTR(cfg_mgcp_rtp_keepalive,
947 cfg_mgcp_rtp_keepalive_cmd,
948 "rtp keep-alive <1-120>",
949 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n",
950 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200951{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200952 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200953 OSMO_ASSERT(trunk);
954 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200955 return CMD_SUCCESS;
956}
957
Philipp Maier19c430f2020-09-22 15:52:50 +0200958DEFUN_ATTR(cfg_mgcp_rtp_keepalive_once,
959 cfg_mgcp_rtp_keepalive_once_cmd,
960 "rtp keep-alive once",
961 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n",
962 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200963{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200964 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200965 OSMO_ASSERT(trunk);
966 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200967 return CMD_SUCCESS;
968}
969
Philipp Maier19c430f2020-09-22 15:52:50 +0200970DEFUN_ATTR(cfg_mgcp_no_rtp_keepalive,
971 cfg_mgcp_no_rtp_keepalive_cmd,
972 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR,
973 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200974{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200975 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200976 OSMO_ASSERT(trunk);
977 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200978 return CMD_SUCCESS;
979}
980
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200981#define CALL_AGENT_STR "Call agent information\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200982DEFUN(cfg_mgcp_agent_addr,
983 cfg_mgcp_agent_addr_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200984 "call-agent ip " VTY_IPV46_CMD,
985 CALL_AGENT_STR IP_STR
986 "IPv4 Address of the call agent\n"
987 "IPv6 Address of the call agent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200988{
Eric2764bdb2021-08-23 22:11:47 +0200989 osmo_strlcpy(g_cfg->call_agent_addr, argv[0], sizeof(g_cfg->call_agent_addr));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200990 return CMD_SUCCESS;
991}
992
993ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200994 "call agent ip A.B.C.D",
995 CALL_AGENT_STR CALL_AGENT_STR IP_STR
996 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200997
Philipp Maier21be42a2020-05-29 21:39:48 +0200998DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier0653cc82020-08-10 22:52:51 +0200999 "trunk <0-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000{
Philipp Maier14b27a82020-06-02 20:15:30 +02001001 struct mgcp_trunk *trunk;
Philipp Maierd70eef62021-07-19 13:53:28 +02001002 unsigned int index = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001003
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001004 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +01001005 if (!trunk) {
1006 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +02001007 if (!trunk) {
1008 vty_out(vty, "%%Unable to allocate trunk %u.%s",
1009 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +01001010 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +02001011 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001012 }
1013
1014 vty->node = TRUNK_NODE;
1015 vty->index = trunk;
1016 return CMD_SUCCESS;
1017}
1018
1019static int config_write_trunk(struct vty *vty)
1020{
Philipp Maier14b27a82020-06-02 20:15:30 +02001021 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001022
1023 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +02001024
1025 /* Due to historical reasons, the virtual trunk is configured
1026 using separate VTY parameters, so we omit writing the trunk
1027 config of trunk 0 here. The configuration for the virtual
1028 trunk is written by config_write_mgcp(). */
1029
Philipp Maier31682a32020-11-26 00:39:35 +01001030 if (trunk->trunk_type == MGCP_TRUNK_VIRTUAL
1031 && trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
Philipp Maierd19de2e2020-06-03 13:55:33 +02001032 continue;
1033
Philipp Maierd70eef62021-07-19 13:53:28 +02001034 vty_out(vty, " trunk %u%s", trunk->trunk_nr, VTY_NEWLINE);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001035 vty_out(vty, " line %u%s", trunk->e1.vty_line_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001036 vty_out(vty, " %ssdp audio-payload send-ptime%s",
1037 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
1038 vty_out(vty, " %ssdp audio-payload send-name%s",
1039 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
1040
1041 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
1042 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
1043 else if (trunk->keepalive_interval)
1044 vty_out(vty, " rtp keep-alive %d%s",
1045 trunk->keepalive_interval, VTY_NEWLINE);
1046 else
1047 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001048 vty_out(vty, " force-realloc %d%s",
1049 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001050 vty_out(vty, " rtp-accept-all %d%s",
1051 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001052 if (trunk->omit_rtcp)
1053 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
1054 else
1055 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001056 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +02001057 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001058 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001059 trunk->force_constant_ssrc ? "" : "no ",
1060 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001061 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001062 trunk->force_aligned_timing ? "" : "no ",
1063 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001064 vty_out(vty, " %srtp-patch rfc5993hr%s",
1065 trunk->rfc5993_hr_convert ? "" : "no ",
1066 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001067 } else
1068 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
1069 if (trunk->audio_fmtp_extra)
1070 vty_out(vty, " sdp audio fmtp-extra %s%s",
1071 trunk->audio_fmtp_extra, VTY_NEWLINE);
1072 vty_out(vty, " %sallow-transcoding%s",
1073 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
1074 }
1075
1076 return CMD_SUCCESS;
1077}
1078
Philipp Maier19c430f2020-09-22 15:52:50 +02001079DEFUN_USRATTR(cfg_trunk_sdp_fmtp_extra,
1080 cfg_trunk_sdp_fmtp_extra_cmd,
1081 X(MGW_CMD_ATTR_NEWCONN),
1082 "sdp audio fmtp-extra .NAME",
1083 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
1084 "Extra Information\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001085{
Philipp Maier14b27a82020-06-02 20:15:30 +02001086 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001087 char *txt = argv_concat(argv, argc, 0);
1088 if (!txt)
1089 return CMD_WARNING;
1090
1091 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
1092 talloc_free(txt);
1093 return CMD_SUCCESS;
1094}
1095
Philipp Maier7f90ddb2020-06-02 21:52:53 +02001096DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001097 cfg_trunk_payload_number_cmd,
1098 "sdp audio-payload number <0-255>",
1099 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
1100{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001101 return CMD_SUCCESS;
1102}
1103
1104ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001105 "sdp audio payload number <0-255>",
1106 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001107
Philipp Maier7f90ddb2020-06-02 21:52:53 +02001108DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001109 cfg_trunk_payload_name_cmd,
1110 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001111 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001112{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001113 return CMD_SUCCESS;
1114}
1115
1116ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001117 "sdp audio payload name NAME",
1118 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001119
Philipp Maierba94b6d2020-09-22 16:14:32 +02001120DEFUN_DEPRECATED(cfg_trunk_loop,
1121 cfg_trunk_loop_cmd,
1122 "loop (0|1)",
1123 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001124{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001125 return CMD_SUCCESS;
1126}
1127
Philipp Maier41425e92020-11-26 00:41:59 +01001128DEFUN_USRATTR(cfg_trunk_force_realloc,
1129 cfg_trunk_force_realloc_cmd,
1130 X(MGW_CMD_ATTR_NEWCONN),
1131 "force-realloc (0|1)",
1132 "Force endpoint reallocation when the endpoint is still seized\n"
1133 "Don't force reallocation\n" "force reallocation\n")
1134{
1135 struct mgcp_trunk *trunk = vty->index;
1136 OSMO_ASSERT(trunk);
1137 trunk->force_realloc = atoi(argv[0]);
1138 return CMD_SUCCESS;
1139}
1140
1141DEFUN_ATTR(cfg_trunk_rtp_accept_all,
1142 cfg_trunk_rtp_accept_all_cmd,
1143 "rtp-accept-all (0|1)",
1144 "Accept all RTP packets, even when the originating IP/Port does not match\n"
1145 "enable filter\n" "disable filter\n",
1146 CMD_ATTR_IMMEDIATE)
1147{
1148 struct mgcp_trunk *trunk = vty->index;
1149 OSMO_ASSERT(trunk);
1150 trunk->rtp_accept_all = atoi(argv[0]);
1151 return CMD_SUCCESS;
1152}
1153
Philipp Maier19c430f2020-09-22 15:52:50 +02001154DEFUN_USRATTR(cfg_trunk_sdp_payload_send_ptime,
1155 cfg_trunk_sdp_payload_send_ptime_cmd,
1156 X(MGW_CMD_ATTR_NEWCONN),
1157 "sdp audio-payload send-ptime",
1158 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\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->audio_send_ptime = 1;
1162 return CMD_SUCCESS;
1163}
1164
Philipp Maier19c430f2020-09-22 15:52:50 +02001165DEFUN_USRATTR(cfg_trunk_no_sdp_payload_send_ptime,
1166 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1167 X(MGW_CMD_ATTR_NEWCONN),
1168 "no sdp audio-payload send-ptime",
1169 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001170{
Philipp Maier14b27a82020-06-02 20:15:30 +02001171 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001172 trunk->audio_send_ptime = 0;
1173 return CMD_SUCCESS;
1174}
1175
Philipp Maier19c430f2020-09-22 15:52:50 +02001176DEFUN_USRATTR(cfg_trunk_sdp_payload_send_name,
1177 cfg_trunk_sdp_payload_send_name_cmd,
1178 X(MGW_CMD_ATTR_NEWCONN),
1179 "sdp audio-payload send-name",
1180 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001181{
Philipp Maier14b27a82020-06-02 20:15:30 +02001182 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001183 trunk->audio_send_name = 1;
1184 return CMD_SUCCESS;
1185}
1186
Philipp Maier19c430f2020-09-22 15:52:50 +02001187DEFUN_USRATTR(cfg_trunk_no_sdp_payload_send_name,
1188 cfg_trunk_no_sdp_payload_send_name_cmd,
1189 X(MGW_CMD_ATTR_NEWCONN),
1190 "no sdp audio-payload send-name",
1191 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001192{
Philipp Maier14b27a82020-06-02 20:15:30 +02001193 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001194 trunk->audio_send_name = 0;
1195 return CMD_SUCCESS;
1196}
1197
Philipp Maier19c430f2020-09-22 15:52:50 +02001198DEFUN_ATTR(cfg_trunk_omit_rtcp,
1199 cfg_trunk_omit_rtcp_cmd,
1200 "rtcp-omit", RTCP_OMIT_STR,
1201 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001202{
Philipp Maier14b27a82020-06-02 20:15:30 +02001203 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001204 trunk->omit_rtcp = 1;
1205 return CMD_SUCCESS;
1206}
1207
Philipp Maier19c430f2020-09-22 15:52:50 +02001208DEFUN_ATTR(cfg_trunk_no_omit_rtcp,
1209 cfg_trunk_no_omit_rtcp_cmd,
1210 "no rtcp-omit", NO_STR RTCP_OMIT_STR,
1211 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001212{
Philipp Maier14b27a82020-06-02 20:15:30 +02001213 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001214 trunk->omit_rtcp = 0;
1215 return CMD_SUCCESS;
1216}
1217
Philipp Maier19c430f2020-09-22 15:52:50 +02001218DEFUN_USRATTR(cfg_trunk_patch_rtp_ssrc,
1219 cfg_trunk_patch_rtp_ssrc_cmd,
1220 X(MGW_CMD_ATTR_NEWCONN),
1221 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001222{
Philipp Maier14b27a82020-06-02 20:15:30 +02001223 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001224 trunk->force_constant_ssrc = 1;
1225 return CMD_SUCCESS;
1226}
1227
Philipp Maier19c430f2020-09-22 15:52:50 +02001228DEFUN_USRATTR(cfg_trunk_no_patch_rtp_ssrc,
1229 cfg_trunk_no_patch_rtp_ssrc_cmd,
1230 X(MGW_CMD_ATTR_NEWCONN),
1231 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001232{
Philipp Maier14b27a82020-06-02 20:15:30 +02001233 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001234 trunk->force_constant_ssrc = 0;
1235 return CMD_SUCCESS;
1236}
1237
Philipp Maier19c430f2020-09-22 15:52:50 +02001238DEFUN_USRATTR(cfg_trunk_patch_rtp_ts,
1239 cfg_trunk_patch_rtp_ts_cmd,
1240 X(MGW_CMD_ATTR_NEWCONN),
1241 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001242{
Philipp Maier14b27a82020-06-02 20:15:30 +02001243 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001244 trunk->force_aligned_timing = 1;
1245 return CMD_SUCCESS;
1246}
1247
Philipp Maier19c430f2020-09-22 15:52:50 +02001248DEFUN_USRATTR(cfg_trunk_no_patch_rtp_ts,
1249 cfg_trunk_no_patch_rtp_ts_cmd,
1250 X(MGW_CMD_ATTR_NEWCONN),
1251 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001252{
Philipp Maier14b27a82020-06-02 20:15:30 +02001253 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001254 trunk->force_aligned_timing = 0;
1255 return CMD_SUCCESS;
1256}
1257
Philipp Maier19c430f2020-09-22 15:52:50 +02001258DEFUN_USRATTR(cfg_trunk_patch_rtp_rfc5993hr,
1259 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1260 X(MGW_CMD_ATTR_NEWCONN),
1261 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
Philipp Maier9fc8a022019-02-20 12:26:52 +01001262{
Philipp Maier14b27a82020-06-02 20:15:30 +02001263 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001264 trunk->rfc5993_hr_convert = true;
1265 return CMD_SUCCESS;
1266}
1267
Philipp Maier19c430f2020-09-22 15:52:50 +02001268DEFUN_USRATTR(cfg_trunk_no_patch_rtp_rfc5993hr,
1269 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1270 X(MGW_CMD_ATTR_NEWCONN),
1271 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
Philipp Maier9fc8a022019-02-20 12:26:52 +01001272{
Philipp Maier14b27a82020-06-02 20:15:30 +02001273 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001274 trunk->rfc5993_hr_convert = false;
1275 return CMD_SUCCESS;
1276}
1277
Philipp Maier19c430f2020-09-22 15:52:50 +02001278DEFUN_USRATTR(cfg_trunk_no_patch_rtp,
1279 cfg_trunk_no_patch_rtp_cmd,
1280 X(MGW_CMD_ATTR_NEWCONN),
1281 "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001282{
Philipp Maier14b27a82020-06-02 20:15:30 +02001283 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001284 trunk->force_constant_ssrc = 0;
1285 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001286 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001287 return CMD_SUCCESS;
1288}
1289
Philipp Maier19c430f2020-09-22 15:52:50 +02001290DEFUN_ATTR(cfg_trunk_rtp_keepalive,
1291 cfg_trunk_rtp_keepalive_cmd,
1292 "rtp keep-alive <1-120>",
1293 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n",
1294 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001295{
Philipp Maier14b27a82020-06-02 20:15:30 +02001296 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001297 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1298 return CMD_SUCCESS;
1299}
1300
Philipp Maier19c430f2020-09-22 15:52:50 +02001301DEFUN_ATTR(cfg_trunk_rtp_keepalive_once,
1302 cfg_trunk_rtp_keepalive_once_cmd,
1303 "rtp keep-alive once",
1304 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n",
1305 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001306{
Philipp Maier14b27a82020-06-02 20:15:30 +02001307 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001308 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1309 return CMD_SUCCESS;
1310}
1311
Philipp Maier19c430f2020-09-22 15:52:50 +02001312DEFUN_ATTR(cfg_trunk_no_rtp_keepalive,
1313 cfg_trunk_no_rtp_keepalive_cmd,
1314 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR,
1315 CMD_ATTR_IMMEDIATE)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001316{
Philipp Maier14b27a82020-06-02 20:15:30 +02001317 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001318 mgcp_trunk_set_keepalive(trunk, 0);
1319 return CMD_SUCCESS;
1320}
1321
Philipp Maier19c430f2020-09-22 15:52:50 +02001322DEFUN_USRATTR(cfg_trunk_allow_transcoding,
1323 cfg_trunk_allow_transcoding_cmd,
1324 X(MGW_CMD_ATTR_NEWCONN),
1325 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001326{
Philipp Maier14b27a82020-06-02 20:15:30 +02001327 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001328 trunk->no_audio_transcoding = 0;
1329 return CMD_SUCCESS;
1330}
1331
Philipp Maier19c430f2020-09-22 15:52:50 +02001332DEFUN_USRATTR(cfg_trunk_no_allow_transcoding,
1333 cfg_trunk_no_allow_transcoding_cmd,
1334 X(MGW_CMD_ATTR_NEWCONN),
1335 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001336{
Philipp Maier14b27a82020-06-02 20:15:30 +02001337 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001338 trunk->no_audio_transcoding = 1;
1339 return CMD_SUCCESS;
1340}
1341
Philipp Maier889fe7f2020-07-06 17:44:12 +02001342#define LINE_STR "Configure trunk for given Line\nE1/T1 Line Number\n"
1343
1344DEFUN(cfg_trunk_line,
1345 cfg_trunk_line_cmd,
1346 "line <0-255>",
1347 LINE_STR)
1348{
1349 struct mgcp_trunk *trunk = vty->index;
1350 int line_nr = atoi(argv[0]);
1351 trunk->e1.vty_line_nr = line_nr;
1352 return CMD_SUCCESS;
1353}
1354
Philipp Maier87bd9be2017-08-22 16:35:41 +02001355DEFUN(loop_conn,
1356 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001357 "loop-endpoint <0-64> NAME (0|1)",
1358 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001359 "The name in hex of the endpoint\n" "Disable the loop\n"
1360 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001361{
Philipp Maier14b27a82020-06-02 20:15:30 +02001362 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001363 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001364 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001365
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001366 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001367 if (!trunk) {
1368 vty_out(vty, "%%Trunk %d not found in the config.%s",
1369 atoi(argv[0]), VTY_NEWLINE);
1370 return CMD_WARNING;
1371 }
1372
1373 if (!trunk->endpoints) {
Philipp Maierd70eef62021-07-19 13:53:28 +02001374 vty_out(vty, "%%Trunk %u has no endpoints allocated.%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001375 trunk->trunk_nr, VTY_NEWLINE);
1376 return CMD_WARNING;
1377 }
1378
1379 int endp_no = strtoul(argv[1], NULL, 16);
1380 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1381 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001382 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001383 return CMD_WARNING;
1384 }
1385
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001386 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001387 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001388 llist_for_each_entry(conn, &endp->conns, entry) {
1389 if (conn->type == MGCP_CONN_TYPE_RTP)
1390 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1391 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1392 else {
1393 /* FIXME: Introduce support for other connection (E1)
1394 * types when implementation is available */
1395 vty_out(vty, "%%Can't enable SSRC patching,"
1396 "connection %s is not an RTP connection.%s",
1397 mgcp_conn_dump(conn), VTY_NEWLINE);
1398 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001399
Philipp Maier87bd9be2017-08-22 16:35:41 +02001400 if (loop)
1401 conn->mode = MGCP_CONN_LOOPBACK;
1402 else
1403 conn->mode = conn->mode_orig;
1404 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001405
1406 return CMD_SUCCESS;
1407}
1408
Philipp Maier87bd9be2017-08-22 16:35:41 +02001409DEFUN(tap_rtp,
1410 tap_rtp_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001411 "tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001412 "Forward data on endpoint to a different system\n" "Trunk number\n"
1413 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001414 "The connection id in hex\n"
1415 "Forward incoming data\n"
1416 "Forward leaving data\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001417 "Destination IPv4 of the data\n"
1418 "Destination IPv6 of the data\n"
1419 "Destination port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001420{
1421 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001422 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001423 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001424 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001425 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001426
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001427 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001428 if (!trunk) {
1429 vty_out(vty, "%%Trunk %d not found in the config.%s",
1430 atoi(argv[0]), VTY_NEWLINE);
1431 return CMD_WARNING;
1432 }
1433
1434 if (!trunk->endpoints) {
Philipp Maierd70eef62021-07-19 13:53:28 +02001435 vty_out(vty, "%%Trunk %u has no endpoints allocated.%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001436 trunk->trunk_nr, VTY_NEWLINE);
1437 return CMD_WARNING;
1438 }
1439
1440 int endp_no = strtoul(argv[1], NULL, 16);
1441 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1442 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001443 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001444 return CMD_WARNING;
1445 }
1446
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001447 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001448
Philipp Maier01d24a32017-11-21 17:26:09 +01001449 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001450 conn = mgcp_conn_get_rtp(endp, conn_id);
1451 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001452 vty_out(vty, "Conn ID %s is invalid.%s",
1453 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001454 return CMD_WARNING;
1455 }
1456
1457 if (strcmp(argv[3], "in") == 0)
1458 tap = &conn->tap_in;
1459 else if (strcmp(argv[3], "out") == 0)
1460 tap = &conn->tap_out;
1461 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001462 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1463 return CMD_WARNING;
1464 }
1465
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001466 memset(&tap->forward, 0, sizeof(tap->forward));
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001467
1468 tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);
1469 switch (tap->forward.u.sa.sa_family) {
1470 case AF_INET:
1471 if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)
1472 return CMD_WARNING;
1473 tap->forward.u.sin.sin_port = htons(atoi(argv[5]));
1474 break;
1475 case AF_INET6:
1476 if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)
1477 return CMD_WARNING;
1478 tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));
1479 break;
1480 default:
1481 return CMD_WARNING;
1482 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001483 tap->enabled = 1;
1484 return CMD_SUCCESS;
1485}
1486
1487DEFUN(free_endp, free_endp_cmd,
1488 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001489 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001490{
Philipp Maier14b27a82020-06-02 20:15:30 +02001491 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001492 struct mgcp_endpoint *endp;
1493
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001494 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001495 if (!trunk) {
1496 vty_out(vty, "%%Trunk %d not found in the config.%s",
1497 atoi(argv[0]), VTY_NEWLINE);
1498 return CMD_WARNING;
1499 }
1500
1501 if (!trunk->endpoints) {
Philipp Maierd70eef62021-07-19 13:53:28 +02001502 vty_out(vty, "%%Trunk %u has no endpoints allocated.%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001503 trunk->trunk_nr, VTY_NEWLINE);
1504 return CMD_WARNING;
1505 }
1506
1507 int endp_no = strtoul(argv[1], NULL, 16);
1508 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1509 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001510 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001511 return CMD_WARNING;
1512 }
1513
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001514 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001515 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001516 return CMD_SUCCESS;
1517}
1518
1519DEFUN(reset_endp, reset_endp_cmd,
1520 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001521 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001522{
Philipp Maier14b27a82020-06-02 20:15:30 +02001523 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001524 struct mgcp_endpoint *endp;
1525 int endp_no, rc;
1526
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001527 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001528 if (!trunk) {
1529 vty_out(vty, "%%Trunk %d not found in the config.%s",
1530 atoi(argv[0]), VTY_NEWLINE);
1531 return CMD_WARNING;
1532 }
1533
1534 if (!trunk->endpoints) {
Philipp Maierd70eef62021-07-19 13:53:28 +02001535 vty_out(vty, "%%Trunk %u has no endpoints allocated.%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001536 trunk->trunk_nr, VTY_NEWLINE);
1537 return CMD_WARNING;
1538 }
1539
1540 endp_no = strtoul(argv[1], NULL, 16);
1541 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1542 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001543 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001544 return CMD_WARNING;
1545 }
1546
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001547 endp = trunk->endpoints[endp_no];
1548 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001549 if (rc < 0) {
1550 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1551 return CMD_WARNING;
1552 }
1553 return CMD_SUCCESS;
1554}
1555
1556DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001557 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001558{
1559 int rc;
1560
1561 rc = mgcp_send_reset_all(g_cfg);
1562 if (rc < 0) {
1563 vty_out(vty, "Error %d during endpoint reset.%s",
1564 rc, VTY_NEWLINE);
1565 return CMD_WARNING;
1566 }
1567 return CMD_SUCCESS;
1568}
1569
1570#define OSMUX_STR "RTP multiplexing\n"
1571DEFUN(cfg_mgcp_osmux,
1572 cfg_mgcp_osmux_cmd,
1573 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001574 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001575{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001576 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001577 OSMO_ASSERT(trunk);
1578
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001579 if (strcmp(argv[0], "off") == 0) {
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001580 g_cfg->osmux.usage = OSMUX_USAGE_OFF;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001581 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001582 } else if (strcmp(argv[0], "on") == 0)
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001583 g_cfg->osmux.usage = OSMUX_USAGE_ON;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001584 else if (strcmp(argv[0], "only") == 0)
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001585 g_cfg->osmux.usage = OSMUX_USAGE_ONLY;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001586
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001587 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001588
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001589}
1590
1591DEFUN(cfg_mgcp_osmux_ip,
1592 cfg_mgcp_osmux_ip_cmd,
Pau Espin Pedrol70c03f52022-10-04 16:49:41 +02001593 "osmux bind-ip " VTY_IPV4_CMD,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001594 OSMUX_STR IP_STR
Pau Espin Pedrol70c03f52022-10-04 16:49:41 +02001595 "IPv4 Address to bind to\n")
1596{
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001597 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux.local_addr_v4, argv[0]);
Pau Espin Pedrol70c03f52022-10-04 16:49:41 +02001598 return CMD_SUCCESS;
1599}
1600
1601DEFUN(cfg_mgcp_osmux_ip_v6,
1602 cfg_mgcp_osmux_ip_v6_cmd,
1603 "osmux bind-ip-v6 " VTY_IPV6_CMD,
1604 OSMUX_STR IP_STR
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001605 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001606{
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001607 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux.local_addr_v6, argv[0]);
1608 return CMD_SUCCESS;
1609}
1610
1611DEFUN(cfg_mgcp_osmux_port,
1612 cfg_mgcp_osmux_port_cmd,
1613 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
1614{
1615 g_cfg->osmux.local_port = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001616 return CMD_SUCCESS;
1617}
1618
1619DEFUN(cfg_mgcp_osmux_batch_factor,
1620 cfg_mgcp_osmux_batch_factor_cmd,
1621 "osmux batch-factor <1-8>",
1622 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1623{
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001624 g_cfg->osmux.batch_factor = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001625 return CMD_SUCCESS;
1626}
1627
1628DEFUN(cfg_mgcp_osmux_batch_size,
1629 cfg_mgcp_osmux_batch_size_cmd,
1630 "osmux batch-size <1-65535>",
1631 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1632{
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001633 g_cfg->osmux.batch_size = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001634 return CMD_SUCCESS;
1635}
1636
1637DEFUN(cfg_mgcp_osmux_dummy,
1638 cfg_mgcp_osmux_dummy_cmd,
1639 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001640 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1641 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001642{
1643 if (strcmp(argv[0], "on") == 0)
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001644 g_cfg->osmux.dummy_padding = true;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001645 else if (strcmp(argv[0], "off") == 0)
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001646 g_cfg->osmux.dummy_padding = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001647
1648 return CMD_SUCCESS;
1649}
1650
Pau Espin Pedrol833281d2022-10-06 17:41:22 +02001651DEFUN(cfg_mgcp_osmux_peer_behind_nat,
1652 cfg_mgcp_osmux_peer_behind_nat_cmd,
1653 "osmux peer-behind-nat (on|off)",
1654 OSMUX_STR "Define whether peer is behind NAT\n"
1655 "Peer is behind NAT\n"
1656 "Peer is NOT behind NAT\n")
1657{
1658 if (strcmp(argv[0], "on") == 0)
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001659 g_cfg->osmux.peer_behind_nat = true;
Pau Espin Pedrol833281d2022-10-06 17:41:22 +02001660 else if (strcmp(argv[0], "off") == 0)
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001661 g_cfg->osmux.peer_behind_nat = false;
Pau Espin Pedrol833281d2022-10-06 17:41:22 +02001662
1663 return CMD_SUCCESS;
1664}
1665
Philipp Maier12943ea2018-01-17 15:40:25 +01001666DEFUN(cfg_mgcp_domain,
1667 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001668 "domain NAME",
1669 "Set the domain part expected in MGCP messages' endpoint names\n"
1670 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001671{
1672 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1673 return CMD_SUCCESS;
1674}
1675
Oliver Smithe36b7752019-01-22 16:31:36 +01001676DEFUN(cfg_mgcp_conn_timeout,
1677 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001678 "conn-timeout <0-65534>",
1679 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1680 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001681 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1682 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001683 "Timeout value (sec.)\n")
1684{
1685 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1686 return CMD_SUCCESS;
1687}
1688
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001689int mgcp_vty_init(void)
1690{
1691 install_element_ve(&show_mgcp_cmd);
Keithfe53edd2021-05-04 15:23:30 -05001692 install_element_ve(&show_mgcp_active_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001693 install_element_ve(&show_mgcp_endpoint_cmd);
1694 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001695 install_element(ENABLE_NODE, &loop_conn_cmd);
1696 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001697 install_element(ENABLE_NODE, &free_endp_cmd);
1698 install_element(ENABLE_NODE, &reset_endp_cmd);
1699 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1700
1701 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1702 install_node(&mgcp_node, config_write_mgcp);
1703
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001704 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001705 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1706 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1707 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001708 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001709 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001710 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001711 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001712 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_v6_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001713 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001714 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001715 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_v6_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001716 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1717 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001718 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
Harald Welte55a92292021-04-28 19:06:34 +02001719 install_element(MGCP_NODE, &cfg_mgcp_rtp_priority_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001720 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1721 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1722 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1723 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1724 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1725 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1726 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001727 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1728 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1729 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1730 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1731 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1732 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001733 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001734 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1735 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1736 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1737 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1738 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1739 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1740 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1741 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001742 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1743 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001744 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1745 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1746 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1747 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1748 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1749 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1750 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
Pau Espin Pedrol70c03f52022-10-04 16:49:41 +02001751 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_v6_cmd);
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001752 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001753 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1754 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001755 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
Pau Espin Pedrol833281d2022-10-06 17:41:22 +02001756 install_element(MGCP_NODE, &cfg_mgcp_osmux_peer_behind_nat_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001757 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1758 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001759 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001760 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001761
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001762 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1763 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001764 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1765 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1766 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1767 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1768 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1769 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1770 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1771 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
Philipp Maier41425e92020-11-26 00:41:59 +01001772 install_element(TRUNK_NODE, &cfg_trunk_force_realloc_cmd);
1773 install_element(TRUNK_NODE, &cfg_trunk_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001774 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1775 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1776 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1777 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1778 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001779 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1780 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001781 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1782 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1783 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1784 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1785 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1786 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1787 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1788 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1789 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001790 install_element(TRUNK_NODE, &cfg_trunk_line_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001791
1792 return 0;
1793}
1794
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001795int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1796 enum mgcp_role role)
1797{
1798 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001799 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001800
Pau Espin Pedrol36413c02022-10-12 17:58:17 +02001801 cfg->osmux.local_port = OSMUX_DEFAULT_PORT;
1802 cfg->osmux.batch_factor = 4;
1803 cfg->osmux.batch_size = OSMUX_BATCH_DEFAULT_MAX;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001804
1805 g_cfg = cfg;
1806 rc = vty_read_config_file(config_file, NULL);
1807 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001808 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1809 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001810 return rc;
1811 }
1812
Eric2764bdb2021-08-23 22:11:47 +02001813 if (!strlen(g_cfg->source_addr)) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001814 fprintf(stderr, "You need to specify a bind address.\n");
1815 return -1;
1816 }
1817
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001818 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier889fe7f2020-07-06 17:44:12 +02001819 if (mgcp_trunk_equip(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001820 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maierd70eef62021-07-19 13:53:28 +02001821 "Failed to initialize trunk %u (%d endpoints)\n",
Philipp Maier48454982017-11-10 16:46:41 +01001822 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001823 return -1;
1824 }
1825 }
1826 cfg->role = role;
1827
1828 return 0;
1829}