blob: 440452fa5259e265c711078c0cdd887f9e6ff21a [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
Philipp Maier8cfe7df2020-09-22 16:18:26 +0200445DEFUN_DEPRECATED(cfg_mgcp_bind_early,
446 cfg_mgcp_bind_early_cmd,
447 "bind early (0|1)",
448 BIND_STR
449 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200450{
Philipp Maier8cfe7df2020-09-22 16:18:26 +0200451 return CMD_SUCCESS;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200452}
453
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200454#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200455#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200456#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200457#define RANGE_START_STR "Start of the range of ports\n"
458#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200459
Philipp Maierf1889d82017-11-08 14:59:39 +0100460DEFUN(cfg_mgcp_rtp_port_range,
461 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200462 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200463 RTP_STR "Range of ports to use for the NET side\n"
464 RANGE_START_STR RANGE_END_STR)
465{
Philipp Maiera19547b2018-05-22 13:44:34 +0200466 int start;
467 int end;
468
469 start = atoi(argv[0]);
470 end = atoi(argv[1]);
471
472 if (end < start) {
473 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
474 end, start, VTY_NEWLINE);
475 return CMD_WARNING;
476 }
477
478 if (start & 1) {
479 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
480 start, start & 0xFFFE, VTY_NEWLINE);
481 start &= 0xFFFE;
482 }
483
484 if ((end & 1) == 0) {
485 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
486 end, end | 1, VTY_NEWLINE);
487 end |= 1;
488 }
489
490 g_cfg->net_ports.range_start = start;
491 g_cfg->net_ports.range_end = end;
492 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
493
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200494 return CMD_SUCCESS;
495}
Philipp Maierf1889d82017-11-08 14:59:39 +0100496ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
497 cfg_mgcp_rtp_net_range_cmd,
498 "rtp net-range <0-65534> <0-65534>",
499 RTP_STR "Range of ports to use for the NET side\n"
500 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200501
Philipp Maierf1889d82017-11-08 14:59:39 +0100502DEFUN(cfg_mgcp_rtp_bind_ip,
503 cfg_mgcp_rtp_bind_ip_cmd,
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200504 "rtp bind-ip A.B.C.D",
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200505 RTP_STR "Bind endpoints facing the Network\n"
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200506 "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200507{
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200508 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v4, argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200509 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{
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200522 talloc_free(g_cfg->net_ports.bind_addr_v4);
523 g_cfg->net_ports.bind_addr_v4 = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200524 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
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200532DEFUN(cfg_mgcp_rtp_bind_ip_v6,
533 cfg_mgcp_rtp_bind_ip_v6_cmd,
534 "rtp bind-ip-v6 " VTY_IPV6_CMD,
535 RTP_STR "Bind endpoints facing the Network\n"
536 "IPv6 Address to bind to\n")
537{
538 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v6, argv[0]);
539 return CMD_SUCCESS;
540}
541
542DEFUN(cfg_mgcp_rtp_no_bind_ip_v6,
543cfg_mgcp_rtp_no_bind_ip_v6_cmd,
544"no rtp bind-ip-v6",
545NO_STR RTP_STR "Bind endpoints facing the Network\n"
546"Address to bind to\n")
547{
548 talloc_free(g_cfg->net_ports.bind_addr_v6);
549 g_cfg->net_ports.bind_addr_v6 = NULL;
550 return CMD_SUCCESS;
551}
552
Philipp Maier1cb1e382017-11-02 17:16:04 +0100553DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
554 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
555 "rtp ip-probing",
556 RTP_STR "automatic rtp bind ip selection\n")
557{
558 g_cfg->net_ports.bind_addr_probe = true;
559 return CMD_SUCCESS;
560}
561
562DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
563 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
564 "no rtp ip-probing",
565 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
566{
567 g_cfg->net_ports.bind_addr_probe = false;
568 return CMD_SUCCESS;
569}
570
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200571DEFUN(cfg_mgcp_rtp_ip_dscp,
572 cfg_mgcp_rtp_ip_dscp_cmd,
573 "rtp ip-dscp <0-255>",
574 RTP_STR
575 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
576{
577 int dscp = atoi(argv[0]);
578 g_cfg->endp_dscp = dscp;
579 return CMD_SUCCESS;
580}
581
582ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200583 "rtp ip-tos <0-255>",
584 RTP_STR
585 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
586#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200587DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200588 cfg_mgcp_rtp_force_ptime_cmd,
589 "rtp force-ptime (10|20|40)",
590 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200591 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200592{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200593 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200594 return CMD_SUCCESS;
595}
596
597DEFUN(cfg_mgcp_no_rtp_force_ptime,
598 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200599 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200600{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200601 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200602 return CMD_SUCCESS;
603}
604
605DEFUN(cfg_mgcp_sdp_fmtp_extra,
606 cfg_mgcp_sdp_fmtp_extra_cmd,
607 "sdp audio fmtp-extra .NAME",
608 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
609 "Extra Information\n")
610{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200611 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200612 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200613 char *txt = argv_concat(argv, argc, 0);
614 if (!txt)
615 return CMD_WARNING;
616
Philipp Maierd19de2e2020-06-03 13:55:33 +0200617 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200618 talloc_free(txt);
619 return CMD_SUCCESS;
620}
621
622DEFUN(cfg_mgcp_allow_transcoding,
623 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200624 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200625{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200626 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200627 OSMO_ASSERT(trunk);
628 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200629 return CMD_SUCCESS;
630}
631
632DEFUN(cfg_mgcp_no_allow_transcoding,
633 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200634 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200635{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200636 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200637 OSMO_ASSERT(trunk);
638 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200639 return CMD_SUCCESS;
640}
641
642#define SDP_STR "SDP File related options\n"
643#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200644DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200645 cfg_mgcp_sdp_payload_number_cmd,
646 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200647 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200648{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200649 return CMD_SUCCESS;
650}
651
Philipp Maier87bd9be2017-08-22 16:35:41 +0200652ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
653 cfg_mgcp_sdp_payload_number_cmd_old,
654 "sdp audio payload number <0-255>",
655 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200656
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200657DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200658 cfg_mgcp_sdp_payload_name_cmd,
659 "sdp audio-payload name NAME",
660 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
661{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200662 return CMD_SUCCESS;
663}
664
665ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200666 "sdp audio payload name NAME",
667 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200668
Philipp Maier21be42a2020-05-29 21:39:48 +0200669DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200670 cfg_mgcp_sdp_payload_send_ptime_cmd,
671 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200672 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200673{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200674 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200675 OSMO_ASSERT(trunk);
676 trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200677 return CMD_SUCCESS;
678}
679
680DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
681 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
682 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200683 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200684{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200685 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200686 OSMO_ASSERT(trunk);
687 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200688 return CMD_SUCCESS;
689}
690
691DEFUN(cfg_mgcp_sdp_payload_send_name,
692 cfg_mgcp_sdp_payload_send_name_cmd,
693 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200694 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200695{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200696 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200697 OSMO_ASSERT(trunk);
698 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200699 return CMD_SUCCESS;
700}
701
702DEFUN(cfg_mgcp_no_sdp_payload_send_name,
703 cfg_mgcp_no_sdp_payload_send_name_cmd,
704 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200705 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200706{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200707 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200708 OSMO_ASSERT(trunk);
709 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200710 return CMD_SUCCESS;
711}
712
Philipp Maierba94b6d2020-09-22 16:14:32 +0200713DEFUN_DEPRECATED(cfg_mgcp_loop,
714 cfg_mgcp_loop_cmd,
715 "loop (0|1)",
716 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200717{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200718 return CMD_SUCCESS;
719}
720
721DEFUN(cfg_mgcp_force_realloc,
722 cfg_mgcp_force_realloc_cmd,
723 "force-realloc (0|1)",
724 "Force endpoint reallocation when the endpoint is still seized\n"
725 "Don't force reallocation\n" "force reallocation\n")
726{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200727 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200728 OSMO_ASSERT(trunk);
729 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730 return CMD_SUCCESS;
731}
732
Philipp Maier87bd9be2017-08-22 16:35:41 +0200733DEFUN(cfg_mgcp_rtp_accept_all,
734 cfg_mgcp_rtp_accept_all_cmd,
735 "rtp-accept-all (0|1)",
736 "Accept all RTP packets, even when the originating IP/Port does not match\n"
737 "enable filter\n" "disable filter\n")
738{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200739 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200740 OSMO_ASSERT(trunk);
741 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200742 return CMD_SUCCESS;
743}
744
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200745DEFUN(cfg_mgcp_number_endp,
746 cfg_mgcp_number_endp_cmd,
Philipp Maier869b21c2020-07-03 16:04:16 +0200747 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200748 "Number options\n" "Endpoints available\n" "Number endpoints\n")
749{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200750 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200751 OSMO_ASSERT(trunk);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200752 trunk->v.vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200753 return CMD_SUCCESS;
754}
755
Philipp Maier87bd9be2017-08-22 16:35:41 +0200756DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200757{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200758 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200759 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200760 return CMD_SUCCESS;
761}
762
763DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200764 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200765{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200766 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200767 OSMO_ASSERT(trunk);
768 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200769 return CMD_SUCCESS;
770}
771
772DEFUN(cfg_mgcp_patch_rtp_ssrc,
773 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200774 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200775{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200776 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200777 OSMO_ASSERT(trunk);
778 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200779 return CMD_SUCCESS;
780}
781
782DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
783 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200784 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200785{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200786 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200787 OSMO_ASSERT(trunk);
788 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200789 return CMD_SUCCESS;
790}
791
792DEFUN(cfg_mgcp_patch_rtp_ts,
793 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200794 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200795{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200796 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200797 OSMO_ASSERT(trunk);
798 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200799 return CMD_SUCCESS;
800}
801
802DEFUN(cfg_mgcp_no_patch_rtp_ts,
803 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200804 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200805{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200806 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200807 OSMO_ASSERT(trunk);
808 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200809 return CMD_SUCCESS;
810}
811
Philipp Maier9fc8a022019-02-20 12:26:52 +0100812DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
813 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
814 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
815{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200816 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200817 OSMO_ASSERT(trunk);
818 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100819 return CMD_SUCCESS;
820}
821
822DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
823 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
824 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
825{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200826 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200827 OSMO_ASSERT(trunk);
828 trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100829 return CMD_SUCCESS;
830}
831
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200832DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200833 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200834{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200835 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200836 OSMO_ASSERT(trunk);
837 trunk->force_constant_ssrc = 0;
838 trunk->force_aligned_timing = 0;
839 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200840 return CMD_SUCCESS;
841}
842
843DEFUN(cfg_mgcp_rtp_keepalive,
844 cfg_mgcp_rtp_keepalive_cmd,
845 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200846 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200847{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200848 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200849 OSMO_ASSERT(trunk);
850 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200851 return CMD_SUCCESS;
852}
853
854DEFUN(cfg_mgcp_rtp_keepalive_once,
855 cfg_mgcp_rtp_keepalive_once_cmd,
856 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200857 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200858{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200859 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200860 OSMO_ASSERT(trunk);
861 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200862 return CMD_SUCCESS;
863}
864
865DEFUN(cfg_mgcp_no_rtp_keepalive,
866 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200867 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200868{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200869 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200870 OSMO_ASSERT(trunk);
871 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200872 return CMD_SUCCESS;
873}
874
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200875#define CALL_AGENT_STR "Call agent information\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200876DEFUN(cfg_mgcp_agent_addr,
877 cfg_mgcp_agent_addr_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200878 "call-agent ip " VTY_IPV46_CMD,
879 CALL_AGENT_STR IP_STR
880 "IPv4 Address of the call agent\n"
881 "IPv6 Address of the call agent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200882{
883 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
884 return CMD_SUCCESS;
885}
886
887ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200888 "call agent ip A.B.C.D",
889 CALL_AGENT_STR CALL_AGENT_STR IP_STR
890 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200891
Philipp Maier21be42a2020-05-29 21:39:48 +0200892DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier0653cc82020-08-10 22:52:51 +0200893 "trunk <0-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200894{
Philipp Maier14b27a82020-06-02 20:15:30 +0200895 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200896 int index = atoi(argv[0]);
897
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200898 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100899 if (!trunk) {
900 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200901 if (!trunk) {
902 vty_out(vty, "%%Unable to allocate trunk %u.%s",
903 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100904 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200905 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200906 }
907
908 vty->node = TRUNK_NODE;
909 vty->index = trunk;
910 return CMD_SUCCESS;
911}
912
913static int config_write_trunk(struct vty *vty)
914{
Philipp Maier14b27a82020-06-02 20:15:30 +0200915 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200916
917 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200918
919 /* Due to historical reasons, the virtual trunk is configured
920 using separate VTY parameters, so we omit writing the trunk
921 config of trunk 0 here. The configuration for the virtual
922 trunk is written by config_write_mgcp(). */
923
924 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
925 continue;
926
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200927 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200928 vty_out(vty, " line %u%s", trunk->e1.vty_line_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200929 vty_out(vty, " %ssdp audio-payload send-ptime%s",
930 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
931 vty_out(vty, " %ssdp audio-payload send-name%s",
932 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
933
934 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
935 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
936 else if (trunk->keepalive_interval)
937 vty_out(vty, " rtp keep-alive %d%s",
938 trunk->keepalive_interval, VTY_NEWLINE);
939 else
940 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200941 vty_out(vty, " force-realloc %d%s",
942 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200943 vty_out(vty, " rtp-accept-all %d%s",
944 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200945 if (trunk->omit_rtcp)
946 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
947 else
948 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100949 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200950 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200951 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200952 trunk->force_constant_ssrc ? "" : "no ",
953 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200954 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200955 trunk->force_aligned_timing ? "" : "no ",
956 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100957 vty_out(vty, " %srtp-patch rfc5993hr%s",
958 trunk->rfc5993_hr_convert ? "" : "no ",
959 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200960 } else
961 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
962 if (trunk->audio_fmtp_extra)
963 vty_out(vty, " sdp audio fmtp-extra %s%s",
964 trunk->audio_fmtp_extra, VTY_NEWLINE);
965 vty_out(vty, " %sallow-transcoding%s",
966 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
967 }
968
969 return CMD_SUCCESS;
970}
971
972DEFUN(cfg_trunk_sdp_fmtp_extra,
973 cfg_trunk_sdp_fmtp_extra_cmd,
974 "sdp audio fmtp-extra .NAME",
975 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
976 "Extra Information\n")
977{
Philipp Maier14b27a82020-06-02 20:15:30 +0200978 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200979 char *txt = argv_concat(argv, argc, 0);
980 if (!txt)
981 return CMD_WARNING;
982
983 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
984 talloc_free(txt);
985 return CMD_SUCCESS;
986}
987
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200988DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200989 cfg_trunk_payload_number_cmd,
990 "sdp audio-payload number <0-255>",
991 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
992{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200993 return CMD_SUCCESS;
994}
995
996ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200997 "sdp audio payload number <0-255>",
998 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200999
Philipp Maier7f90ddb2020-06-02 21:52:53 +02001000DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001001 cfg_trunk_payload_name_cmd,
1002 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001003 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001004{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001005 return CMD_SUCCESS;
1006}
1007
1008ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001009 "sdp audio payload name NAME",
1010 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001011
Philipp Maierba94b6d2020-09-22 16:14:32 +02001012DEFUN_DEPRECATED(cfg_trunk_loop,
1013 cfg_trunk_loop_cmd,
1014 "loop (0|1)",
1015 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001016{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001017 return CMD_SUCCESS;
1018}
1019
1020DEFUN(cfg_trunk_sdp_payload_send_ptime,
1021 cfg_trunk_sdp_payload_send_ptime_cmd,
1022 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001023 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001024{
Philipp Maier14b27a82020-06-02 20:15:30 +02001025 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001026 trunk->audio_send_ptime = 1;
1027 return CMD_SUCCESS;
1028}
1029
1030DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1031 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1032 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001033 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001034{
Philipp Maier14b27a82020-06-02 20:15:30 +02001035 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001036 trunk->audio_send_ptime = 0;
1037 return CMD_SUCCESS;
1038}
1039
1040DEFUN(cfg_trunk_sdp_payload_send_name,
1041 cfg_trunk_sdp_payload_send_name_cmd,
1042 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001043 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001044{
Philipp Maier14b27a82020-06-02 20:15:30 +02001045 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001046 trunk->audio_send_name = 1;
1047 return CMD_SUCCESS;
1048}
1049
1050DEFUN(cfg_trunk_no_sdp_payload_send_name,
1051 cfg_trunk_no_sdp_payload_send_name_cmd,
1052 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001053 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001054{
Philipp Maier14b27a82020-06-02 20:15:30 +02001055 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001056 trunk->audio_send_name = 0;
1057 return CMD_SUCCESS;
1058}
1059
Philipp Maier87bd9be2017-08-22 16:35:41 +02001060DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001061{
Philipp Maier14b27a82020-06-02 20:15:30 +02001062 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001063 trunk->omit_rtcp = 1;
1064 return CMD_SUCCESS;
1065}
1066
1067DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001068 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001069{
Philipp Maier14b27a82020-06-02 20:15:30 +02001070 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001071 trunk->omit_rtcp = 0;
1072 return CMD_SUCCESS;
1073}
1074
1075DEFUN(cfg_trunk_patch_rtp_ssrc,
1076 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001077 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001078{
Philipp Maier14b27a82020-06-02 20:15:30 +02001079 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001080 trunk->force_constant_ssrc = 1;
1081 return CMD_SUCCESS;
1082}
1083
1084DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1085 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001086 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001087{
Philipp Maier14b27a82020-06-02 20:15:30 +02001088 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001089 trunk->force_constant_ssrc = 0;
1090 return CMD_SUCCESS;
1091}
1092
1093DEFUN(cfg_trunk_patch_rtp_ts,
1094 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001095 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001096{
Philipp Maier14b27a82020-06-02 20:15:30 +02001097 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001098 trunk->force_aligned_timing = 1;
1099 return CMD_SUCCESS;
1100}
1101
1102DEFUN(cfg_trunk_no_patch_rtp_ts,
1103 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001104 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001105{
Philipp Maier14b27a82020-06-02 20:15:30 +02001106 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001107 trunk->force_aligned_timing = 0;
1108 return CMD_SUCCESS;
1109}
1110
Philipp Maier9fc8a022019-02-20 12:26:52 +01001111DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1112 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1113 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1114{
Philipp Maier14b27a82020-06-02 20:15:30 +02001115 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001116 trunk->rfc5993_hr_convert = true;
1117 return CMD_SUCCESS;
1118}
1119
1120DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1121 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1122 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1123{
Philipp Maier14b27a82020-06-02 20:15:30 +02001124 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001125 trunk->rfc5993_hr_convert = false;
1126 return CMD_SUCCESS;
1127}
1128
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001129DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001130 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001131{
Philipp Maier14b27a82020-06-02 20:15:30 +02001132 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001133 trunk->force_constant_ssrc = 0;
1134 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001135 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001136 return CMD_SUCCESS;
1137}
1138
1139DEFUN(cfg_trunk_rtp_keepalive,
1140 cfg_trunk_rtp_keepalive_cmd,
1141 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001142 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001143{
Philipp Maier14b27a82020-06-02 20:15:30 +02001144 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001145 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1146 return CMD_SUCCESS;
1147}
1148
1149DEFUN(cfg_trunk_rtp_keepalive_once,
1150 cfg_trunk_rtp_keepalive_once_cmd,
1151 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001152 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001153{
Philipp Maier14b27a82020-06-02 20:15:30 +02001154 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001155 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1156 return CMD_SUCCESS;
1157}
1158
1159DEFUN(cfg_trunk_no_rtp_keepalive,
1160 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001161 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001162{
Philipp Maier14b27a82020-06-02 20:15:30 +02001163 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001164 mgcp_trunk_set_keepalive(trunk, 0);
1165 return CMD_SUCCESS;
1166}
1167
1168DEFUN(cfg_trunk_allow_transcoding,
1169 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001170 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001171{
Philipp Maier14b27a82020-06-02 20:15:30 +02001172 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001173 trunk->no_audio_transcoding = 0;
1174 return CMD_SUCCESS;
1175}
1176
1177DEFUN(cfg_trunk_no_allow_transcoding,
1178 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001179 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001180{
Philipp Maier14b27a82020-06-02 20:15:30 +02001181 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001182 trunk->no_audio_transcoding = 1;
1183 return CMD_SUCCESS;
1184}
1185
Philipp Maier889fe7f2020-07-06 17:44:12 +02001186#define LINE_STR "Configure trunk for given Line\nE1/T1 Line Number\n"
1187
1188DEFUN(cfg_trunk_line,
1189 cfg_trunk_line_cmd,
1190 "line <0-255>",
1191 LINE_STR)
1192{
1193 struct mgcp_trunk *trunk = vty->index;
1194 int line_nr = atoi(argv[0]);
1195 trunk->e1.vty_line_nr = line_nr;
1196 return CMD_SUCCESS;
1197}
1198
Philipp Maier87bd9be2017-08-22 16:35:41 +02001199DEFUN(loop_conn,
1200 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001201 "loop-endpoint <0-64> NAME (0|1)",
1202 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001203 "The name in hex of the endpoint\n" "Disable the loop\n"
1204 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001205{
Philipp Maier14b27a82020-06-02 20:15:30 +02001206 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001207 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001208 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001209
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001210 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001211 if (!trunk) {
1212 vty_out(vty, "%%Trunk %d not found in the config.%s",
1213 atoi(argv[0]), VTY_NEWLINE);
1214 return CMD_WARNING;
1215 }
1216
1217 if (!trunk->endpoints) {
1218 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1219 trunk->trunk_nr, VTY_NEWLINE);
1220 return CMD_WARNING;
1221 }
1222
1223 int endp_no = strtoul(argv[1], NULL, 16);
1224 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1225 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001226 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001227 return CMD_WARNING;
1228 }
1229
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001230 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001231 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001232 llist_for_each_entry(conn, &endp->conns, entry) {
1233 if (conn->type == MGCP_CONN_TYPE_RTP)
1234 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1235 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1236 else {
1237 /* FIXME: Introduce support for other connection (E1)
1238 * types when implementation is available */
1239 vty_out(vty, "%%Can't enable SSRC patching,"
1240 "connection %s is not an RTP connection.%s",
1241 mgcp_conn_dump(conn), VTY_NEWLINE);
1242 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001243
Philipp Maier87bd9be2017-08-22 16:35:41 +02001244 if (loop)
1245 conn->mode = MGCP_CONN_LOOPBACK;
1246 else
1247 conn->mode = conn->mode_orig;
1248 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001249
1250 return CMD_SUCCESS;
1251}
1252
Philipp Maier87bd9be2017-08-22 16:35:41 +02001253DEFUN(tap_rtp,
1254 tap_rtp_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001255 "tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001256 "Forward data on endpoint to a different system\n" "Trunk number\n"
1257 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001258 "The connection id in hex\n"
1259 "Forward incoming data\n"
1260 "Forward leaving data\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001261 "Destination IPv4 of the data\n"
1262 "Destination IPv6 of the data\n"
1263 "Destination port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001264{
1265 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001266 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001267 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001268 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001269 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001270
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001271 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001272 if (!trunk) {
1273 vty_out(vty, "%%Trunk %d not found in the config.%s",
1274 atoi(argv[0]), VTY_NEWLINE);
1275 return CMD_WARNING;
1276 }
1277
1278 if (!trunk->endpoints) {
1279 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1280 trunk->trunk_nr, VTY_NEWLINE);
1281 return CMD_WARNING;
1282 }
1283
1284 int endp_no = strtoul(argv[1], NULL, 16);
1285 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1286 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001287 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001288 return CMD_WARNING;
1289 }
1290
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001291 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001292
Philipp Maier01d24a32017-11-21 17:26:09 +01001293 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001294 conn = mgcp_conn_get_rtp(endp, conn_id);
1295 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001296 vty_out(vty, "Conn ID %s is invalid.%s",
1297 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001298 return CMD_WARNING;
1299 }
1300
1301 if (strcmp(argv[3], "in") == 0)
1302 tap = &conn->tap_in;
1303 else if (strcmp(argv[3], "out") == 0)
1304 tap = &conn->tap_out;
1305 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001306 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1307 return CMD_WARNING;
1308 }
1309
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001310 memset(&tap->forward, 0, sizeof(tap->forward));
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001311
1312 tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);
1313 switch (tap->forward.u.sa.sa_family) {
1314 case AF_INET:
1315 if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)
1316 return CMD_WARNING;
1317 tap->forward.u.sin.sin_port = htons(atoi(argv[5]));
1318 break;
1319 case AF_INET6:
1320 if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)
1321 return CMD_WARNING;
1322 tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));
1323 break;
1324 default:
1325 return CMD_WARNING;
1326 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001327 tap->enabled = 1;
1328 return CMD_SUCCESS;
1329}
1330
1331DEFUN(free_endp, free_endp_cmd,
1332 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001333 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001334{
Philipp Maier14b27a82020-06-02 20:15:30 +02001335 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001336 struct mgcp_endpoint *endp;
1337
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001338 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001339 if (!trunk) {
1340 vty_out(vty, "%%Trunk %d not found in the config.%s",
1341 atoi(argv[0]), VTY_NEWLINE);
1342 return CMD_WARNING;
1343 }
1344
1345 if (!trunk->endpoints) {
1346 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1347 trunk->trunk_nr, VTY_NEWLINE);
1348 return CMD_WARNING;
1349 }
1350
1351 int endp_no = strtoul(argv[1], NULL, 16);
1352 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1353 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001354 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001355 return CMD_WARNING;
1356 }
1357
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001358 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001359 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001360 return CMD_SUCCESS;
1361}
1362
1363DEFUN(reset_endp, reset_endp_cmd,
1364 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001365 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001366{
Philipp Maier14b27a82020-06-02 20:15:30 +02001367 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001368 struct mgcp_endpoint *endp;
1369 int endp_no, rc;
1370
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001371 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001372 if (!trunk) {
1373 vty_out(vty, "%%Trunk %d not found in the config.%s",
1374 atoi(argv[0]), VTY_NEWLINE);
1375 return CMD_WARNING;
1376 }
1377
1378 if (!trunk->endpoints) {
1379 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1380 trunk->trunk_nr, VTY_NEWLINE);
1381 return CMD_WARNING;
1382 }
1383
1384 endp_no = strtoul(argv[1], NULL, 16);
1385 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1386 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001387 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001388 return CMD_WARNING;
1389 }
1390
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001391 endp = trunk->endpoints[endp_no];
1392 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001393 if (rc < 0) {
1394 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1395 return CMD_WARNING;
1396 }
1397 return CMD_SUCCESS;
1398}
1399
1400DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001401 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001402{
1403 int rc;
1404
1405 rc = mgcp_send_reset_all(g_cfg);
1406 if (rc < 0) {
1407 vty_out(vty, "Error %d during endpoint reset.%s",
1408 rc, VTY_NEWLINE);
1409 return CMD_WARNING;
1410 }
1411 return CMD_SUCCESS;
1412}
1413
1414#define OSMUX_STR "RTP multiplexing\n"
1415DEFUN(cfg_mgcp_osmux,
1416 cfg_mgcp_osmux_cmd,
1417 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001418 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001419{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001420 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001421 OSMO_ASSERT(trunk);
1422
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001423 if (strcmp(argv[0], "off") == 0) {
1424 g_cfg->osmux = OSMUX_USAGE_OFF;
1425 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001426 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001427 g_cfg->osmux = OSMUX_USAGE_ON;
1428 else if (strcmp(argv[0], "only") == 0)
1429 g_cfg->osmux = OSMUX_USAGE_ONLY;
1430
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001431 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001432
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001433}
1434
1435DEFUN(cfg_mgcp_osmux_ip,
1436 cfg_mgcp_osmux_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001437 "osmux bind-ip " VTY_IPV46_CMD,
1438 OSMUX_STR IP_STR
1439 "IPv4 Address to bind to\n"
1440 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001441{
1442 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1443 return CMD_SUCCESS;
1444}
1445
1446DEFUN(cfg_mgcp_osmux_batch_factor,
1447 cfg_mgcp_osmux_batch_factor_cmd,
1448 "osmux batch-factor <1-8>",
1449 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1450{
1451 g_cfg->osmux_batch = atoi(argv[0]);
1452 return CMD_SUCCESS;
1453}
1454
1455DEFUN(cfg_mgcp_osmux_batch_size,
1456 cfg_mgcp_osmux_batch_size_cmd,
1457 "osmux batch-size <1-65535>",
1458 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1459{
1460 g_cfg->osmux_batch_size = atoi(argv[0]);
1461 return CMD_SUCCESS;
1462}
1463
1464DEFUN(cfg_mgcp_osmux_port,
1465 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001466 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001467{
1468 g_cfg->osmux_port = atoi(argv[0]);
1469 return CMD_SUCCESS;
1470}
1471
1472DEFUN(cfg_mgcp_osmux_dummy,
1473 cfg_mgcp_osmux_dummy_cmd,
1474 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001475 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1476 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001477{
1478 if (strcmp(argv[0], "on") == 0)
1479 g_cfg->osmux_dummy = 1;
1480 else if (strcmp(argv[0], "off") == 0)
1481 g_cfg->osmux_dummy = 0;
1482
1483 return CMD_SUCCESS;
1484}
1485
Philipp Maier12943ea2018-01-17 15:40:25 +01001486DEFUN(cfg_mgcp_domain,
1487 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001488 "domain NAME",
1489 "Set the domain part expected in MGCP messages' endpoint names\n"
1490 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001491{
1492 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1493 return CMD_SUCCESS;
1494}
1495
Oliver Smithe36b7752019-01-22 16:31:36 +01001496DEFUN(cfg_mgcp_conn_timeout,
1497 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001498 "conn-timeout <0-65534>",
1499 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1500 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001501 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1502 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001503 "Timeout value (sec.)\n")
1504{
1505 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1506 return CMD_SUCCESS;
1507}
1508
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001509int mgcp_vty_init(void)
1510{
1511 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001512 install_element_ve(&show_mgcp_endpoint_cmd);
1513 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001514 install_element(ENABLE_NODE, &loop_conn_cmd);
1515 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001516 install_element(ENABLE_NODE, &free_endp_cmd);
1517 install_element(ENABLE_NODE, &reset_endp_cmd);
1518 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1519
1520 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1521 install_node(&mgcp_node, config_write_mgcp);
1522
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001523 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001524 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1525 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1526 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001527 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001528 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001529 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001530 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001531 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_v6_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001532 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001533 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001534 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_v6_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001535 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1536 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001537 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1538 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1539 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1540 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1541 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1542 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1543 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1544 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1545 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001546 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1547 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1548 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1549 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1550 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1551 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001552 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001553 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1554 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1555 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1556 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1557 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1558 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1559 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1560 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001561 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1562 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001563 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1564 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1565 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1566 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1567 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1568 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1569 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1570 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1571 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1572 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1573 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1574 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1575 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001576 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001577 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001578
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001579 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1580 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001581 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1582 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1583 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1584 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1585 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1586 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1587 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1588 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1589 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1590 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1591 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1592 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1593 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001594 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1595 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001596 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1597 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1598 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1599 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1600 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1601 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1602 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1603 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1604 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001605 install_element(TRUNK_NODE, &cfg_trunk_line_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001606
1607 return 0;
1608}
1609
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001610int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1611 enum mgcp_role role)
1612{
1613 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001614 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001615
1616 cfg->osmux_port = OSMUX_PORT;
1617 cfg->osmux_batch = 4;
1618 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1619
1620 g_cfg = cfg;
1621 rc = vty_read_config_file(config_file, NULL);
1622 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001623 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1624 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001625 return rc;
1626 }
1627
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001628 if (!g_cfg->source_addr) {
1629 fprintf(stderr, "You need to specify a bind address.\n");
1630 return -1;
1631 }
1632
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001633 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier889fe7f2020-07-06 17:44:12 +02001634 if (mgcp_trunk_equip(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001635 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001636 "Failed to initialize trunk %d (%d endpoints)\n",
1637 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001638 return -1;
1639 }
1640 }
1641 cfg->role = role;
1642
1643 return 0;
1644}