blob: cc7c5b864c10703a5faaaadd24832a66bee63964 [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);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +020074 if (g_cfg->net_ports.bind_addr_v4)
Philipp Maierf53796c2020-06-02 20:38:28 +020075 vty_out(vty, " rtp bind-ip %s%s",
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +020076 g_cfg->net_ports.bind_addr_v4, VTY_NEWLINE);
77 if (g_cfg->net_ports.bind_addr_v6)
78 vty_out(vty, " rtp bind-ip-v6 %s%s",
79 g_cfg->net_ports.bind_addr_v6, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010080 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020081 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010082 else
Philipp Maierf53796c2020-06-02 20:38:28 +020083 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
84 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010085 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020086 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010087 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020088 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010089 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020090 else
Philipp Maierf53796c2020-06-02 20:38:28 +020091 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020092
Harald Weltec39b1bf2020-03-08 11:29:39 +010093 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +020094 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020095 else
Philipp Maierf53796c2020-06-02 20:38:28 +020096 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010097 if (trunk->force_constant_ssrc
98 || trunk->force_aligned_timing
99 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200100 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100101 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200102 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200103 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100104 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200105 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200106 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100107 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100108 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200109 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200110 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100111 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200112 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100113 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200114 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100115 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200116 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100117 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200118 vty_out(vty, " number endpoints %u%s",
Philipp Maier889fe7f2020-07-06 17:44:12 +0200119 trunk->v.vty_number_endpoints, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200120 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100121 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200122 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200123 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200124 VTY_NEWLINE);
125 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200126 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200127 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200128
129 switch (g_cfg->osmux) {
130 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200131 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200132 break;
133 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200134 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200135 break;
136 case OSMUX_USAGE_OFF:
137 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200138 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200139 break;
140 }
141 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200142 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200143 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200144 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200145 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200146 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200147 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200148 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200149 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200150 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200151 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
152 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100153
154 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200155 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100156
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200157 return CMD_SUCCESS;
158}
159
Philipp Maiercede2a42018-07-03 14:14:21 +0200160static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200161{
Philipp Maiercede2a42018-07-03 14:14:21 +0200162 struct mgcp_rtp_state *state = &conn->state;
163 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200164 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100165 struct rate_ctr *tx_packets, *tx_bytes;
166 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200167 struct rate_ctr *dropped_packets;
168
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100169 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
170 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
171 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
172 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200173 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200174
175 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100176 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
177 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200178 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
179 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200180 " Payload Type: %d Rate: %u Channels: %d %s"
181 " Frame Duration: %u Frame Denominator: %u%s"
182 " FPP: %d Packet Duration: %u%s"
183 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
184 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100185 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
186 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200187 state->in_stream.err_ts_ctr->current,
188 state->out_stream.err_ts_ctr->current,
189 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200190 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200191 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200192 codec->frame_duration_num, codec->frame_duration_den,
193 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
194 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
195 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
196 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200197}
198
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200199static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200200 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200201{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200202 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200203
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200204 vty_out(vty, "%s trunk %d endpoint %s:%s",
205 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Philipp Maier8d6a1932020-06-18 12:19:31 +0200206 vty_out(vty, " Availability: %s%s",
207 mgcp_endp_avail(endp) ? "available" : "not in service", VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200208
209 if (llist_empty(&endp->conns)) {
210 vty_out(vty, " No active connections%s", VTY_NEWLINE);
211 return;
212 }
213
214 llist_for_each_entry(conn, &endp->conns, entry) {
215 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
216
217 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100218 if (endp->cfg->conn_timeout) {
219 struct timeval remaining;
220 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
221 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
222 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
223 }
224
Stefan Sperling12086582018-06-26 15:26:28 +0200225 /* FIXME: Also add verbosity for other
226 * connection types (E1) as soon as
227 * the implementation is available */
228 if (conn->type == MGCP_CONN_TYPE_RTP) {
229 dump_rtp_end(vty, &conn->u.rtp);
230 }
231 }
232 }
233}
234
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200235static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
236{
237 vty_out(vty, "%s", VTY_NEWLINE);
238 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
239
240 if (ratectr->mgcp_general_ctr_group) {
241 vty_out(vty, " %s:%s",
242 ratectr->mgcp_general_ctr_group->desc->
243 group_description, VTY_NEWLINE);
244 vty_out_rate_ctr_group_fmt(vty,
245 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
246 ratectr->mgcp_general_ctr_group);
247 }
248}
249
Philipp Maier889fe7f2020-07-06 17:44:12 +0200250static void dump_ratectr_trunk(struct vty *vty, struct mgcp_trunk *trunk)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200251{
Philipp Maier889fe7f2020-07-06 17:44:12 +0200252 struct mgcp_ratectr_trunk *ratectr = &trunk->ratectr;
253
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200254 vty_out(vty, "%s", VTY_NEWLINE);
255 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
256
257 if (ratectr->mgcp_crcx_ctr_group) {
258 vty_out(vty, " %s:%s",
259 ratectr->mgcp_crcx_ctr_group->desc->group_description,
260 VTY_NEWLINE);
261 vty_out_rate_ctr_group_fmt(vty,
262 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
263 ratectr->mgcp_crcx_ctr_group);
264 }
265 if (ratectr->mgcp_dlcx_ctr_group) {
266 vty_out(vty, " %s:%s",
267 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
268 VTY_NEWLINE);
269 vty_out_rate_ctr_group_fmt(vty,
270 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
271 ratectr->mgcp_dlcx_ctr_group);
272 }
273 if (ratectr->mgcp_mdcx_ctr_group) {
274 vty_out(vty, " %s:%s",
275 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
276 VTY_NEWLINE);
277 vty_out_rate_ctr_group_fmt(vty,
278 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
279 ratectr->mgcp_mdcx_ctr_group);
280 }
281 if (ratectr->all_rtp_conn_stats) {
282 vty_out(vty, " %s:%s",
283 ratectr->all_rtp_conn_stats->desc->group_description,
284 VTY_NEWLINE);
285 vty_out_rate_ctr_group_fmt(vty,
286 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
287 ratectr->all_rtp_conn_stats);
288 }
Philipp Maier889fe7f2020-07-06 17:44:12 +0200289
290 if (ratectr->e1_stats && trunk->trunk_type == MGCP_TRUNK_E1) {
291 vty_out(vty, " %s:%s",
292 ratectr->e1_stats->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->e1_stats);
297 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200298}
299
300
301static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200302{
303 int i;
304
305 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200306 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
Philipp Maier869b21c2020-07-03 16:04:16 +0200307 trunk->trunk_nr, trunk->number_endpoints, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200308
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200309 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200310 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
311 return;
312 }
313
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200314 for (i = 0; i < trunk->number_endpoints; ++i) {
315 struct mgcp_endpoint *endp = trunk->endpoints[i];
316 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
317 show_stats);
318 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200319 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200320 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200321
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200322 if (show_stats)
Philipp Maier889fe7f2020-07-06 17:44:12 +0200323 dump_ratectr_trunk(vty, trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200324}
325
Stefan Sperling12086582018-06-26 15:26:28 +0200326#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
327
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200328DEFUN(show_mcgp, show_mgcp_cmd,
329 "show mgcp [stats]",
330 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200331 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200332 "Include Statistics\n")
333{
Philipp Maier14b27a82020-06-02 20:15:30 +0200334 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200335 int show_stats = argc >= 1;
336
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200337 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200338 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200339
340 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200341 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200342 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200343
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200344 if (show_stats)
345 dump_ratectr_global(vty, &g_cfg->ratectr);
346
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200347 return CMD_SUCCESS;
348}
349
Stefan Sperling12086582018-06-26 15:26:28 +0200350static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200351dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200352{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200353 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200354
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200355 if (trunk) {
356 /* If a trunk is given, search on that specific trunk only */
357 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
358 if (!endp) {
359 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
360 return;
361 }
362 } else {
363 /* If no trunk is given, search on all possible trunks */
364 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
365 if (!endp) {
366 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
367 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200368 }
369 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200370
371 trunk = endp->trunk;
372 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200373}
374
375DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
376 "show mgcp endpoint NAME",
377 SHOW_STR
378 SHOW_MGCP_STR
379 "Display information about an endpoint\n" "The name of the endpoint\n")
380{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200381 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200382 return CMD_SUCCESS;
383}
384
385DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
386 "show mgcp trunk <0-64> endpoint NAME",
387 SHOW_STR
388 SHOW_MGCP_STR
389 "Display information about a trunk\n" "Trunk number\n"
390 "Display information about an endpoint\n" "The name of the endpoint\n")
391{
Philipp Maier14b27a82020-06-02 20:15:30 +0200392 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200393 int trunkidx = atoi(argv[0]);
394
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200395 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200396 if (!trunk) {
397 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
398 return CMD_WARNING;
399 }
400
401 dump_mgcp_endpoint(vty, trunk, argv[1]);
402 return CMD_SUCCESS;
403}
404
Philipp Maier87bd9be2017-08-22 16:35:41 +0200405DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200406{
407 vty->node = MGCP_NODE;
408 return CMD_SUCCESS;
409}
410
411DEFUN(cfg_mgcp_local_ip,
412 cfg_mgcp_local_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200413 "local ip " VTY_IPV46_CMD,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200414 "Local options for the SDP record\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200415 IP_STR
416 "IPv4 Address to use in SDP record\n"
417 "IPv6 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200418{
419 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
420 return CMD_SUCCESS;
421}
422
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200423#define BIND_STR "Listen/Bind related socket option\n"
424DEFUN(cfg_mgcp_bind_ip,
425 cfg_mgcp_bind_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200426 "bind ip " VTY_IPV46_CMD,
427 BIND_STR IP_STR
428 "IPv4 Address to bind to\n"
429 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200430{
431 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
432 return CMD_SUCCESS;
433}
434
435DEFUN(cfg_mgcp_bind_port,
436 cfg_mgcp_bind_port_cmd,
437 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200438 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200439{
440 unsigned int port = atoi(argv[0]);
441 g_cfg->source_port = port;
442 return CMD_SUCCESS;
443}
444
445DEFUN(cfg_mgcp_bind_early,
446 cfg_mgcp_bind_early_cmd,
447 "bind early (0|1)",
448 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200449 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200450{
451 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
452 return CMD_WARNING;
453}
454
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200455#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200456#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200457#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200458#define RANGE_START_STR "Start of the range of ports\n"
459#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200460
Philipp Maierf1889d82017-11-08 14:59:39 +0100461DEFUN(cfg_mgcp_rtp_port_range,
462 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200463 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200464 RTP_STR "Range of ports to use for the NET side\n"
465 RANGE_START_STR RANGE_END_STR)
466{
Philipp Maiera19547b2018-05-22 13:44:34 +0200467 int start;
468 int end;
469
470 start = atoi(argv[0]);
471 end = atoi(argv[1]);
472
473 if (end < start) {
474 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
475 end, start, VTY_NEWLINE);
476 return CMD_WARNING;
477 }
478
479 if (start & 1) {
480 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
481 start, start & 0xFFFE, VTY_NEWLINE);
482 start &= 0xFFFE;
483 }
484
485 if ((end & 1) == 0) {
486 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
487 end, end | 1, VTY_NEWLINE);
488 end |= 1;
489 }
490
491 g_cfg->net_ports.range_start = start;
492 g_cfg->net_ports.range_end = end;
493 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
494
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200495 return CMD_SUCCESS;
496}
Philipp Maierf1889d82017-11-08 14:59:39 +0100497ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
498 cfg_mgcp_rtp_net_range_cmd,
499 "rtp net-range <0-65534> <0-65534>",
500 RTP_STR "Range of ports to use for the NET side\n"
501 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200502
Philipp Maierf1889d82017-11-08 14:59:39 +0100503DEFUN(cfg_mgcp_rtp_bind_ip,
504 cfg_mgcp_rtp_bind_ip_cmd,
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200505 "rtp bind-ip A.B.C.D",
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200506 RTP_STR "Bind endpoints facing the Network\n"
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200507 "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200508{
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200509 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v4, argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200510 return CMD_SUCCESS;
511}
Philipp Maierf1889d82017-11-08 14:59:39 +0100512ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
513 cfg_mgcp_rtp_net_bind_ip_cmd,
514 "rtp net-bind-ip A.B.C.D",
515 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200516
Philipp Maierf1889d82017-11-08 14:59:39 +0100517DEFUN(cfg_mgcp_rtp_no_bind_ip,
518 cfg_mgcp_rtp_no_bind_ip_cmd,
519 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200520 NO_STR RTP_STR "Bind endpoints facing the Network\n"
521 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200522{
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200523 talloc_free(g_cfg->net_ports.bind_addr_v4);
524 g_cfg->net_ports.bind_addr_v4 = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200525 return CMD_SUCCESS;
526}
Philipp Maierf1889d82017-11-08 14:59:39 +0100527ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
528 cfg_mgcp_rtp_no_net_bind_ip_cmd,
529 "no rtp net-bind-ip",
530 NO_STR RTP_STR "Bind endpoints facing the Network\n"
531 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200532
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200533DEFUN(cfg_mgcp_rtp_bind_ip_v6,
534 cfg_mgcp_rtp_bind_ip_v6_cmd,
535 "rtp bind-ip-v6 " VTY_IPV6_CMD,
536 RTP_STR "Bind endpoints facing the Network\n"
537 "IPv6 Address to bind to\n")
538{
539 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v6, argv[0]);
540 return CMD_SUCCESS;
541}
542
543DEFUN(cfg_mgcp_rtp_no_bind_ip_v6,
544cfg_mgcp_rtp_no_bind_ip_v6_cmd,
545"no rtp bind-ip-v6",
546NO_STR RTP_STR "Bind endpoints facing the Network\n"
547"Address to bind to\n")
548{
549 talloc_free(g_cfg->net_ports.bind_addr_v6);
550 g_cfg->net_ports.bind_addr_v6 = NULL;
551 return CMD_SUCCESS;
552}
553
Philipp Maier1cb1e382017-11-02 17:16:04 +0100554DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
555 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
556 "rtp ip-probing",
557 RTP_STR "automatic rtp bind ip selection\n")
558{
559 g_cfg->net_ports.bind_addr_probe = true;
560 return CMD_SUCCESS;
561}
562
563DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
564 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
565 "no rtp ip-probing",
566 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
567{
568 g_cfg->net_ports.bind_addr_probe = false;
569 return CMD_SUCCESS;
570}
571
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200572DEFUN(cfg_mgcp_rtp_ip_dscp,
573 cfg_mgcp_rtp_ip_dscp_cmd,
574 "rtp ip-dscp <0-255>",
575 RTP_STR
576 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
577{
578 int dscp = atoi(argv[0]);
579 g_cfg->endp_dscp = dscp;
580 return CMD_SUCCESS;
581}
582
583ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200584 "rtp ip-tos <0-255>",
585 RTP_STR
586 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
587#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200588DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200589 cfg_mgcp_rtp_force_ptime_cmd,
590 "rtp force-ptime (10|20|40)",
591 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200592 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200593{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200594 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200595 return CMD_SUCCESS;
596}
597
598DEFUN(cfg_mgcp_no_rtp_force_ptime,
599 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200600 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200601{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200602 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200603 return CMD_SUCCESS;
604}
605
606DEFUN(cfg_mgcp_sdp_fmtp_extra,
607 cfg_mgcp_sdp_fmtp_extra_cmd,
608 "sdp audio fmtp-extra .NAME",
609 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
610 "Extra Information\n")
611{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200612 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200613 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200614 char *txt = argv_concat(argv, argc, 0);
615 if (!txt)
616 return CMD_WARNING;
617
Philipp Maierd19de2e2020-06-03 13:55:33 +0200618 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200619 talloc_free(txt);
620 return CMD_SUCCESS;
621}
622
623DEFUN(cfg_mgcp_allow_transcoding,
624 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200625 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200626{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200627 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200628 OSMO_ASSERT(trunk);
629 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200630 return CMD_SUCCESS;
631}
632
633DEFUN(cfg_mgcp_no_allow_transcoding,
634 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200635 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200636{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200637 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200638 OSMO_ASSERT(trunk);
639 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200640 return CMD_SUCCESS;
641}
642
643#define SDP_STR "SDP File related options\n"
644#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200645DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200646 cfg_mgcp_sdp_payload_number_cmd,
647 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200648 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200649{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200650 return CMD_SUCCESS;
651}
652
Philipp Maier87bd9be2017-08-22 16:35:41 +0200653ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
654 cfg_mgcp_sdp_payload_number_cmd_old,
655 "sdp audio payload number <0-255>",
656 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200657
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200658DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200659 cfg_mgcp_sdp_payload_name_cmd,
660 "sdp audio-payload name NAME",
661 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
662{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200663 return CMD_SUCCESS;
664}
665
666ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200667 "sdp audio payload name NAME",
668 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200669
Philipp Maier21be42a2020-05-29 21:39:48 +0200670DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200671 cfg_mgcp_sdp_payload_send_ptime_cmd,
672 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200673 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\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_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200678 return CMD_SUCCESS;
679}
680
681DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
682 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
683 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200684 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\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_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200689 return CMD_SUCCESS;
690}
691
692DEFUN(cfg_mgcp_sdp_payload_send_name,
693 cfg_mgcp_sdp_payload_send_name_cmd,
694 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200695 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\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);
699 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200700 return CMD_SUCCESS;
701}
702
703DEFUN(cfg_mgcp_no_sdp_payload_send_name,
704 cfg_mgcp_no_sdp_payload_send_name_cmd,
705 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200706 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\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->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200711 return CMD_SUCCESS;
712}
713
Philipp Maierba94b6d2020-09-22 16:14:32 +0200714DEFUN_DEPRECATED(cfg_mgcp_loop,
715 cfg_mgcp_loop_cmd,
716 "loop (0|1)",
717 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200718{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200719 return CMD_SUCCESS;
720}
721
722DEFUN(cfg_mgcp_force_realloc,
723 cfg_mgcp_force_realloc_cmd,
724 "force-realloc (0|1)",
725 "Force endpoint reallocation when the endpoint is still seized\n"
726 "Don't force reallocation\n" "force reallocation\n")
727{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200728 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200729 OSMO_ASSERT(trunk);
730 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200731 return CMD_SUCCESS;
732}
733
Philipp Maier87bd9be2017-08-22 16:35:41 +0200734DEFUN(cfg_mgcp_rtp_accept_all,
735 cfg_mgcp_rtp_accept_all_cmd,
736 "rtp-accept-all (0|1)",
737 "Accept all RTP packets, even when the originating IP/Port does not match\n"
738 "enable filter\n" "disable filter\n")
739{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200740 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200741 OSMO_ASSERT(trunk);
742 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200743 return CMD_SUCCESS;
744}
745
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200746DEFUN(cfg_mgcp_number_endp,
747 cfg_mgcp_number_endp_cmd,
Philipp Maier869b21c2020-07-03 16:04:16 +0200748 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200749 "Number options\n" "Endpoints available\n" "Number endpoints\n")
750{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200751 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200752 OSMO_ASSERT(trunk);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200753 trunk->v.vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200754 return CMD_SUCCESS;
755}
756
Philipp Maier87bd9be2017-08-22 16:35:41 +0200757DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200758{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200759 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200760 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200761 return CMD_SUCCESS;
762}
763
764DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200765 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200766{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200767 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200768 OSMO_ASSERT(trunk);
769 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200770 return CMD_SUCCESS;
771}
772
773DEFUN(cfg_mgcp_patch_rtp_ssrc,
774 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200775 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200776{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200777 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200778 OSMO_ASSERT(trunk);
779 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200780 return CMD_SUCCESS;
781}
782
783DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
784 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200785 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200786{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200787 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200788 OSMO_ASSERT(trunk);
789 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200790 return CMD_SUCCESS;
791}
792
793DEFUN(cfg_mgcp_patch_rtp_ts,
794 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200795 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200796{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200797 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200798 OSMO_ASSERT(trunk);
799 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200800 return CMD_SUCCESS;
801}
802
803DEFUN(cfg_mgcp_no_patch_rtp_ts,
804 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200805 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200806{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200807 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200808 OSMO_ASSERT(trunk);
809 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200810 return CMD_SUCCESS;
811}
812
Philipp Maier9fc8a022019-02-20 12:26:52 +0100813DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
814 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
815 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
816{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200817 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200818 OSMO_ASSERT(trunk);
819 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100820 return CMD_SUCCESS;
821}
822
823DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
824 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
825 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
826{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200827 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200828 OSMO_ASSERT(trunk);
829 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100830 return CMD_SUCCESS;
831}
832
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200833DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200834 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200835{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200836 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200837 OSMO_ASSERT(trunk);
838 trunk->force_constant_ssrc = 0;
839 trunk->force_aligned_timing = 0;
840 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200841 return CMD_SUCCESS;
842}
843
844DEFUN(cfg_mgcp_rtp_keepalive,
845 cfg_mgcp_rtp_keepalive_cmd,
846 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200847 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200848{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200849 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200850 OSMO_ASSERT(trunk);
851 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200852 return CMD_SUCCESS;
853}
854
855DEFUN(cfg_mgcp_rtp_keepalive_once,
856 cfg_mgcp_rtp_keepalive_once_cmd,
857 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200858 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200859{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200860 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200861 OSMO_ASSERT(trunk);
862 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200863 return CMD_SUCCESS;
864}
865
866DEFUN(cfg_mgcp_no_rtp_keepalive,
867 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200868 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200869{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200870 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200871 OSMO_ASSERT(trunk);
872 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200873 return CMD_SUCCESS;
874}
875
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200876#define CALL_AGENT_STR "Call agent information\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200877DEFUN(cfg_mgcp_agent_addr,
878 cfg_mgcp_agent_addr_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200879 "call-agent ip " VTY_IPV46_CMD,
880 CALL_AGENT_STR IP_STR
881 "IPv4 Address of the call agent\n"
882 "IPv6 Address of the call agent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200883{
884 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
885 return CMD_SUCCESS;
886}
887
888ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200889 "call agent ip A.B.C.D",
890 CALL_AGENT_STR CALL_AGENT_STR IP_STR
891 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200892
Philipp Maier21be42a2020-05-29 21:39:48 +0200893DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier0653cc82020-08-10 22:52:51 +0200894 "trunk <0-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200895{
Philipp Maier14b27a82020-06-02 20:15:30 +0200896 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200897 int index = atoi(argv[0]);
898
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200899 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100900 if (!trunk) {
901 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200902 if (!trunk) {
903 vty_out(vty, "%%Unable to allocate trunk %u.%s",
904 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100905 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200906 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200907 }
908
909 vty->node = TRUNK_NODE;
910 vty->index = trunk;
911 return CMD_SUCCESS;
912}
913
914static int config_write_trunk(struct vty *vty)
915{
Philipp Maier14b27a82020-06-02 20:15:30 +0200916 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200917
918 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200919
920 /* Due to historical reasons, the virtual trunk is configured
921 using separate VTY parameters, so we omit writing the trunk
922 config of trunk 0 here. The configuration for the virtual
923 trunk is written by config_write_mgcp(). */
924
925 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
926 continue;
927
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200928 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200929 vty_out(vty, " line %u%s", trunk->e1.vty_line_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200930 vty_out(vty, " %ssdp audio-payload send-ptime%s",
931 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
932 vty_out(vty, " %ssdp audio-payload send-name%s",
933 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
934
935 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
936 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
937 else if (trunk->keepalive_interval)
938 vty_out(vty, " rtp keep-alive %d%s",
939 trunk->keepalive_interval, VTY_NEWLINE);
940 else
941 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200942 vty_out(vty, " force-realloc %d%s",
943 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200944 vty_out(vty, " rtp-accept-all %d%s",
945 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200946 if (trunk->omit_rtcp)
947 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
948 else
949 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100950 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200951 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200952 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200953 trunk->force_constant_ssrc ? "" : "no ",
954 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200955 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200956 trunk->force_aligned_timing ? "" : "no ",
957 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100958 vty_out(vty, " %srtp-patch rfc5993hr%s",
959 trunk->rfc5993_hr_convert ? "" : "no ",
960 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200961 } else
962 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
963 if (trunk->audio_fmtp_extra)
964 vty_out(vty, " sdp audio fmtp-extra %s%s",
965 trunk->audio_fmtp_extra, VTY_NEWLINE);
966 vty_out(vty, " %sallow-transcoding%s",
967 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
968 }
969
970 return CMD_SUCCESS;
971}
972
973DEFUN(cfg_trunk_sdp_fmtp_extra,
974 cfg_trunk_sdp_fmtp_extra_cmd,
975 "sdp audio fmtp-extra .NAME",
976 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
977 "Extra Information\n")
978{
Philipp Maier14b27a82020-06-02 20:15:30 +0200979 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200980 char *txt = argv_concat(argv, argc, 0);
981 if (!txt)
982 return CMD_WARNING;
983
984 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
985 talloc_free(txt);
986 return CMD_SUCCESS;
987}
988
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200989DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200990 cfg_trunk_payload_number_cmd,
991 "sdp audio-payload number <0-255>",
992 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
993{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200994 return CMD_SUCCESS;
995}
996
997ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200998 "sdp audio payload number <0-255>",
999 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000
Philipp Maier7f90ddb2020-06-02 21:52:53 +02001001DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001002 cfg_trunk_payload_name_cmd,
1003 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001004 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001005{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001006 return CMD_SUCCESS;
1007}
1008
1009ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001010 "sdp audio payload name NAME",
1011 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001012
Philipp Maierba94b6d2020-09-22 16:14:32 +02001013DEFUN_DEPRECATED(cfg_trunk_loop,
1014 cfg_trunk_loop_cmd,
1015 "loop (0|1)",
1016 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001017{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001018 return CMD_SUCCESS;
1019}
1020
1021DEFUN(cfg_trunk_sdp_payload_send_ptime,
1022 cfg_trunk_sdp_payload_send_ptime_cmd,
1023 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001024 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001025{
Philipp Maier14b27a82020-06-02 20:15:30 +02001026 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001027 trunk->audio_send_ptime = 1;
1028 return CMD_SUCCESS;
1029}
1030
1031DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1032 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1033 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001034 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001035{
Philipp Maier14b27a82020-06-02 20:15:30 +02001036 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001037 trunk->audio_send_ptime = 0;
1038 return CMD_SUCCESS;
1039}
1040
1041DEFUN(cfg_trunk_sdp_payload_send_name,
1042 cfg_trunk_sdp_payload_send_name_cmd,
1043 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001044 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001045{
Philipp Maier14b27a82020-06-02 20:15:30 +02001046 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001047 trunk->audio_send_name = 1;
1048 return CMD_SUCCESS;
1049}
1050
1051DEFUN(cfg_trunk_no_sdp_payload_send_name,
1052 cfg_trunk_no_sdp_payload_send_name_cmd,
1053 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001054 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
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->audio_send_name = 0;
1058 return CMD_SUCCESS;
1059}
1060
Philipp Maier87bd9be2017-08-22 16:35:41 +02001061DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001062{
Philipp Maier14b27a82020-06-02 20:15:30 +02001063 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001064 trunk->omit_rtcp = 1;
1065 return CMD_SUCCESS;
1066}
1067
1068DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001069 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001070{
Philipp Maier14b27a82020-06-02 20:15:30 +02001071 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001072 trunk->omit_rtcp = 0;
1073 return CMD_SUCCESS;
1074}
1075
1076DEFUN(cfg_trunk_patch_rtp_ssrc,
1077 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001078 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001079{
Philipp Maier14b27a82020-06-02 20:15:30 +02001080 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001081 trunk->force_constant_ssrc = 1;
1082 return CMD_SUCCESS;
1083}
1084
1085DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1086 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001087 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001088{
Philipp Maier14b27a82020-06-02 20:15:30 +02001089 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001090 trunk->force_constant_ssrc = 0;
1091 return CMD_SUCCESS;
1092}
1093
1094DEFUN(cfg_trunk_patch_rtp_ts,
1095 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001096 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001097{
Philipp Maier14b27a82020-06-02 20:15:30 +02001098 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001099 trunk->force_aligned_timing = 1;
1100 return CMD_SUCCESS;
1101}
1102
1103DEFUN(cfg_trunk_no_patch_rtp_ts,
1104 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001105 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001106{
Philipp Maier14b27a82020-06-02 20:15:30 +02001107 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001108 trunk->force_aligned_timing = 0;
1109 return CMD_SUCCESS;
1110}
1111
Philipp Maier9fc8a022019-02-20 12:26:52 +01001112DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1113 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1114 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1115{
Philipp Maier14b27a82020-06-02 20:15:30 +02001116 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001117 trunk->rfc5993_hr_convert = true;
1118 return CMD_SUCCESS;
1119}
1120
1121DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1122 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1123 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1124{
Philipp Maier14b27a82020-06-02 20:15:30 +02001125 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001126 trunk->rfc5993_hr_convert = false;
1127 return CMD_SUCCESS;
1128}
1129
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001130DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001131 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001132{
Philipp Maier14b27a82020-06-02 20:15:30 +02001133 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001134 trunk->force_constant_ssrc = 0;
1135 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001136 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001137 return CMD_SUCCESS;
1138}
1139
1140DEFUN(cfg_trunk_rtp_keepalive,
1141 cfg_trunk_rtp_keepalive_cmd,
1142 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001143 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001144{
Philipp Maier14b27a82020-06-02 20:15:30 +02001145 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001146 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1147 return CMD_SUCCESS;
1148}
1149
1150DEFUN(cfg_trunk_rtp_keepalive_once,
1151 cfg_trunk_rtp_keepalive_once_cmd,
1152 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001153 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001154{
Philipp Maier14b27a82020-06-02 20:15:30 +02001155 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001156 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1157 return CMD_SUCCESS;
1158}
1159
1160DEFUN(cfg_trunk_no_rtp_keepalive,
1161 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001162 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001163{
Philipp Maier14b27a82020-06-02 20:15:30 +02001164 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001165 mgcp_trunk_set_keepalive(trunk, 0);
1166 return CMD_SUCCESS;
1167}
1168
1169DEFUN(cfg_trunk_allow_transcoding,
1170 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001171 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001172{
Philipp Maier14b27a82020-06-02 20:15:30 +02001173 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001174 trunk->no_audio_transcoding = 0;
1175 return CMD_SUCCESS;
1176}
1177
1178DEFUN(cfg_trunk_no_allow_transcoding,
1179 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001180 "no allow-transcoding", NO_STR "Allow transcoding\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->no_audio_transcoding = 1;
1184 return CMD_SUCCESS;
1185}
1186
Philipp Maier889fe7f2020-07-06 17:44:12 +02001187#define LINE_STR "Configure trunk for given Line\nE1/T1 Line Number\n"
1188
1189DEFUN(cfg_trunk_line,
1190 cfg_trunk_line_cmd,
1191 "line <0-255>",
1192 LINE_STR)
1193{
1194 struct mgcp_trunk *trunk = vty->index;
1195 int line_nr = atoi(argv[0]);
1196 trunk->e1.vty_line_nr = line_nr;
1197 return CMD_SUCCESS;
1198}
1199
Philipp Maier87bd9be2017-08-22 16:35:41 +02001200DEFUN(loop_conn,
1201 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001202 "loop-endpoint <0-64> NAME (0|1)",
1203 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001204 "The name in hex of the endpoint\n" "Disable the loop\n"
1205 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001206{
Philipp Maier14b27a82020-06-02 20:15:30 +02001207 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001208 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001209 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001210
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001211 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001212 if (!trunk) {
1213 vty_out(vty, "%%Trunk %d not found in the config.%s",
1214 atoi(argv[0]), VTY_NEWLINE);
1215 return CMD_WARNING;
1216 }
1217
1218 if (!trunk->endpoints) {
1219 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1220 trunk->trunk_nr, VTY_NEWLINE);
1221 return CMD_WARNING;
1222 }
1223
1224 int endp_no = strtoul(argv[1], NULL, 16);
1225 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1226 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001227 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001228 return CMD_WARNING;
1229 }
1230
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001231 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001232 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001233 llist_for_each_entry(conn, &endp->conns, entry) {
1234 if (conn->type == MGCP_CONN_TYPE_RTP)
1235 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1236 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1237 else {
1238 /* FIXME: Introduce support for other connection (E1)
1239 * types when implementation is available */
1240 vty_out(vty, "%%Can't enable SSRC patching,"
1241 "connection %s is not an RTP connection.%s",
1242 mgcp_conn_dump(conn), VTY_NEWLINE);
1243 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001244
Philipp Maier87bd9be2017-08-22 16:35:41 +02001245 if (loop)
1246 conn->mode = MGCP_CONN_LOOPBACK;
1247 else
1248 conn->mode = conn->mode_orig;
1249 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001250
1251 return CMD_SUCCESS;
1252}
1253
Philipp Maier87bd9be2017-08-22 16:35:41 +02001254DEFUN(tap_rtp,
1255 tap_rtp_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001256 "tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001257 "Forward data on endpoint to a different system\n" "Trunk number\n"
1258 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001259 "The connection id in hex\n"
1260 "Forward incoming data\n"
1261 "Forward leaving data\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001262 "Destination IPv4 of the data\n"
1263 "Destination IPv6 of the data\n"
1264 "Destination port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001265{
1266 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001267 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001268 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001269 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001270 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001271
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001272 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001273 if (!trunk) {
1274 vty_out(vty, "%%Trunk %d not found in the config.%s",
1275 atoi(argv[0]), VTY_NEWLINE);
1276 return CMD_WARNING;
1277 }
1278
1279 if (!trunk->endpoints) {
1280 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1281 trunk->trunk_nr, VTY_NEWLINE);
1282 return CMD_WARNING;
1283 }
1284
1285 int endp_no = strtoul(argv[1], NULL, 16);
1286 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1287 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001288 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001289 return CMD_WARNING;
1290 }
1291
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001292 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001293
Philipp Maier01d24a32017-11-21 17:26:09 +01001294 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001295 conn = mgcp_conn_get_rtp(endp, conn_id);
1296 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001297 vty_out(vty, "Conn ID %s is invalid.%s",
1298 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001299 return CMD_WARNING;
1300 }
1301
1302 if (strcmp(argv[3], "in") == 0)
1303 tap = &conn->tap_in;
1304 else if (strcmp(argv[3], "out") == 0)
1305 tap = &conn->tap_out;
1306 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001307 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1308 return CMD_WARNING;
1309 }
1310
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001311 memset(&tap->forward, 0, sizeof(tap->forward));
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001312
1313 tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);
1314 switch (tap->forward.u.sa.sa_family) {
1315 case AF_INET:
1316 if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)
1317 return CMD_WARNING;
1318 tap->forward.u.sin.sin_port = htons(atoi(argv[5]));
1319 break;
1320 case AF_INET6:
1321 if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)
1322 return CMD_WARNING;
1323 tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));
1324 break;
1325 default:
1326 return CMD_WARNING;
1327 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001328 tap->enabled = 1;
1329 return CMD_SUCCESS;
1330}
1331
1332DEFUN(free_endp, free_endp_cmd,
1333 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001334 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001335{
Philipp Maier14b27a82020-06-02 20:15:30 +02001336 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001337 struct mgcp_endpoint *endp;
1338
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001339 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001340 if (!trunk) {
1341 vty_out(vty, "%%Trunk %d not found in the config.%s",
1342 atoi(argv[0]), VTY_NEWLINE);
1343 return CMD_WARNING;
1344 }
1345
1346 if (!trunk->endpoints) {
1347 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1348 trunk->trunk_nr, VTY_NEWLINE);
1349 return CMD_WARNING;
1350 }
1351
1352 int endp_no = strtoul(argv[1], NULL, 16);
1353 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1354 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001355 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001356 return CMD_WARNING;
1357 }
1358
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001359 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001360 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001361 return CMD_SUCCESS;
1362}
1363
1364DEFUN(reset_endp, reset_endp_cmd,
1365 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001366 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001367{
Philipp Maier14b27a82020-06-02 20:15:30 +02001368 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001369 struct mgcp_endpoint *endp;
1370 int endp_no, rc;
1371
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001372 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001373 if (!trunk) {
1374 vty_out(vty, "%%Trunk %d not found in the config.%s",
1375 atoi(argv[0]), VTY_NEWLINE);
1376 return CMD_WARNING;
1377 }
1378
1379 if (!trunk->endpoints) {
1380 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1381 trunk->trunk_nr, VTY_NEWLINE);
1382 return CMD_WARNING;
1383 }
1384
1385 endp_no = strtoul(argv[1], NULL, 16);
1386 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1387 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001388 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001389 return CMD_WARNING;
1390 }
1391
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001392 endp = trunk->endpoints[endp_no];
1393 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001394 if (rc < 0) {
1395 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1396 return CMD_WARNING;
1397 }
1398 return CMD_SUCCESS;
1399}
1400
1401DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001402 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001403{
1404 int rc;
1405
1406 rc = mgcp_send_reset_all(g_cfg);
1407 if (rc < 0) {
1408 vty_out(vty, "Error %d during endpoint reset.%s",
1409 rc, VTY_NEWLINE);
1410 return CMD_WARNING;
1411 }
1412 return CMD_SUCCESS;
1413}
1414
1415#define OSMUX_STR "RTP multiplexing\n"
1416DEFUN(cfg_mgcp_osmux,
1417 cfg_mgcp_osmux_cmd,
1418 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001419 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001420{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001421 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001422 OSMO_ASSERT(trunk);
1423
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001424 if (strcmp(argv[0], "off") == 0) {
1425 g_cfg->osmux = OSMUX_USAGE_OFF;
1426 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001427 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001428 g_cfg->osmux = OSMUX_USAGE_ON;
1429 else if (strcmp(argv[0], "only") == 0)
1430 g_cfg->osmux = OSMUX_USAGE_ONLY;
1431
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001432 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001433
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001434}
1435
1436DEFUN(cfg_mgcp_osmux_ip,
1437 cfg_mgcp_osmux_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001438 "osmux bind-ip " VTY_IPV46_CMD,
1439 OSMUX_STR IP_STR
1440 "IPv4 Address to bind to\n"
1441 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001442{
1443 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1444 return CMD_SUCCESS;
1445}
1446
1447DEFUN(cfg_mgcp_osmux_batch_factor,
1448 cfg_mgcp_osmux_batch_factor_cmd,
1449 "osmux batch-factor <1-8>",
1450 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1451{
1452 g_cfg->osmux_batch = atoi(argv[0]);
1453 return CMD_SUCCESS;
1454}
1455
1456DEFUN(cfg_mgcp_osmux_batch_size,
1457 cfg_mgcp_osmux_batch_size_cmd,
1458 "osmux batch-size <1-65535>",
1459 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1460{
1461 g_cfg->osmux_batch_size = atoi(argv[0]);
1462 return CMD_SUCCESS;
1463}
1464
1465DEFUN(cfg_mgcp_osmux_port,
1466 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001467 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001468{
1469 g_cfg->osmux_port = atoi(argv[0]);
1470 return CMD_SUCCESS;
1471}
1472
1473DEFUN(cfg_mgcp_osmux_dummy,
1474 cfg_mgcp_osmux_dummy_cmd,
1475 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001476 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1477 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001478{
1479 if (strcmp(argv[0], "on") == 0)
1480 g_cfg->osmux_dummy = 1;
1481 else if (strcmp(argv[0], "off") == 0)
1482 g_cfg->osmux_dummy = 0;
1483
1484 return CMD_SUCCESS;
1485}
1486
Philipp Maier12943ea2018-01-17 15:40:25 +01001487DEFUN(cfg_mgcp_domain,
1488 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001489 "domain NAME",
1490 "Set the domain part expected in MGCP messages' endpoint names\n"
1491 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001492{
1493 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1494 return CMD_SUCCESS;
1495}
1496
Oliver Smithe36b7752019-01-22 16:31:36 +01001497DEFUN(cfg_mgcp_conn_timeout,
1498 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001499 "conn-timeout <0-65534>",
1500 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1501 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001502 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1503 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001504 "Timeout value (sec.)\n")
1505{
1506 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1507 return CMD_SUCCESS;
1508}
1509
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001510int mgcp_vty_init(void)
1511{
1512 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001513 install_element_ve(&show_mgcp_endpoint_cmd);
1514 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001515 install_element(ENABLE_NODE, &loop_conn_cmd);
1516 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001517 install_element(ENABLE_NODE, &free_endp_cmd);
1518 install_element(ENABLE_NODE, &reset_endp_cmd);
1519 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1520
1521 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1522 install_node(&mgcp_node, config_write_mgcp);
1523
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001524 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001525 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1526 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1527 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001528 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001529 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001530 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001531 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001532 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_v6_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001533 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001534 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001535 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_v6_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001536 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1537 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001538 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1539 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1540 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1541 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1542 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1543 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1544 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1545 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1546 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001547 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1548 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1549 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1550 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1551 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1552 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001553 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001554 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1555 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1556 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1557 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1558 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1559 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1560 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1561 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001562 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1563 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001564 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1565 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1566 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1567 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1568 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1569 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1570 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1571 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1572 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1573 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1574 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1575 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1576 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001577 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001578 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001579
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001580 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1581 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001582 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1583 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1584 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1585 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1586 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1587 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1588 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1589 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1590 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1591 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1592 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1593 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1594 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001595 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1596 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001597 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1598 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1599 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1600 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1601 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1602 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1603 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1604 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1605 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001606 install_element(TRUNK_NODE, &cfg_trunk_line_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001607
1608 return 0;
1609}
1610
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001611int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1612 enum mgcp_role role)
1613{
1614 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001615 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001616
1617 cfg->osmux_port = OSMUX_PORT;
1618 cfg->osmux_batch = 4;
1619 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1620
1621 g_cfg = cfg;
1622 rc = vty_read_config_file(config_file, NULL);
1623 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001624 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1625 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001626 return rc;
1627 }
1628
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001629 if (!g_cfg->source_addr) {
1630 fprintf(stderr, "You need to specify a bind address.\n");
1631 return -1;
1632 }
1633
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001634 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier889fe7f2020-07-06 17:44:12 +02001635 if (mgcp_trunk_equip(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001636 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001637 "Failed to initialize trunk %d (%d endpoints)\n",
1638 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001639 return -1;
1640 }
1641 }
1642 cfg->role = role;
1643
1644 return 0;
1645}