blob: 8ea1cddb37441996f011756ae34ed2f41a4ac0c2 [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
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020045
46static struct mgcp_config *g_cfg = NULL;
47
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020048struct cmd_node mgcp_node = {
49 MGCP_NODE,
50 "%s(config-mgcp)# ",
51 1,
52};
53
54struct cmd_node trunk_node = {
55 TRUNK_NODE,
56 "%s(config-mgcp-trunk)# ",
57 1,
58};
59
60static int config_write_mgcp(struct vty *vty)
61{
Philipp Maier6fbbeec2020-07-01 23:00:54 +020062 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +020063 OSMO_ASSERT(trunk);
Harald Weltec39b1bf2020-03-08 11:29:39 +010064
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020065 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020066 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020067 if (g_cfg->local_ip)
68 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020069 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
70 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
71 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020072 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
73 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020074 if (g_cfg->net_ports.bind_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +020075 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020076 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010077 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020078 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010079 else
Philipp Maierf53796c2020-06-02 20:38:28 +020080 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
81 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010082 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020083 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010084 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020085 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010086 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020087 else
Philipp Maierf53796c2020-06-02 20:38:28 +020088 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020089
Harald Weltec39b1bf2020-03-08 11:29:39 +010090 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +020091 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020092 else
Philipp Maierf53796c2020-06-02 20:38:28 +020093 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010094 if (trunk->force_constant_ssrc
95 || trunk->force_aligned_timing
96 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +020097 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010098 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +020099 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200100 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100101 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200102 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200103 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100104 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100105 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200106 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200107 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100108 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200109 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100110 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200111 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100112 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200113 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100114 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200115 vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
116 vty_out(vty, " number endpoints %u%s",
Philipp Maier889fe7f2020-07-06 17:44:12 +0200117 trunk->v.vty_number_endpoints, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200118 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100119 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200120 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200121 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200122 VTY_NEWLINE);
123 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200124 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200125 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200126
127 switch (g_cfg->osmux) {
128 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200129 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200130 break;
131 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200132 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200133 break;
134 case OSMUX_USAGE_OFF:
135 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200136 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200137 break;
138 }
139 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200140 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200141 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200142 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200143 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200144 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200145 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200146 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200147 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200148 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200149 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
150 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100151
152 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200153 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100154
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200155 return CMD_SUCCESS;
156}
157
Philipp Maiercede2a42018-07-03 14:14:21 +0200158static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200159{
Philipp Maiercede2a42018-07-03 14:14:21 +0200160 struct mgcp_rtp_state *state = &conn->state;
161 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200162 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100163 struct rate_ctr *tx_packets, *tx_bytes;
164 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200165 struct rate_ctr *dropped_packets;
166
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100167 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
168 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
169 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
170 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200171 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200172
173 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100174 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
175 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200176 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
177 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200178 " Payload Type: %d Rate: %u Channels: %d %s"
179 " Frame Duration: %u Frame Denominator: %u%s"
180 " FPP: %d Packet Duration: %u%s"
181 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
182 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100183 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
184 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200185 state->in_stream.err_ts_ctr->current,
186 state->out_stream.err_ts_ctr->current,
187 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200188 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200189 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200190 codec->frame_duration_num, codec->frame_duration_den,
191 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
192 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
193 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
194 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200195}
196
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200197static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200198 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200199{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200200 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200201
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200202 vty_out(vty, "%s trunk %d endpoint %s:%s",
203 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Philipp Maier8d6a1932020-06-18 12:19:31 +0200204 vty_out(vty, " Availability: %s%s",
205 mgcp_endp_avail(endp) ? "available" : "not in service", VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200206
207 if (llist_empty(&endp->conns)) {
208 vty_out(vty, " No active connections%s", VTY_NEWLINE);
209 return;
210 }
211
212 llist_for_each_entry(conn, &endp->conns, entry) {
213 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
214
215 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100216 if (endp->cfg->conn_timeout) {
217 struct timeval remaining;
218 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
219 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
220 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
221 }
222
Stefan Sperling12086582018-06-26 15:26:28 +0200223 /* FIXME: Also add verbosity for other
224 * connection types (E1) as soon as
225 * the implementation is available */
226 if (conn->type == MGCP_CONN_TYPE_RTP) {
227 dump_rtp_end(vty, &conn->u.rtp);
228 }
229 }
230 }
231}
232
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200233static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
234{
235 vty_out(vty, "%s", VTY_NEWLINE);
236 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
237
238 if (ratectr->mgcp_general_ctr_group) {
239 vty_out(vty, " %s:%s",
240 ratectr->mgcp_general_ctr_group->desc->
241 group_description, VTY_NEWLINE);
242 vty_out_rate_ctr_group_fmt(vty,
243 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
244 ratectr->mgcp_general_ctr_group);
245 }
246}
247
Philipp Maier889fe7f2020-07-06 17:44:12 +0200248static void dump_ratectr_trunk(struct vty *vty, struct mgcp_trunk *trunk)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200249{
Philipp Maier889fe7f2020-07-06 17:44:12 +0200250 struct mgcp_ratectr_trunk *ratectr = &trunk->ratectr;
251
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200252 vty_out(vty, "%s", VTY_NEWLINE);
253 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
254
255 if (ratectr->mgcp_crcx_ctr_group) {
256 vty_out(vty, " %s:%s",
257 ratectr->mgcp_crcx_ctr_group->desc->group_description,
258 VTY_NEWLINE);
259 vty_out_rate_ctr_group_fmt(vty,
260 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
261 ratectr->mgcp_crcx_ctr_group);
262 }
263 if (ratectr->mgcp_dlcx_ctr_group) {
264 vty_out(vty, " %s:%s",
265 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
266 VTY_NEWLINE);
267 vty_out_rate_ctr_group_fmt(vty,
268 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
269 ratectr->mgcp_dlcx_ctr_group);
270 }
271 if (ratectr->mgcp_mdcx_ctr_group) {
272 vty_out(vty, " %s:%s",
273 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
274 VTY_NEWLINE);
275 vty_out_rate_ctr_group_fmt(vty,
276 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
277 ratectr->mgcp_mdcx_ctr_group);
278 }
279 if (ratectr->all_rtp_conn_stats) {
280 vty_out(vty, " %s:%s",
281 ratectr->all_rtp_conn_stats->desc->group_description,
282 VTY_NEWLINE);
283 vty_out_rate_ctr_group_fmt(vty,
284 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
285 ratectr->all_rtp_conn_stats);
286 }
Philipp Maier889fe7f2020-07-06 17:44:12 +0200287
288 if (ratectr->e1_stats && trunk->trunk_type == MGCP_TRUNK_E1) {
289 vty_out(vty, " %s:%s",
290 ratectr->e1_stats->desc->group_description,
291 VTY_NEWLINE);
292 vty_out_rate_ctr_group_fmt(vty,
293 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
294 ratectr->e1_stats);
295 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200296}
297
298
299static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200300{
301 int i;
302
303 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200304 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
Philipp Maier869b21c2020-07-03 16:04:16 +0200305 trunk->trunk_nr, trunk->number_endpoints, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200306
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200307 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200308 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
309 return;
310 }
311
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200312 for (i = 0; i < trunk->number_endpoints; ++i) {
313 struct mgcp_endpoint *endp = trunk->endpoints[i];
314 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
315 show_stats);
316 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200317 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200318 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200319
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200320 if (show_stats)
Philipp Maier889fe7f2020-07-06 17:44:12 +0200321 dump_ratectr_trunk(vty, trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200322}
323
Stefan Sperling12086582018-06-26 15:26:28 +0200324#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
325
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200326DEFUN(show_mcgp, show_mgcp_cmd,
327 "show mgcp [stats]",
328 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200329 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200330 "Include Statistics\n")
331{
Philipp Maier14b27a82020-06-02 20:15:30 +0200332 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200333 int show_stats = argc >= 1;
334
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200335 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200336 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200337
338 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200339 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200340 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200341
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200342 if (show_stats)
343 dump_ratectr_global(vty, &g_cfg->ratectr);
344
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200345 return CMD_SUCCESS;
346}
347
Stefan Sperling12086582018-06-26 15:26:28 +0200348static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200349dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200350{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200351 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200352
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200353 if (trunk) {
354 /* If a trunk is given, search on that specific trunk only */
355 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
356 if (!endp) {
357 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
358 return;
359 }
360 } else {
361 /* If no trunk is given, search on all possible trunks */
362 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
363 if (!endp) {
364 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
365 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200366 }
367 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200368
369 trunk = endp->trunk;
370 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200371}
372
373DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
374 "show mgcp endpoint NAME",
375 SHOW_STR
376 SHOW_MGCP_STR
377 "Display information about an endpoint\n" "The name of the endpoint\n")
378{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200379 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200380 return CMD_SUCCESS;
381}
382
383DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
384 "show mgcp trunk <0-64> endpoint NAME",
385 SHOW_STR
386 SHOW_MGCP_STR
387 "Display information about a trunk\n" "Trunk number\n"
388 "Display information about an endpoint\n" "The name of the endpoint\n")
389{
Philipp Maier14b27a82020-06-02 20:15:30 +0200390 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200391 int trunkidx = atoi(argv[0]);
392
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200393 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200394 if (!trunk) {
395 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
396 return CMD_WARNING;
397 }
398
399 dump_mgcp_endpoint(vty, trunk, argv[1]);
400 return CMD_SUCCESS;
401}
402
Philipp Maier87bd9be2017-08-22 16:35:41 +0200403DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200404{
405 vty->node = MGCP_NODE;
406 return CMD_SUCCESS;
407}
408
409DEFUN(cfg_mgcp_local_ip,
410 cfg_mgcp_local_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200411 "local ip " VTY_IPV46_CMD,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200412 "Local options for the SDP record\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200413 IP_STR
414 "IPv4 Address to use in SDP record\n"
415 "IPv6 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200416{
417 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
418 return CMD_SUCCESS;
419}
420
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200421#define BIND_STR "Listen/Bind related socket option\n"
422DEFUN(cfg_mgcp_bind_ip,
423 cfg_mgcp_bind_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200424 "bind ip " VTY_IPV46_CMD,
425 BIND_STR IP_STR
426 "IPv4 Address to bind to\n"
427 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200428{
429 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
430 return CMD_SUCCESS;
431}
432
433DEFUN(cfg_mgcp_bind_port,
434 cfg_mgcp_bind_port_cmd,
435 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200436 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200437{
438 unsigned int port = atoi(argv[0]);
439 g_cfg->source_port = port;
440 return CMD_SUCCESS;
441}
442
443DEFUN(cfg_mgcp_bind_early,
444 cfg_mgcp_bind_early_cmd,
445 "bind early (0|1)",
446 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200447 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200448{
449 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
450 return CMD_WARNING;
451}
452
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200453#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200454#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200455#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200456#define RANGE_START_STR "Start of the range of ports\n"
457#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200458
Philipp Maierf1889d82017-11-08 14:59:39 +0100459DEFUN(cfg_mgcp_rtp_port_range,
460 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200461 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200462 RTP_STR "Range of ports to use for the NET side\n"
463 RANGE_START_STR RANGE_END_STR)
464{
Philipp Maiera19547b2018-05-22 13:44:34 +0200465 int start;
466 int end;
467
468 start = atoi(argv[0]);
469 end = atoi(argv[1]);
470
471 if (end < start) {
472 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
473 end, start, VTY_NEWLINE);
474 return CMD_WARNING;
475 }
476
477 if (start & 1) {
478 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
479 start, start & 0xFFFE, VTY_NEWLINE);
480 start &= 0xFFFE;
481 }
482
483 if ((end & 1) == 0) {
484 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
485 end, end | 1, VTY_NEWLINE);
486 end |= 1;
487 }
488
489 g_cfg->net_ports.range_start = start;
490 g_cfg->net_ports.range_end = end;
491 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
492
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200493 return CMD_SUCCESS;
494}
Philipp Maierf1889d82017-11-08 14:59:39 +0100495ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
496 cfg_mgcp_rtp_net_range_cmd,
497 "rtp net-range <0-65534> <0-65534>",
498 RTP_STR "Range of ports to use for the NET side\n"
499 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200500
Philipp Maierf1889d82017-11-08 14:59:39 +0100501DEFUN(cfg_mgcp_rtp_bind_ip,
502 cfg_mgcp_rtp_bind_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200503 "rtp bind-ip " VTY_IPV46_CMD,
504 RTP_STR "Bind endpoints facing the Network\n"
505 "IPv4 Address to bind to\n"
506 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200507{
508 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
509 return CMD_SUCCESS;
510}
Philipp Maierf1889d82017-11-08 14:59:39 +0100511ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
512 cfg_mgcp_rtp_net_bind_ip_cmd,
513 "rtp net-bind-ip A.B.C.D",
514 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200515
Philipp Maierf1889d82017-11-08 14:59:39 +0100516DEFUN(cfg_mgcp_rtp_no_bind_ip,
517 cfg_mgcp_rtp_no_bind_ip_cmd,
518 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200519 NO_STR RTP_STR "Bind endpoints facing the Network\n"
520 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200521{
522 talloc_free(g_cfg->net_ports.bind_addr);
523 g_cfg->net_ports.bind_addr = NULL;
524 return CMD_SUCCESS;
525}
Philipp Maierf1889d82017-11-08 14:59:39 +0100526ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
527 cfg_mgcp_rtp_no_net_bind_ip_cmd,
528 "no rtp net-bind-ip",
529 NO_STR RTP_STR "Bind endpoints facing the Network\n"
530 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200531
Philipp Maier1cb1e382017-11-02 17:16:04 +0100532DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
533 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
534 "rtp ip-probing",
535 RTP_STR "automatic rtp bind ip selection\n")
536{
537 g_cfg->net_ports.bind_addr_probe = true;
538 return CMD_SUCCESS;
539}
540
541DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
542 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
543 "no rtp ip-probing",
544 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
545{
546 g_cfg->net_ports.bind_addr_probe = false;
547 return CMD_SUCCESS;
548}
549
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200550DEFUN(cfg_mgcp_rtp_ip_dscp,
551 cfg_mgcp_rtp_ip_dscp_cmd,
552 "rtp ip-dscp <0-255>",
553 RTP_STR
554 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
555{
556 int dscp = atoi(argv[0]);
557 g_cfg->endp_dscp = dscp;
558 return CMD_SUCCESS;
559}
560
561ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200562 "rtp ip-tos <0-255>",
563 RTP_STR
564 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
565#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200566DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200567 cfg_mgcp_rtp_force_ptime_cmd,
568 "rtp force-ptime (10|20|40)",
569 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200570 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200571{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200572 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200573 return CMD_SUCCESS;
574}
575
576DEFUN(cfg_mgcp_no_rtp_force_ptime,
577 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200578 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200579{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200580 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200581 return CMD_SUCCESS;
582}
583
584DEFUN(cfg_mgcp_sdp_fmtp_extra,
585 cfg_mgcp_sdp_fmtp_extra_cmd,
586 "sdp audio fmtp-extra .NAME",
587 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
588 "Extra Information\n")
589{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200590 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200591 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200592 char *txt = argv_concat(argv, argc, 0);
593 if (!txt)
594 return CMD_WARNING;
595
Philipp Maierd19de2e2020-06-03 13:55:33 +0200596 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200597 talloc_free(txt);
598 return CMD_SUCCESS;
599}
600
601DEFUN(cfg_mgcp_allow_transcoding,
602 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200603 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200604{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200605 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200606 OSMO_ASSERT(trunk);
607 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200608 return CMD_SUCCESS;
609}
610
611DEFUN(cfg_mgcp_no_allow_transcoding,
612 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200613 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200614{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200615 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200616 OSMO_ASSERT(trunk);
617 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200618 return CMD_SUCCESS;
619}
620
621#define SDP_STR "SDP File related options\n"
622#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200623DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200624 cfg_mgcp_sdp_payload_number_cmd,
625 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200626 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200627{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200628 return CMD_SUCCESS;
629}
630
Philipp Maier87bd9be2017-08-22 16:35:41 +0200631ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
632 cfg_mgcp_sdp_payload_number_cmd_old,
633 "sdp audio payload number <0-255>",
634 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200635
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200636DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200637 cfg_mgcp_sdp_payload_name_cmd,
638 "sdp audio-payload name NAME",
639 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
640{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200641 return CMD_SUCCESS;
642}
643
644ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200645 "sdp audio payload name NAME",
646 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200647
Philipp Maier21be42a2020-05-29 21:39:48 +0200648DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200649 cfg_mgcp_sdp_payload_send_ptime_cmd,
650 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200651 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200652{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200653 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200654 OSMO_ASSERT(trunk);
655 trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200656 return CMD_SUCCESS;
657}
658
659DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
660 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
661 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200662 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200663{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200664 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200665 OSMO_ASSERT(trunk);
666 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200667 return CMD_SUCCESS;
668}
669
670DEFUN(cfg_mgcp_sdp_payload_send_name,
671 cfg_mgcp_sdp_payload_send_name_cmd,
672 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200673 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200674{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200675 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200676 OSMO_ASSERT(trunk);
677 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200678 return CMD_SUCCESS;
679}
680
681DEFUN(cfg_mgcp_no_sdp_payload_send_name,
682 cfg_mgcp_no_sdp_payload_send_name_cmd,
683 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200684 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200685{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200686 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200687 OSMO_ASSERT(trunk);
688 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200689 return CMD_SUCCESS;
690}
691
692DEFUN(cfg_mgcp_loop,
693 cfg_mgcp_loop_cmd,
694 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200695 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200696{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200697 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200698 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200699 if (g_cfg->osmux) {
700 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
701 return CMD_WARNING;
702 }
Philipp Maierd19de2e2020-06-03 13:55:33 +0200703 trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200704 return CMD_SUCCESS;
705}
706
707DEFUN(cfg_mgcp_force_realloc,
708 cfg_mgcp_force_realloc_cmd,
709 "force-realloc (0|1)",
710 "Force endpoint reallocation when the endpoint is still seized\n"
711 "Don't force reallocation\n" "force reallocation\n")
712{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200713 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200714 OSMO_ASSERT(trunk);
715 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200716 return CMD_SUCCESS;
717}
718
Philipp Maier87bd9be2017-08-22 16:35:41 +0200719DEFUN(cfg_mgcp_rtp_accept_all,
720 cfg_mgcp_rtp_accept_all_cmd,
721 "rtp-accept-all (0|1)",
722 "Accept all RTP packets, even when the originating IP/Port does not match\n"
723 "enable filter\n" "disable filter\n")
724{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200725 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200726 OSMO_ASSERT(trunk);
727 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200728 return CMD_SUCCESS;
729}
730
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200731DEFUN(cfg_mgcp_number_endp,
732 cfg_mgcp_number_endp_cmd,
Philipp Maier869b21c2020-07-03 16:04:16 +0200733 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200734 "Number options\n" "Endpoints available\n" "Number endpoints\n")
735{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200736 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200737 OSMO_ASSERT(trunk);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200738 trunk->v.vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200739 return CMD_SUCCESS;
740}
741
Philipp Maier87bd9be2017-08-22 16:35:41 +0200742DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200743{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200744 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200745 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200746 return CMD_SUCCESS;
747}
748
749DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200750 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200751{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200752 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200753 OSMO_ASSERT(trunk);
754 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200755 return CMD_SUCCESS;
756}
757
758DEFUN(cfg_mgcp_patch_rtp_ssrc,
759 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200760 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200761{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200762 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200763 OSMO_ASSERT(trunk);
764 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200765 return CMD_SUCCESS;
766}
767
768DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
769 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200770 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200771{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200772 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200773 OSMO_ASSERT(trunk);
774 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200775 return CMD_SUCCESS;
776}
777
778DEFUN(cfg_mgcp_patch_rtp_ts,
779 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200780 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\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->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200785 return CMD_SUCCESS;
786}
787
788DEFUN(cfg_mgcp_no_patch_rtp_ts,
789 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200790 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200791{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200792 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200793 OSMO_ASSERT(trunk);
794 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200795 return CMD_SUCCESS;
796}
797
Philipp Maier9fc8a022019-02-20 12:26:52 +0100798DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
799 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
800 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
801{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200802 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200803 OSMO_ASSERT(trunk);
804 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100805 return CMD_SUCCESS;
806}
807
808DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
809 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
810 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
811{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200812 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200813 OSMO_ASSERT(trunk);
814 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100815 return CMD_SUCCESS;
816}
817
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200818DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200819 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200820{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200821 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200822 OSMO_ASSERT(trunk);
823 trunk->force_constant_ssrc = 0;
824 trunk->force_aligned_timing = 0;
825 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200826 return CMD_SUCCESS;
827}
828
829DEFUN(cfg_mgcp_rtp_keepalive,
830 cfg_mgcp_rtp_keepalive_cmd,
831 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200832 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200833{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200834 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200835 OSMO_ASSERT(trunk);
836 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200837 return CMD_SUCCESS;
838}
839
840DEFUN(cfg_mgcp_rtp_keepalive_once,
841 cfg_mgcp_rtp_keepalive_once_cmd,
842 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200843 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200844{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200845 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200846 OSMO_ASSERT(trunk);
847 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200848 return CMD_SUCCESS;
849}
850
851DEFUN(cfg_mgcp_no_rtp_keepalive,
852 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200853 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200854{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200855 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200856 OSMO_ASSERT(trunk);
857 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200858 return CMD_SUCCESS;
859}
860
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200861#define CALL_AGENT_STR "Call agent information\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200862DEFUN(cfg_mgcp_agent_addr,
863 cfg_mgcp_agent_addr_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200864 "call-agent ip " VTY_IPV46_CMD,
865 CALL_AGENT_STR IP_STR
866 "IPv4 Address of the call agent\n"
867 "IPv6 Address of the call agent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200868{
869 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
870 return CMD_SUCCESS;
871}
872
873ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200874 "call agent ip A.B.C.D",
875 CALL_AGENT_STR CALL_AGENT_STR IP_STR
876 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200877
Philipp Maier21be42a2020-05-29 21:39:48 +0200878DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier0653cc82020-08-10 22:52:51 +0200879 "trunk <0-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200880{
Philipp Maier14b27a82020-06-02 20:15:30 +0200881 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200882 int index = atoi(argv[0]);
883
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200884 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100885 if (!trunk) {
886 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200887 if (!trunk) {
888 vty_out(vty, "%%Unable to allocate trunk %u.%s",
889 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100890 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200891 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200892 }
893
894 vty->node = TRUNK_NODE;
895 vty->index = trunk;
896 return CMD_SUCCESS;
897}
898
899static int config_write_trunk(struct vty *vty)
900{
Philipp Maier14b27a82020-06-02 20:15:30 +0200901 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200902
903 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200904
905 /* Due to historical reasons, the virtual trunk is configured
906 using separate VTY parameters, so we omit writing the trunk
907 config of trunk 0 here. The configuration for the virtual
908 trunk is written by config_write_mgcp(). */
909
910 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
911 continue;
912
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200913 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200914 vty_out(vty, " line %u%s", trunk->e1.vty_line_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200915 vty_out(vty, " %ssdp audio-payload send-ptime%s",
916 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
917 vty_out(vty, " %ssdp audio-payload send-name%s",
918 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
919
920 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
921 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
922 else if (trunk->keepalive_interval)
923 vty_out(vty, " rtp keep-alive %d%s",
924 trunk->keepalive_interval, VTY_NEWLINE);
925 else
926 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200927 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200928 vty_out(vty, " force-realloc %d%s",
929 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200930 vty_out(vty, " rtp-accept-all %d%s",
931 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200932 if (trunk->omit_rtcp)
933 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
934 else
935 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100936 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200937 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200938 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200939 trunk->force_constant_ssrc ? "" : "no ",
940 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200941 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200942 trunk->force_aligned_timing ? "" : "no ",
943 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100944 vty_out(vty, " %srtp-patch rfc5993hr%s",
945 trunk->rfc5993_hr_convert ? "" : "no ",
946 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200947 } else
948 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
949 if (trunk->audio_fmtp_extra)
950 vty_out(vty, " sdp audio fmtp-extra %s%s",
951 trunk->audio_fmtp_extra, VTY_NEWLINE);
952 vty_out(vty, " %sallow-transcoding%s",
953 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
954 }
955
956 return CMD_SUCCESS;
957}
958
959DEFUN(cfg_trunk_sdp_fmtp_extra,
960 cfg_trunk_sdp_fmtp_extra_cmd,
961 "sdp audio fmtp-extra .NAME",
962 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
963 "Extra Information\n")
964{
Philipp Maier14b27a82020-06-02 20:15:30 +0200965 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200966 char *txt = argv_concat(argv, argc, 0);
967 if (!txt)
968 return CMD_WARNING;
969
970 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
971 talloc_free(txt);
972 return CMD_SUCCESS;
973}
974
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200975DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200976 cfg_trunk_payload_number_cmd,
977 "sdp audio-payload number <0-255>",
978 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
979{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200980 return CMD_SUCCESS;
981}
982
983ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200984 "sdp audio payload number <0-255>",
985 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200986
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200987DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200988 cfg_trunk_payload_name_cmd,
989 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200990 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200991{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200992 return CMD_SUCCESS;
993}
994
995ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200996 "sdp audio payload name NAME",
997 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200998
Philipp Maier21be42a2020-05-29 21:39:48 +0200999DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000 cfg_trunk_loop_cmd,
1001 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001002 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001003{
Philipp Maier14b27a82020-06-02 20:15:30 +02001004 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001005
1006 if (g_cfg->osmux) {
1007 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
1008 return CMD_WARNING;
1009 }
1010 trunk->audio_loop = atoi(argv[0]);
1011 return CMD_SUCCESS;
1012}
1013
1014DEFUN(cfg_trunk_sdp_payload_send_ptime,
1015 cfg_trunk_sdp_payload_send_ptime_cmd,
1016 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001017 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001018{
Philipp Maier14b27a82020-06-02 20:15:30 +02001019 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001020 trunk->audio_send_ptime = 1;
1021 return CMD_SUCCESS;
1022}
1023
1024DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1025 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1026 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001027 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001028{
Philipp Maier14b27a82020-06-02 20:15:30 +02001029 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001030 trunk->audio_send_ptime = 0;
1031 return CMD_SUCCESS;
1032}
1033
1034DEFUN(cfg_trunk_sdp_payload_send_name,
1035 cfg_trunk_sdp_payload_send_name_cmd,
1036 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001037 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001038{
Philipp Maier14b27a82020-06-02 20:15:30 +02001039 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001040 trunk->audio_send_name = 1;
1041 return CMD_SUCCESS;
1042}
1043
1044DEFUN(cfg_trunk_no_sdp_payload_send_name,
1045 cfg_trunk_no_sdp_payload_send_name_cmd,
1046 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001047 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001048{
Philipp Maier14b27a82020-06-02 20:15:30 +02001049 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001050 trunk->audio_send_name = 0;
1051 return CMD_SUCCESS;
1052}
1053
Philipp Maier87bd9be2017-08-22 16:35:41 +02001054DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001055{
Philipp Maier14b27a82020-06-02 20:15:30 +02001056 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001057 trunk->omit_rtcp = 1;
1058 return CMD_SUCCESS;
1059}
1060
1061DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001062 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001063{
Philipp Maier14b27a82020-06-02 20:15:30 +02001064 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001065 trunk->omit_rtcp = 0;
1066 return CMD_SUCCESS;
1067}
1068
1069DEFUN(cfg_trunk_patch_rtp_ssrc,
1070 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001071 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001072{
Philipp Maier14b27a82020-06-02 20:15:30 +02001073 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001074 trunk->force_constant_ssrc = 1;
1075 return CMD_SUCCESS;
1076}
1077
1078DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1079 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001080 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001081{
Philipp Maier14b27a82020-06-02 20:15:30 +02001082 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001083 trunk->force_constant_ssrc = 0;
1084 return CMD_SUCCESS;
1085}
1086
1087DEFUN(cfg_trunk_patch_rtp_ts,
1088 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001089 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001090{
Philipp Maier14b27a82020-06-02 20:15:30 +02001091 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001092 trunk->force_aligned_timing = 1;
1093 return CMD_SUCCESS;
1094}
1095
1096DEFUN(cfg_trunk_no_patch_rtp_ts,
1097 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001098 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001099{
Philipp Maier14b27a82020-06-02 20:15:30 +02001100 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001101 trunk->force_aligned_timing = 0;
1102 return CMD_SUCCESS;
1103}
1104
Philipp Maier9fc8a022019-02-20 12:26:52 +01001105DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1106 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1107 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1108{
Philipp Maier14b27a82020-06-02 20:15:30 +02001109 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001110 trunk->rfc5993_hr_convert = true;
1111 return CMD_SUCCESS;
1112}
1113
1114DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1115 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1116 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1117{
Philipp Maier14b27a82020-06-02 20:15:30 +02001118 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001119 trunk->rfc5993_hr_convert = false;
1120 return CMD_SUCCESS;
1121}
1122
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001123DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001124 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001125{
Philipp Maier14b27a82020-06-02 20:15:30 +02001126 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001127 trunk->force_constant_ssrc = 0;
1128 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001129 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001130 return CMD_SUCCESS;
1131}
1132
1133DEFUN(cfg_trunk_rtp_keepalive,
1134 cfg_trunk_rtp_keepalive_cmd,
1135 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001136 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001137{
Philipp Maier14b27a82020-06-02 20:15:30 +02001138 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001139 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1140 return CMD_SUCCESS;
1141}
1142
1143DEFUN(cfg_trunk_rtp_keepalive_once,
1144 cfg_trunk_rtp_keepalive_once_cmd,
1145 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001146 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001147{
Philipp Maier14b27a82020-06-02 20:15:30 +02001148 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001149 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1150 return CMD_SUCCESS;
1151}
1152
1153DEFUN(cfg_trunk_no_rtp_keepalive,
1154 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001155 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001156{
Philipp Maier14b27a82020-06-02 20:15:30 +02001157 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001158 mgcp_trunk_set_keepalive(trunk, 0);
1159 return CMD_SUCCESS;
1160}
1161
1162DEFUN(cfg_trunk_allow_transcoding,
1163 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001164 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001165{
Philipp Maier14b27a82020-06-02 20:15:30 +02001166 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001167 trunk->no_audio_transcoding = 0;
1168 return CMD_SUCCESS;
1169}
1170
1171DEFUN(cfg_trunk_no_allow_transcoding,
1172 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001173 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001174{
Philipp Maier14b27a82020-06-02 20:15:30 +02001175 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001176 trunk->no_audio_transcoding = 1;
1177 return CMD_SUCCESS;
1178}
1179
Philipp Maier889fe7f2020-07-06 17:44:12 +02001180#define LINE_STR "Configure trunk for given Line\nE1/T1 Line Number\n"
1181
1182DEFUN(cfg_trunk_line,
1183 cfg_trunk_line_cmd,
1184 "line <0-255>",
1185 LINE_STR)
1186{
1187 struct mgcp_trunk *trunk = vty->index;
1188 int line_nr = atoi(argv[0]);
1189 trunk->e1.vty_line_nr = line_nr;
1190 return CMD_SUCCESS;
1191}
1192
Philipp Maier87bd9be2017-08-22 16:35:41 +02001193DEFUN(loop_conn,
1194 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001195 "loop-endpoint <0-64> NAME (0|1)",
1196 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001197 "The name in hex of the endpoint\n" "Disable the loop\n"
1198 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001199{
Philipp Maier14b27a82020-06-02 20:15:30 +02001200 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001201 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001202 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001203
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001204 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001205 if (!trunk) {
1206 vty_out(vty, "%%Trunk %d not found in the config.%s",
1207 atoi(argv[0]), VTY_NEWLINE);
1208 return CMD_WARNING;
1209 }
1210
1211 if (!trunk->endpoints) {
1212 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1213 trunk->trunk_nr, VTY_NEWLINE);
1214 return CMD_WARNING;
1215 }
1216
1217 int endp_no = strtoul(argv[1], NULL, 16);
1218 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1219 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001220 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001221 return CMD_WARNING;
1222 }
1223
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001224 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001225 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001226 llist_for_each_entry(conn, &endp->conns, entry) {
1227 if (conn->type == MGCP_CONN_TYPE_RTP)
1228 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1229 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1230 else {
1231 /* FIXME: Introduce support for other connection (E1)
1232 * types when implementation is available */
1233 vty_out(vty, "%%Can't enable SSRC patching,"
1234 "connection %s is not an RTP connection.%s",
1235 mgcp_conn_dump(conn), VTY_NEWLINE);
1236 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001237
Philipp Maier87bd9be2017-08-22 16:35:41 +02001238 if (loop)
1239 conn->mode = MGCP_CONN_LOOPBACK;
1240 else
1241 conn->mode = conn->mode_orig;
1242 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001243
1244 return CMD_SUCCESS;
1245}
1246
Philipp Maier87bd9be2017-08-22 16:35:41 +02001247DEFUN(tap_rtp,
1248 tap_rtp_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001249 "tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001250 "Forward data on endpoint to a different system\n" "Trunk number\n"
1251 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001252 "The connection id in hex\n"
1253 "Forward incoming data\n"
1254 "Forward leaving data\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001255 "Destination IPv4 of the data\n"
1256 "Destination IPv6 of the data\n"
1257 "Destination port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001258{
1259 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001260 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001261 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001262 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001263 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001264
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001265 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001266 if (!trunk) {
1267 vty_out(vty, "%%Trunk %d not found in the config.%s",
1268 atoi(argv[0]), VTY_NEWLINE);
1269 return CMD_WARNING;
1270 }
1271
1272 if (!trunk->endpoints) {
1273 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1274 trunk->trunk_nr, VTY_NEWLINE);
1275 return CMD_WARNING;
1276 }
1277
1278 int endp_no = strtoul(argv[1], NULL, 16);
1279 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1280 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001281 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001282 return CMD_WARNING;
1283 }
1284
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001285 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001286
Philipp Maier01d24a32017-11-21 17:26:09 +01001287 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001288 conn = mgcp_conn_get_rtp(endp, conn_id);
1289 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001290 vty_out(vty, "Conn ID %s is invalid.%s",
1291 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001292 return CMD_WARNING;
1293 }
1294
1295 if (strcmp(argv[3], "in") == 0)
1296 tap = &conn->tap_in;
1297 else if (strcmp(argv[3], "out") == 0)
1298 tap = &conn->tap_out;
1299 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001300 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1301 return CMD_WARNING;
1302 }
1303
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001304 memset(&tap->forward, 0, sizeof(tap->forward));
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001305
1306 tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);
1307 switch (tap->forward.u.sa.sa_family) {
1308 case AF_INET:
1309 if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)
1310 return CMD_WARNING;
1311 tap->forward.u.sin.sin_port = htons(atoi(argv[5]));
1312 break;
1313 case AF_INET6:
1314 if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)
1315 return CMD_WARNING;
1316 tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));
1317 break;
1318 default:
1319 return CMD_WARNING;
1320 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001321 tap->enabled = 1;
1322 return CMD_SUCCESS;
1323}
1324
1325DEFUN(free_endp, free_endp_cmd,
1326 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001327 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001328{
Philipp Maier14b27a82020-06-02 20:15:30 +02001329 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001330 struct mgcp_endpoint *endp;
1331
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001332 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001333 if (!trunk) {
1334 vty_out(vty, "%%Trunk %d not found in the config.%s",
1335 atoi(argv[0]), VTY_NEWLINE);
1336 return CMD_WARNING;
1337 }
1338
1339 if (!trunk->endpoints) {
1340 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1341 trunk->trunk_nr, VTY_NEWLINE);
1342 return CMD_WARNING;
1343 }
1344
1345 int endp_no = strtoul(argv[1], NULL, 16);
1346 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1347 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001348 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001349 return CMD_WARNING;
1350 }
1351
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001352 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001353 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001354 return CMD_SUCCESS;
1355}
1356
1357DEFUN(reset_endp, reset_endp_cmd,
1358 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001359 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001360{
Philipp Maier14b27a82020-06-02 20:15:30 +02001361 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001362 struct mgcp_endpoint *endp;
1363 int endp_no, rc;
1364
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001365 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001366 if (!trunk) {
1367 vty_out(vty, "%%Trunk %d not found in the config.%s",
1368 atoi(argv[0]), VTY_NEWLINE);
1369 return CMD_WARNING;
1370 }
1371
1372 if (!trunk->endpoints) {
1373 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1374 trunk->trunk_nr, VTY_NEWLINE);
1375 return CMD_WARNING;
1376 }
1377
1378 endp_no = strtoul(argv[1], NULL, 16);
1379 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1380 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001381 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001382 return CMD_WARNING;
1383 }
1384
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001385 endp = trunk->endpoints[endp_no];
1386 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001387 if (rc < 0) {
1388 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1389 return CMD_WARNING;
1390 }
1391 return CMD_SUCCESS;
1392}
1393
1394DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001395 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001396{
1397 int rc;
1398
1399 rc = mgcp_send_reset_all(g_cfg);
1400 if (rc < 0) {
1401 vty_out(vty, "Error %d during endpoint reset.%s",
1402 rc, VTY_NEWLINE);
1403 return CMD_WARNING;
1404 }
1405 return CMD_SUCCESS;
1406}
1407
1408#define OSMUX_STR "RTP multiplexing\n"
1409DEFUN(cfg_mgcp_osmux,
1410 cfg_mgcp_osmux_cmd,
1411 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001412 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001413{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001414 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001415 OSMO_ASSERT(trunk);
1416
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001417 if (strcmp(argv[0], "off") == 0) {
1418 g_cfg->osmux = OSMUX_USAGE_OFF;
1419 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001420 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001421 g_cfg->osmux = OSMUX_USAGE_ON;
1422 else if (strcmp(argv[0], "only") == 0)
1423 g_cfg->osmux = OSMUX_USAGE_ONLY;
1424
Philipp Maierd19de2e2020-06-03 13:55:33 +02001425 if (trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001426 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001427 return CMD_WARNING;
1428 }
1429
1430 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001431
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001432}
1433
1434DEFUN(cfg_mgcp_osmux_ip,
1435 cfg_mgcp_osmux_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001436 "osmux bind-ip " VTY_IPV46_CMD,
1437 OSMUX_STR IP_STR
1438 "IPv4 Address to bind to\n"
1439 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001440{
1441 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1442 return CMD_SUCCESS;
1443}
1444
1445DEFUN(cfg_mgcp_osmux_batch_factor,
1446 cfg_mgcp_osmux_batch_factor_cmd,
1447 "osmux batch-factor <1-8>",
1448 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1449{
1450 g_cfg->osmux_batch = atoi(argv[0]);
1451 return CMD_SUCCESS;
1452}
1453
1454DEFUN(cfg_mgcp_osmux_batch_size,
1455 cfg_mgcp_osmux_batch_size_cmd,
1456 "osmux batch-size <1-65535>",
1457 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1458{
1459 g_cfg->osmux_batch_size = atoi(argv[0]);
1460 return CMD_SUCCESS;
1461}
1462
1463DEFUN(cfg_mgcp_osmux_port,
1464 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001465 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001466{
1467 g_cfg->osmux_port = atoi(argv[0]);
1468 return CMD_SUCCESS;
1469}
1470
1471DEFUN(cfg_mgcp_osmux_dummy,
1472 cfg_mgcp_osmux_dummy_cmd,
1473 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001474 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1475 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001476{
1477 if (strcmp(argv[0], "on") == 0)
1478 g_cfg->osmux_dummy = 1;
1479 else if (strcmp(argv[0], "off") == 0)
1480 g_cfg->osmux_dummy = 0;
1481
1482 return CMD_SUCCESS;
1483}
1484
Philipp Maier12943ea2018-01-17 15:40:25 +01001485DEFUN(cfg_mgcp_domain,
1486 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001487 "domain NAME",
1488 "Set the domain part expected in MGCP messages' endpoint names\n"
1489 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001490{
1491 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1492 return CMD_SUCCESS;
1493}
1494
Oliver Smithe36b7752019-01-22 16:31:36 +01001495DEFUN(cfg_mgcp_conn_timeout,
1496 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001497 "conn-timeout <0-65534>",
1498 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1499 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001500 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1501 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001502 "Timeout value (sec.)\n")
1503{
1504 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1505 return CMD_SUCCESS;
1506}
1507
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001508int mgcp_vty_init(void)
1509{
1510 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001511 install_element_ve(&show_mgcp_endpoint_cmd);
1512 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001513 install_element(ENABLE_NODE, &loop_conn_cmd);
1514 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001515 install_element(ENABLE_NODE, &free_endp_cmd);
1516 install_element(ENABLE_NODE, &reset_endp_cmd);
1517 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1518
1519 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1520 install_node(&mgcp_node, config_write_mgcp);
1521
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001522 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001523 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1524 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1525 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001526 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001527 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001528 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001529 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001530 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001531 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001532 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1533 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001534 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1535 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1536 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1537 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1538 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1539 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1540 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1541 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1542 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001543 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1544 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1545 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1546 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1547 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1548 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001549 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001550 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1551 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1552 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1553 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1554 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1555 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1556 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1557 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001558 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1559 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001560 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1561 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1562 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1563 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1564 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1565 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1566 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1567 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1568 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1569 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1570 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1571 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1572 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001573 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001574 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001575
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001576 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1577 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001578 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1579 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1580 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1581 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1582 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1583 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1584 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1585 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1586 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1587 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1588 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1589 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1590 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001591 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1592 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001593 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1594 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1595 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1596 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1597 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1598 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1599 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1600 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1601 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001602 install_element(TRUNK_NODE, &cfg_trunk_line_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001603
1604 return 0;
1605}
1606
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001607int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1608 enum mgcp_role role)
1609{
1610 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001611 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001612
1613 cfg->osmux_port = OSMUX_PORT;
1614 cfg->osmux_batch = 4;
1615 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1616
1617 g_cfg = cfg;
1618 rc = vty_read_config_file(config_file, NULL);
1619 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001620 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1621 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001622 return rc;
1623 }
1624
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001625 if (!g_cfg->source_addr) {
1626 fprintf(stderr, "You need to specify a bind address.\n");
1627 return -1;
1628 }
1629
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001630 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier889fe7f2020-07-06 17:44:12 +02001631 if (mgcp_trunk_equip(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001632 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001633 "Failed to initialize trunk %d (%d endpoints)\n",
1634 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001635 return -1;
1636 }
1637 }
1638 cfg->role = role;
1639
1640 return 0;
1641}