blob: aa27d41fc9a0b4f275445257d1219cd4125a1692 [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, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
119 vty_out(vty, " number endpoints %u%s",
Philipp Maier889fe7f2020-07-06 17:44:12 +0200120 trunk->v.vty_number_endpoints, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200121 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100122 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200123 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200124 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200125 VTY_NEWLINE);
126 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200127 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200128 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200129
130 switch (g_cfg->osmux) {
131 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200132 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200133 break;
134 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200135 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200136 break;
137 case OSMUX_USAGE_OFF:
138 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200139 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200140 break;
141 }
142 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200143 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200144 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200145 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200146 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200147 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200148 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200149 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200150 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200151 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200152 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
153 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100154
155 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200156 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100157
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200158 return CMD_SUCCESS;
159}
160
Philipp Maiercede2a42018-07-03 14:14:21 +0200161static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200162{
Philipp Maiercede2a42018-07-03 14:14:21 +0200163 struct mgcp_rtp_state *state = &conn->state;
164 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200165 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100166 struct rate_ctr *tx_packets, *tx_bytes;
167 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200168 struct rate_ctr *dropped_packets;
169
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100170 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
171 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
172 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
173 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200174 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200175
176 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100177 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
178 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200179 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
180 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200181 " Payload Type: %d Rate: %u Channels: %d %s"
182 " Frame Duration: %u Frame Denominator: %u%s"
183 " FPP: %d Packet Duration: %u%s"
184 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
185 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100186 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
187 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200188 state->in_stream.err_ts_ctr->current,
189 state->out_stream.err_ts_ctr->current,
190 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200191 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200192 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200193 codec->frame_duration_num, codec->frame_duration_den,
194 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
195 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
196 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
197 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200198}
199
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200200static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200201 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200202{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200203 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200204
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200205 vty_out(vty, "%s trunk %d endpoint %s:%s",
206 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Philipp Maier8d6a1932020-06-18 12:19:31 +0200207 vty_out(vty, " Availability: %s%s",
208 mgcp_endp_avail(endp) ? "available" : "not in service", VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200209
210 if (llist_empty(&endp->conns)) {
211 vty_out(vty, " No active connections%s", VTY_NEWLINE);
212 return;
213 }
214
215 llist_for_each_entry(conn, &endp->conns, entry) {
216 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
217
218 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100219 if (endp->cfg->conn_timeout) {
220 struct timeval remaining;
221 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
222 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
223 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
224 }
225
Stefan Sperling12086582018-06-26 15:26:28 +0200226 /* FIXME: Also add verbosity for other
227 * connection types (E1) as soon as
228 * the implementation is available */
229 if (conn->type == MGCP_CONN_TYPE_RTP) {
230 dump_rtp_end(vty, &conn->u.rtp);
231 }
232 }
233 }
234}
235
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200236static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
237{
238 vty_out(vty, "%s", VTY_NEWLINE);
239 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
240
241 if (ratectr->mgcp_general_ctr_group) {
242 vty_out(vty, " %s:%s",
243 ratectr->mgcp_general_ctr_group->desc->
244 group_description, VTY_NEWLINE);
245 vty_out_rate_ctr_group_fmt(vty,
246 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
247 ratectr->mgcp_general_ctr_group);
248 }
249}
250
Philipp Maier889fe7f2020-07-06 17:44:12 +0200251static void dump_ratectr_trunk(struct vty *vty, struct mgcp_trunk *trunk)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200252{
Philipp Maier889fe7f2020-07-06 17:44:12 +0200253 struct mgcp_ratectr_trunk *ratectr = &trunk->ratectr;
254
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200255 vty_out(vty, "%s", VTY_NEWLINE);
256 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
257
258 if (ratectr->mgcp_crcx_ctr_group) {
259 vty_out(vty, " %s:%s",
260 ratectr->mgcp_crcx_ctr_group->desc->group_description,
261 VTY_NEWLINE);
262 vty_out_rate_ctr_group_fmt(vty,
263 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
264 ratectr->mgcp_crcx_ctr_group);
265 }
266 if (ratectr->mgcp_dlcx_ctr_group) {
267 vty_out(vty, " %s:%s",
268 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
269 VTY_NEWLINE);
270 vty_out_rate_ctr_group_fmt(vty,
271 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
272 ratectr->mgcp_dlcx_ctr_group);
273 }
274 if (ratectr->mgcp_mdcx_ctr_group) {
275 vty_out(vty, " %s:%s",
276 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
277 VTY_NEWLINE);
278 vty_out_rate_ctr_group_fmt(vty,
279 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
280 ratectr->mgcp_mdcx_ctr_group);
281 }
282 if (ratectr->all_rtp_conn_stats) {
283 vty_out(vty, " %s:%s",
284 ratectr->all_rtp_conn_stats->desc->group_description,
285 VTY_NEWLINE);
286 vty_out_rate_ctr_group_fmt(vty,
287 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
288 ratectr->all_rtp_conn_stats);
289 }
Philipp Maier889fe7f2020-07-06 17:44:12 +0200290
291 if (ratectr->e1_stats && trunk->trunk_type == MGCP_TRUNK_E1) {
292 vty_out(vty, " %s:%s",
293 ratectr->e1_stats->desc->group_description,
294 VTY_NEWLINE);
295 vty_out_rate_ctr_group_fmt(vty,
296 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
297 ratectr->e1_stats);
298 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200299}
300
301
302static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200303{
304 int i;
305
306 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200307 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
Philipp Maier869b21c2020-07-03 16:04:16 +0200308 trunk->trunk_nr, trunk->number_endpoints, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200309
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200310 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200311 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
312 return;
313 }
314
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200315 for (i = 0; i < trunk->number_endpoints; ++i) {
316 struct mgcp_endpoint *endp = trunk->endpoints[i];
317 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
318 show_stats);
319 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200320 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200321 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200322
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200323 if (show_stats)
Philipp Maier889fe7f2020-07-06 17:44:12 +0200324 dump_ratectr_trunk(vty, trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200325}
326
Stefan Sperling12086582018-06-26 15:26:28 +0200327#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
328
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200329DEFUN(show_mcgp, show_mgcp_cmd,
330 "show mgcp [stats]",
331 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200332 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200333 "Include Statistics\n")
334{
Philipp Maier14b27a82020-06-02 20:15:30 +0200335 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200336 int show_stats = argc >= 1;
337
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200338 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200339 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200340
341 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200342 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200343 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200344
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200345 if (show_stats)
346 dump_ratectr_global(vty, &g_cfg->ratectr);
347
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200348 return CMD_SUCCESS;
349}
350
Stefan Sperling12086582018-06-26 15:26:28 +0200351static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200352dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200353{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200354 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200355
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200356 if (trunk) {
357 /* If a trunk is given, search on that specific trunk only */
358 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
359 if (!endp) {
360 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
361 return;
362 }
363 } else {
364 /* If no trunk is given, search on all possible trunks */
365 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
366 if (!endp) {
367 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
368 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200369 }
370 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200371
372 trunk = endp->trunk;
373 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200374}
375
376DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
377 "show mgcp endpoint NAME",
378 SHOW_STR
379 SHOW_MGCP_STR
380 "Display information about an endpoint\n" "The name of the endpoint\n")
381{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200382 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200383 return CMD_SUCCESS;
384}
385
386DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
387 "show mgcp trunk <0-64> endpoint NAME",
388 SHOW_STR
389 SHOW_MGCP_STR
390 "Display information about a trunk\n" "Trunk number\n"
391 "Display information about an endpoint\n" "The name of the endpoint\n")
392{
Philipp Maier14b27a82020-06-02 20:15:30 +0200393 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200394 int trunkidx = atoi(argv[0]);
395
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200396 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, trunkidx);
Stefan Sperling12086582018-06-26 15:26:28 +0200397 if (!trunk) {
398 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
399 return CMD_WARNING;
400 }
401
402 dump_mgcp_endpoint(vty, trunk, argv[1]);
403 return CMD_SUCCESS;
404}
405
Philipp Maier87bd9be2017-08-22 16:35:41 +0200406DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200407{
408 vty->node = MGCP_NODE;
409 return CMD_SUCCESS;
410}
411
412DEFUN(cfg_mgcp_local_ip,
413 cfg_mgcp_local_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200414 "local ip " VTY_IPV46_CMD,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200415 "Local options for the SDP record\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200416 IP_STR
417 "IPv4 Address to use in SDP record\n"
418 "IPv6 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200419{
420 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
421 return CMD_SUCCESS;
422}
423
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200424#define BIND_STR "Listen/Bind related socket option\n"
425DEFUN(cfg_mgcp_bind_ip,
426 cfg_mgcp_bind_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200427 "bind ip " VTY_IPV46_CMD,
428 BIND_STR IP_STR
429 "IPv4 Address to bind to\n"
430 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200431{
432 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
433 return CMD_SUCCESS;
434}
435
436DEFUN(cfg_mgcp_bind_port,
437 cfg_mgcp_bind_port_cmd,
438 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200439 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200440{
441 unsigned int port = atoi(argv[0]);
442 g_cfg->source_port = port;
443 return CMD_SUCCESS;
444}
445
446DEFUN(cfg_mgcp_bind_early,
447 cfg_mgcp_bind_early_cmd,
448 "bind early (0|1)",
449 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200450 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200451{
452 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
453 return CMD_WARNING;
454}
455
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200456#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200457#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200458#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200459#define RANGE_START_STR "Start of the range of ports\n"
460#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200461
Philipp Maierf1889d82017-11-08 14:59:39 +0100462DEFUN(cfg_mgcp_rtp_port_range,
463 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200464 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200465 RTP_STR "Range of ports to use for the NET side\n"
466 RANGE_START_STR RANGE_END_STR)
467{
Philipp Maiera19547b2018-05-22 13:44:34 +0200468 int start;
469 int end;
470
471 start = atoi(argv[0]);
472 end = atoi(argv[1]);
473
474 if (end < start) {
475 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
476 end, start, VTY_NEWLINE);
477 return CMD_WARNING;
478 }
479
480 if (start & 1) {
481 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
482 start, start & 0xFFFE, VTY_NEWLINE);
483 start &= 0xFFFE;
484 }
485
486 if ((end & 1) == 0) {
487 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
488 end, end | 1, VTY_NEWLINE);
489 end |= 1;
490 }
491
492 g_cfg->net_ports.range_start = start;
493 g_cfg->net_ports.range_end = end;
494 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
495
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200496 return CMD_SUCCESS;
497}
Philipp Maierf1889d82017-11-08 14:59:39 +0100498ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
499 cfg_mgcp_rtp_net_range_cmd,
500 "rtp net-range <0-65534> <0-65534>",
501 RTP_STR "Range of ports to use for the NET side\n"
502 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200503
Philipp Maierf1889d82017-11-08 14:59:39 +0100504DEFUN(cfg_mgcp_rtp_bind_ip,
505 cfg_mgcp_rtp_bind_ip_cmd,
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200506 "rtp bind-ip A.B.C.D",
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200507 RTP_STR "Bind endpoints facing the Network\n"
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200508 "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200509{
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200510 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v4, argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200511 return CMD_SUCCESS;
512}
Philipp Maierf1889d82017-11-08 14:59:39 +0100513ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
514 cfg_mgcp_rtp_net_bind_ip_cmd,
515 "rtp net-bind-ip A.B.C.D",
516 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200517
Philipp Maierf1889d82017-11-08 14:59:39 +0100518DEFUN(cfg_mgcp_rtp_no_bind_ip,
519 cfg_mgcp_rtp_no_bind_ip_cmd,
520 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200521 NO_STR RTP_STR "Bind endpoints facing the Network\n"
522 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200523{
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200524 talloc_free(g_cfg->net_ports.bind_addr_v4);
525 g_cfg->net_ports.bind_addr_v4 = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200526 return CMD_SUCCESS;
527}
Philipp Maierf1889d82017-11-08 14:59:39 +0100528ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
529 cfg_mgcp_rtp_no_net_bind_ip_cmd,
530 "no rtp net-bind-ip",
531 NO_STR RTP_STR "Bind endpoints facing the Network\n"
532 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200533
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +0200534DEFUN(cfg_mgcp_rtp_bind_ip_v6,
535 cfg_mgcp_rtp_bind_ip_v6_cmd,
536 "rtp bind-ip-v6 " VTY_IPV6_CMD,
537 RTP_STR "Bind endpoints facing the Network\n"
538 "IPv6 Address to bind to\n")
539{
540 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v6, argv[0]);
541 return CMD_SUCCESS;
542}
543
544DEFUN(cfg_mgcp_rtp_no_bind_ip_v6,
545cfg_mgcp_rtp_no_bind_ip_v6_cmd,
546"no rtp bind-ip-v6",
547NO_STR RTP_STR "Bind endpoints facing the Network\n"
548"Address to bind to\n")
549{
550 talloc_free(g_cfg->net_ports.bind_addr_v6);
551 g_cfg->net_ports.bind_addr_v6 = NULL;
552 return CMD_SUCCESS;
553}
554
Philipp Maier1cb1e382017-11-02 17:16:04 +0100555DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
556 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
557 "rtp ip-probing",
558 RTP_STR "automatic rtp bind ip selection\n")
559{
560 g_cfg->net_ports.bind_addr_probe = true;
561 return CMD_SUCCESS;
562}
563
564DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
565 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
566 "no rtp ip-probing",
567 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
568{
569 g_cfg->net_ports.bind_addr_probe = false;
570 return CMD_SUCCESS;
571}
572
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200573DEFUN(cfg_mgcp_rtp_ip_dscp,
574 cfg_mgcp_rtp_ip_dscp_cmd,
575 "rtp ip-dscp <0-255>",
576 RTP_STR
577 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
578{
579 int dscp = atoi(argv[0]);
580 g_cfg->endp_dscp = dscp;
581 return CMD_SUCCESS;
582}
583
584ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200585 "rtp ip-tos <0-255>",
586 RTP_STR
587 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
588#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200589DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200590 cfg_mgcp_rtp_force_ptime_cmd,
591 "rtp force-ptime (10|20|40)",
592 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200593 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200594{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200595 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200596 return CMD_SUCCESS;
597}
598
599DEFUN(cfg_mgcp_no_rtp_force_ptime,
600 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200601 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200602{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200603 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200604 return CMD_SUCCESS;
605}
606
607DEFUN(cfg_mgcp_sdp_fmtp_extra,
608 cfg_mgcp_sdp_fmtp_extra_cmd,
609 "sdp audio fmtp-extra .NAME",
610 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
611 "Extra Information\n")
612{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200613 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200614 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200615 char *txt = argv_concat(argv, argc, 0);
616 if (!txt)
617 return CMD_WARNING;
618
Philipp Maierd19de2e2020-06-03 13:55:33 +0200619 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200620 talloc_free(txt);
621 return CMD_SUCCESS;
622}
623
624DEFUN(cfg_mgcp_allow_transcoding,
625 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200626 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200627{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200628 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200629 OSMO_ASSERT(trunk);
630 trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200631 return CMD_SUCCESS;
632}
633
634DEFUN(cfg_mgcp_no_allow_transcoding,
635 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200636 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200637{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200638 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200639 OSMO_ASSERT(trunk);
640 trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200641 return CMD_SUCCESS;
642}
643
644#define SDP_STR "SDP File related options\n"
645#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200646DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200647 cfg_mgcp_sdp_payload_number_cmd,
648 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200649 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200650{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200651 return CMD_SUCCESS;
652}
653
Philipp Maier87bd9be2017-08-22 16:35:41 +0200654ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
655 cfg_mgcp_sdp_payload_number_cmd_old,
656 "sdp audio payload number <0-255>",
657 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200658
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200659DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200660 cfg_mgcp_sdp_payload_name_cmd,
661 "sdp audio-payload name NAME",
662 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
663{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200664 return CMD_SUCCESS;
665}
666
667ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200668 "sdp audio payload name NAME",
669 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200670
Philipp Maier21be42a2020-05-29 21:39:48 +0200671DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200672 cfg_mgcp_sdp_payload_send_ptime_cmd,
673 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200674 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200675{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200676 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200677 OSMO_ASSERT(trunk);
678 trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200679 return CMD_SUCCESS;
680}
681
682DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
683 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
684 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200685 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200686{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200687 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200688 OSMO_ASSERT(trunk);
689 trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200690 return CMD_SUCCESS;
691}
692
693DEFUN(cfg_mgcp_sdp_payload_send_name,
694 cfg_mgcp_sdp_payload_send_name_cmd,
695 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200696 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200697{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200698 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200699 OSMO_ASSERT(trunk);
700 trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200701 return CMD_SUCCESS;
702}
703
704DEFUN(cfg_mgcp_no_sdp_payload_send_name,
705 cfg_mgcp_no_sdp_payload_send_name_cmd,
706 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200707 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200708{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200709 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200710 OSMO_ASSERT(trunk);
711 trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200712 return CMD_SUCCESS;
713}
714
715DEFUN(cfg_mgcp_loop,
716 cfg_mgcp_loop_cmd,
717 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200718 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200719{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200720 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200721 OSMO_ASSERT(trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200722 if (g_cfg->osmux) {
723 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
724 return CMD_WARNING;
725 }
Philipp Maierd19de2e2020-06-03 13:55:33 +0200726 trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200727 return CMD_SUCCESS;
728}
729
730DEFUN(cfg_mgcp_force_realloc,
731 cfg_mgcp_force_realloc_cmd,
732 "force-realloc (0|1)",
733 "Force endpoint reallocation when the endpoint is still seized\n"
734 "Don't force reallocation\n" "force reallocation\n")
735{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200736 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200737 OSMO_ASSERT(trunk);
738 trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200739 return CMD_SUCCESS;
740}
741
Philipp Maier87bd9be2017-08-22 16:35:41 +0200742DEFUN(cfg_mgcp_rtp_accept_all,
743 cfg_mgcp_rtp_accept_all_cmd,
744 "rtp-accept-all (0|1)",
745 "Accept all RTP packets, even when the originating IP/Port does not match\n"
746 "enable filter\n" "disable filter\n")
747{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200748 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200749 OSMO_ASSERT(trunk);
750 trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200751 return CMD_SUCCESS;
752}
753
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200754DEFUN(cfg_mgcp_number_endp,
755 cfg_mgcp_number_endp_cmd,
Philipp Maier869b21c2020-07-03 16:04:16 +0200756 "number endpoints <1-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200757 "Number options\n" "Endpoints available\n" "Number endpoints\n")
758{
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 OSMO_ASSERT(trunk);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200761 trunk->v.vty_number_endpoints = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200762 return CMD_SUCCESS;
763}
764
Philipp Maier87bd9be2017-08-22 16:35:41 +0200765DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", 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 trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200769 return CMD_SUCCESS;
770}
771
772DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200773 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200774{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200775 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200776 OSMO_ASSERT(trunk);
777 trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200778 return CMD_SUCCESS;
779}
780
781DEFUN(cfg_mgcp_patch_rtp_ssrc,
782 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200783 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200784{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200785 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200786 OSMO_ASSERT(trunk);
787 trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200788 return CMD_SUCCESS;
789}
790
791DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
792 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200793 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200794{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200795 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200796 OSMO_ASSERT(trunk);
797 trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200798 return CMD_SUCCESS;
799}
800
801DEFUN(cfg_mgcp_patch_rtp_ts,
802 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200803 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200804{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200805 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200806 OSMO_ASSERT(trunk);
807 trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200808 return CMD_SUCCESS;
809}
810
811DEFUN(cfg_mgcp_no_patch_rtp_ts,
812 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200813 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200814{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200815 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200816 OSMO_ASSERT(trunk);
817 trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200818 return CMD_SUCCESS;
819}
820
Philipp Maier9fc8a022019-02-20 12:26:52 +0100821DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
822 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
823 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
824{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200825 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200826 OSMO_ASSERT(trunk);
827 trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100828 return CMD_SUCCESS;
829}
830
831DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
832 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
833 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
834{
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->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100838 return CMD_SUCCESS;
839}
840
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200841DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200842 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200843{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200844 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200845 OSMO_ASSERT(trunk);
846 trunk->force_constant_ssrc = 0;
847 trunk->force_aligned_timing = 0;
848 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200849 return CMD_SUCCESS;
850}
851
852DEFUN(cfg_mgcp_rtp_keepalive,
853 cfg_mgcp_rtp_keepalive_cmd,
854 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200855 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200856{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200857 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200858 OSMO_ASSERT(trunk);
859 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200860 return CMD_SUCCESS;
861}
862
863DEFUN(cfg_mgcp_rtp_keepalive_once,
864 cfg_mgcp_rtp_keepalive_once_cmd,
865 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200866 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200867{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200868 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200869 OSMO_ASSERT(trunk);
870 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200871 return CMD_SUCCESS;
872}
873
874DEFUN(cfg_mgcp_no_rtp_keepalive,
875 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200876 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200877{
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200878 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +0200879 OSMO_ASSERT(trunk);
880 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200881 return CMD_SUCCESS;
882}
883
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200884#define CALL_AGENT_STR "Call agent information\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200885DEFUN(cfg_mgcp_agent_addr,
886 cfg_mgcp_agent_addr_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +0200887 "call-agent ip " VTY_IPV46_CMD,
888 CALL_AGENT_STR IP_STR
889 "IPv4 Address of the call agent\n"
890 "IPv6 Address of the call agent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200891{
892 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
893 return CMD_SUCCESS;
894}
895
896ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200897 "call agent ip A.B.C.D",
898 CALL_AGENT_STR CALL_AGENT_STR IP_STR
899 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200900
Philipp Maier21be42a2020-05-29 21:39:48 +0200901DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier0653cc82020-08-10 22:52:51 +0200902 "trunk <0-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200903{
Philipp Maier14b27a82020-06-02 20:15:30 +0200904 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200905 int index = atoi(argv[0]);
906
Philipp Maier6fbbeec2020-07-01 23:00:54 +0200907 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100908 if (!trunk) {
909 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200910 if (!trunk) {
911 vty_out(vty, "%%Unable to allocate trunk %u.%s",
912 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100913 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200914 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200915 }
916
917 vty->node = TRUNK_NODE;
918 vty->index = trunk;
919 return CMD_SUCCESS;
920}
921
922static int config_write_trunk(struct vty *vty)
923{
Philipp Maier14b27a82020-06-02 20:15:30 +0200924 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200925
926 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierd19de2e2020-06-03 13:55:33 +0200927
928 /* Due to historical reasons, the virtual trunk is configured
929 using separate VTY parameters, so we omit writing the trunk
930 config of trunk 0 here. The configuration for the virtual
931 trunk is written by config_write_mgcp(). */
932
933 if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
934 continue;
935
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200936 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Philipp Maier889fe7f2020-07-06 17:44:12 +0200937 vty_out(vty, " line %u%s", trunk->e1.vty_line_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200938 vty_out(vty, " %ssdp audio-payload send-ptime%s",
939 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
940 vty_out(vty, " %ssdp audio-payload send-name%s",
941 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
942
943 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
944 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
945 else if (trunk->keepalive_interval)
946 vty_out(vty, " rtp keep-alive %d%s",
947 trunk->keepalive_interval, VTY_NEWLINE);
948 else
949 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200950 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200951 vty_out(vty, " force-realloc %d%s",
952 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200953 vty_out(vty, " rtp-accept-all %d%s",
954 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200955 if (trunk->omit_rtcp)
956 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
957 else
958 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100959 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Philipp Maierd19de2e2020-06-03 13:55:33 +0200960 || trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200961 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200962 trunk->force_constant_ssrc ? "" : "no ",
963 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200964 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200965 trunk->force_aligned_timing ? "" : "no ",
966 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100967 vty_out(vty, " %srtp-patch rfc5993hr%s",
968 trunk->rfc5993_hr_convert ? "" : "no ",
969 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200970 } else
971 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
972 if (trunk->audio_fmtp_extra)
973 vty_out(vty, " sdp audio fmtp-extra %s%s",
974 trunk->audio_fmtp_extra, VTY_NEWLINE);
975 vty_out(vty, " %sallow-transcoding%s",
976 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
977 }
978
979 return CMD_SUCCESS;
980}
981
982DEFUN(cfg_trunk_sdp_fmtp_extra,
983 cfg_trunk_sdp_fmtp_extra_cmd,
984 "sdp audio fmtp-extra .NAME",
985 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
986 "Extra Information\n")
987{
Philipp Maier14b27a82020-06-02 20:15:30 +0200988 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200989 char *txt = argv_concat(argv, argc, 0);
990 if (!txt)
991 return CMD_WARNING;
992
993 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
994 talloc_free(txt);
995 return CMD_SUCCESS;
996}
997
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200998DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200999 cfg_trunk_payload_number_cmd,
1000 "sdp audio-payload number <0-255>",
1001 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
1002{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001003 return CMD_SUCCESS;
1004}
1005
1006ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001007 "sdp audio payload number <0-255>",
1008 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001009
Philipp Maier7f90ddb2020-06-02 21:52:53 +02001010DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001011 cfg_trunk_payload_name_cmd,
1012 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001013 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001014{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001015 return CMD_SUCCESS;
1016}
1017
1018ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001019 "sdp audio payload name NAME",
1020 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001021
Philipp Maier21be42a2020-05-29 21:39:48 +02001022DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001023 cfg_trunk_loop_cmd,
1024 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001025 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001026{
Philipp Maier14b27a82020-06-02 20:15:30 +02001027 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001028
1029 if (g_cfg->osmux) {
1030 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
1031 return CMD_WARNING;
1032 }
1033 trunk->audio_loop = atoi(argv[0]);
1034 return CMD_SUCCESS;
1035}
1036
1037DEFUN(cfg_trunk_sdp_payload_send_ptime,
1038 cfg_trunk_sdp_payload_send_ptime_cmd,
1039 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001040 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001041{
Philipp Maier14b27a82020-06-02 20:15:30 +02001042 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001043 trunk->audio_send_ptime = 1;
1044 return CMD_SUCCESS;
1045}
1046
1047DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
1048 cfg_trunk_no_sdp_payload_send_ptime_cmd,
1049 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001050 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001051{
Philipp Maier14b27a82020-06-02 20:15:30 +02001052 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001053 trunk->audio_send_ptime = 0;
1054 return CMD_SUCCESS;
1055}
1056
1057DEFUN(cfg_trunk_sdp_payload_send_name,
1058 cfg_trunk_sdp_payload_send_name_cmd,
1059 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001060 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
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->audio_send_name = 1;
1064 return CMD_SUCCESS;
1065}
1066
1067DEFUN(cfg_trunk_no_sdp_payload_send_name,
1068 cfg_trunk_no_sdp_payload_send_name_cmd,
1069 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001070 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001071{
Philipp Maier14b27a82020-06-02 20:15:30 +02001072 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001073 trunk->audio_send_name = 0;
1074 return CMD_SUCCESS;
1075}
1076
Philipp Maier87bd9be2017-08-22 16:35:41 +02001077DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
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->omit_rtcp = 1;
1081 return CMD_SUCCESS;
1082}
1083
1084DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001085 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001086{
Philipp Maier14b27a82020-06-02 20:15:30 +02001087 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001088 trunk->omit_rtcp = 0;
1089 return CMD_SUCCESS;
1090}
1091
1092DEFUN(cfg_trunk_patch_rtp_ssrc,
1093 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001094 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001095{
Philipp Maier14b27a82020-06-02 20:15:30 +02001096 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001097 trunk->force_constant_ssrc = 1;
1098 return CMD_SUCCESS;
1099}
1100
1101DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1102 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001103 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001104{
Philipp Maier14b27a82020-06-02 20:15:30 +02001105 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001106 trunk->force_constant_ssrc = 0;
1107 return CMD_SUCCESS;
1108}
1109
1110DEFUN(cfg_trunk_patch_rtp_ts,
1111 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001112 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001113{
Philipp Maier14b27a82020-06-02 20:15:30 +02001114 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001115 trunk->force_aligned_timing = 1;
1116 return CMD_SUCCESS;
1117}
1118
1119DEFUN(cfg_trunk_no_patch_rtp_ts,
1120 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001121 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001122{
Philipp Maier14b27a82020-06-02 20:15:30 +02001123 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001124 trunk->force_aligned_timing = 0;
1125 return CMD_SUCCESS;
1126}
1127
Philipp Maier9fc8a022019-02-20 12:26:52 +01001128DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1129 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1130 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1131{
Philipp Maier14b27a82020-06-02 20:15:30 +02001132 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001133 trunk->rfc5993_hr_convert = true;
1134 return CMD_SUCCESS;
1135}
1136
1137DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1138 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1139 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1140{
Philipp Maier14b27a82020-06-02 20:15:30 +02001141 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001142 trunk->rfc5993_hr_convert = false;
1143 return CMD_SUCCESS;
1144}
1145
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001146DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001147 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001148{
Philipp Maier14b27a82020-06-02 20:15:30 +02001149 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001150 trunk->force_constant_ssrc = 0;
1151 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001152 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001153 return CMD_SUCCESS;
1154}
1155
1156DEFUN(cfg_trunk_rtp_keepalive,
1157 cfg_trunk_rtp_keepalive_cmd,
1158 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001159 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001160{
Philipp Maier14b27a82020-06-02 20:15:30 +02001161 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001162 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1163 return CMD_SUCCESS;
1164}
1165
1166DEFUN(cfg_trunk_rtp_keepalive_once,
1167 cfg_trunk_rtp_keepalive_once_cmd,
1168 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001169 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001170{
Philipp Maier14b27a82020-06-02 20:15:30 +02001171 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001172 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1173 return CMD_SUCCESS;
1174}
1175
1176DEFUN(cfg_trunk_no_rtp_keepalive,
1177 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001178 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001179{
Philipp Maier14b27a82020-06-02 20:15:30 +02001180 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001181 mgcp_trunk_set_keepalive(trunk, 0);
1182 return CMD_SUCCESS;
1183}
1184
1185DEFUN(cfg_trunk_allow_transcoding,
1186 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001187 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001188{
Philipp Maier14b27a82020-06-02 20:15:30 +02001189 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001190 trunk->no_audio_transcoding = 0;
1191 return CMD_SUCCESS;
1192}
1193
1194DEFUN(cfg_trunk_no_allow_transcoding,
1195 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001196 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001197{
Philipp Maier14b27a82020-06-02 20:15:30 +02001198 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001199 trunk->no_audio_transcoding = 1;
1200 return CMD_SUCCESS;
1201}
1202
Philipp Maier889fe7f2020-07-06 17:44:12 +02001203#define LINE_STR "Configure trunk for given Line\nE1/T1 Line Number\n"
1204
1205DEFUN(cfg_trunk_line,
1206 cfg_trunk_line_cmd,
1207 "line <0-255>",
1208 LINE_STR)
1209{
1210 struct mgcp_trunk *trunk = vty->index;
1211 int line_nr = atoi(argv[0]);
1212 trunk->e1.vty_line_nr = line_nr;
1213 return CMD_SUCCESS;
1214}
1215
Philipp Maier87bd9be2017-08-22 16:35:41 +02001216DEFUN(loop_conn,
1217 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001218 "loop-endpoint <0-64> NAME (0|1)",
1219 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001220 "The name in hex of the endpoint\n" "Disable the loop\n"
1221 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001222{
Philipp Maier14b27a82020-06-02 20:15:30 +02001223 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001224 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001225 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001226
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001227 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001228 if (!trunk) {
1229 vty_out(vty, "%%Trunk %d not found in the config.%s",
1230 atoi(argv[0]), VTY_NEWLINE);
1231 return CMD_WARNING;
1232 }
1233
1234 if (!trunk->endpoints) {
1235 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1236 trunk->trunk_nr, VTY_NEWLINE);
1237 return CMD_WARNING;
1238 }
1239
1240 int endp_no = strtoul(argv[1], NULL, 16);
1241 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1242 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001243 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001244 return CMD_WARNING;
1245 }
1246
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001247 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001248 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001249 llist_for_each_entry(conn, &endp->conns, entry) {
1250 if (conn->type == MGCP_CONN_TYPE_RTP)
1251 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1252 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1253 else {
1254 /* FIXME: Introduce support for other connection (E1)
1255 * types when implementation is available */
1256 vty_out(vty, "%%Can't enable SSRC patching,"
1257 "connection %s is not an RTP connection.%s",
1258 mgcp_conn_dump(conn), VTY_NEWLINE);
1259 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001260
Philipp Maier87bd9be2017-08-22 16:35:41 +02001261 if (loop)
1262 conn->mode = MGCP_CONN_LOOPBACK;
1263 else
1264 conn->mode = conn->mode_orig;
1265 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001266
1267 return CMD_SUCCESS;
1268}
1269
Philipp Maier87bd9be2017-08-22 16:35:41 +02001270DEFUN(tap_rtp,
1271 tap_rtp_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001272 "tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001273 "Forward data on endpoint to a different system\n" "Trunk number\n"
1274 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001275 "The connection id in hex\n"
1276 "Forward incoming data\n"
1277 "Forward leaving data\n"
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001278 "Destination IPv4 of the data\n"
1279 "Destination IPv6 of the data\n"
1280 "Destination port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001281{
1282 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001283 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001284 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001285 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001286 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001287
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001288 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001289 if (!trunk) {
1290 vty_out(vty, "%%Trunk %d not found in the config.%s",
1291 atoi(argv[0]), VTY_NEWLINE);
1292 return CMD_WARNING;
1293 }
1294
1295 if (!trunk->endpoints) {
1296 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1297 trunk->trunk_nr, VTY_NEWLINE);
1298 return CMD_WARNING;
1299 }
1300
1301 int endp_no = strtoul(argv[1], NULL, 16);
1302 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1303 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001304 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001305 return CMD_WARNING;
1306 }
1307
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001308 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001309
Philipp Maier01d24a32017-11-21 17:26:09 +01001310 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001311 conn = mgcp_conn_get_rtp(endp, conn_id);
1312 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001313 vty_out(vty, "Conn ID %s is invalid.%s",
1314 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001315 return CMD_WARNING;
1316 }
1317
1318 if (strcmp(argv[3], "in") == 0)
1319 tap = &conn->tap_in;
1320 else if (strcmp(argv[3], "out") == 0)
1321 tap = &conn->tap_out;
1322 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001323 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1324 return CMD_WARNING;
1325 }
1326
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001327 memset(&tap->forward, 0, sizeof(tap->forward));
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001328
1329 tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);
1330 switch (tap->forward.u.sa.sa_family) {
1331 case AF_INET:
1332 if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)
1333 return CMD_WARNING;
1334 tap->forward.u.sin.sin_port = htons(atoi(argv[5]));
1335 break;
1336 case AF_INET6:
1337 if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)
1338 return CMD_WARNING;
1339 tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));
1340 break;
1341 default:
1342 return CMD_WARNING;
1343 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001344 tap->enabled = 1;
1345 return CMD_SUCCESS;
1346}
1347
1348DEFUN(free_endp, free_endp_cmd,
1349 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001350 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001351{
Philipp Maier14b27a82020-06-02 20:15:30 +02001352 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001353 struct mgcp_endpoint *endp;
1354
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001355 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001356 if (!trunk) {
1357 vty_out(vty, "%%Trunk %d not found in the config.%s",
1358 atoi(argv[0]), VTY_NEWLINE);
1359 return CMD_WARNING;
1360 }
1361
1362 if (!trunk->endpoints) {
1363 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1364 trunk->trunk_nr, VTY_NEWLINE);
1365 return CMD_WARNING;
1366 }
1367
1368 int endp_no = strtoul(argv[1], NULL, 16);
1369 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1370 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001371 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001372 return CMD_WARNING;
1373 }
1374
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001375 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001376 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001377 return CMD_SUCCESS;
1378}
1379
1380DEFUN(reset_endp, reset_endp_cmd,
1381 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001382 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001383{
Philipp Maier14b27a82020-06-02 20:15:30 +02001384 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001385 struct mgcp_endpoint *endp;
1386 int endp_no, rc;
1387
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001388 trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_E1, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001389 if (!trunk) {
1390 vty_out(vty, "%%Trunk %d not found in the config.%s",
1391 atoi(argv[0]), VTY_NEWLINE);
1392 return CMD_WARNING;
1393 }
1394
1395 if (!trunk->endpoints) {
1396 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1397 trunk->trunk_nr, VTY_NEWLINE);
1398 return CMD_WARNING;
1399 }
1400
1401 endp_no = strtoul(argv[1], NULL, 16);
1402 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1403 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001404 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001405 return CMD_WARNING;
1406 }
1407
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001408 endp = trunk->endpoints[endp_no];
1409 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001410 if (rc < 0) {
1411 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1412 return CMD_WARNING;
1413 }
1414 return CMD_SUCCESS;
1415}
1416
1417DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001418 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001419{
1420 int rc;
1421
1422 rc = mgcp_send_reset_all(g_cfg);
1423 if (rc < 0) {
1424 vty_out(vty, "Error %d during endpoint reset.%s",
1425 rc, VTY_NEWLINE);
1426 return CMD_WARNING;
1427 }
1428 return CMD_SUCCESS;
1429}
1430
1431#define OSMUX_STR "RTP multiplexing\n"
1432DEFUN(cfg_mgcp_osmux,
1433 cfg_mgcp_osmux_cmd,
1434 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001435 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001436{
Philipp Maier6fbbeec2020-07-01 23:00:54 +02001437 struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
Philipp Maierd19de2e2020-06-03 13:55:33 +02001438 OSMO_ASSERT(trunk);
1439
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001440 if (strcmp(argv[0], "off") == 0) {
1441 g_cfg->osmux = OSMUX_USAGE_OFF;
1442 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001443 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001444 g_cfg->osmux = OSMUX_USAGE_ON;
1445 else if (strcmp(argv[0], "only") == 0)
1446 g_cfg->osmux = OSMUX_USAGE_ONLY;
1447
Philipp Maierd19de2e2020-06-03 13:55:33 +02001448 if (trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001449 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001450 return CMD_WARNING;
1451 }
1452
1453 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001454
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001455}
1456
1457DEFUN(cfg_mgcp_osmux_ip,
1458 cfg_mgcp_osmux_ip_cmd,
Pau Espin Pedrola790f0c2020-08-31 13:29:11 +02001459 "osmux bind-ip " VTY_IPV46_CMD,
1460 OSMUX_STR IP_STR
1461 "IPv4 Address to bind to\n"
1462 "IPv6 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001463{
1464 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1465 return CMD_SUCCESS;
1466}
1467
1468DEFUN(cfg_mgcp_osmux_batch_factor,
1469 cfg_mgcp_osmux_batch_factor_cmd,
1470 "osmux batch-factor <1-8>",
1471 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1472{
1473 g_cfg->osmux_batch = atoi(argv[0]);
1474 return CMD_SUCCESS;
1475}
1476
1477DEFUN(cfg_mgcp_osmux_batch_size,
1478 cfg_mgcp_osmux_batch_size_cmd,
1479 "osmux batch-size <1-65535>",
1480 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1481{
1482 g_cfg->osmux_batch_size = atoi(argv[0]);
1483 return CMD_SUCCESS;
1484}
1485
1486DEFUN(cfg_mgcp_osmux_port,
1487 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001488 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001489{
1490 g_cfg->osmux_port = atoi(argv[0]);
1491 return CMD_SUCCESS;
1492}
1493
1494DEFUN(cfg_mgcp_osmux_dummy,
1495 cfg_mgcp_osmux_dummy_cmd,
1496 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001497 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1498 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001499{
1500 if (strcmp(argv[0], "on") == 0)
1501 g_cfg->osmux_dummy = 1;
1502 else if (strcmp(argv[0], "off") == 0)
1503 g_cfg->osmux_dummy = 0;
1504
1505 return CMD_SUCCESS;
1506}
1507
Philipp Maier12943ea2018-01-17 15:40:25 +01001508DEFUN(cfg_mgcp_domain,
1509 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001510 "domain NAME",
1511 "Set the domain part expected in MGCP messages' endpoint names\n"
1512 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001513{
1514 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1515 return CMD_SUCCESS;
1516}
1517
Oliver Smithe36b7752019-01-22 16:31:36 +01001518DEFUN(cfg_mgcp_conn_timeout,
1519 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001520 "conn-timeout <0-65534>",
1521 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1522 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001523 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1524 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001525 "Timeout value (sec.)\n")
1526{
1527 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1528 return CMD_SUCCESS;
1529}
1530
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001531int mgcp_vty_init(void)
1532{
1533 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001534 install_element_ve(&show_mgcp_endpoint_cmd);
1535 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001536 install_element(ENABLE_NODE, &loop_conn_cmd);
1537 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001538 install_element(ENABLE_NODE, &free_endp_cmd);
1539 install_element(ENABLE_NODE, &reset_endp_cmd);
1540 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1541
1542 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1543 install_node(&mgcp_node, config_write_mgcp);
1544
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001545 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001546 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1547 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1548 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001549 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001550 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001551 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001552 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001553 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_v6_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001554 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001555 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Pau Espin Pedrol8a2a1b22020-09-02 20:46:24 +02001556 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_v6_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001557 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1558 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001559 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1560 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1561 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1562 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1563 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1564 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1565 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1566 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1567 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001568 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1569 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1570 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1571 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1572 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1573 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001574 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001575 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1576 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1577 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1578 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1579 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1580 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1581 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1582 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001583 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1584 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001585 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1586 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1587 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1588 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1589 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1590 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1591 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1592 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1593 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1594 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1595 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1596 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1597 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001598 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001599 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001600
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001601 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1602 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001603 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1604 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1605 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1606 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1607 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1608 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1609 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1610 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1611 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1612 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1613 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1614 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1615 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001616 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1617 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001618 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1619 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1620 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1621 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1622 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1623 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1624 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1625 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1626 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
Philipp Maier889fe7f2020-07-06 17:44:12 +02001627 install_element(TRUNK_NODE, &cfg_trunk_line_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001628
1629 return 0;
1630}
1631
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001632int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1633 enum mgcp_role role)
1634{
1635 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001636 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001637
1638 cfg->osmux_port = OSMUX_PORT;
1639 cfg->osmux_batch = 4;
1640 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1641
1642 g_cfg = cfg;
1643 rc = vty_read_config_file(config_file, NULL);
1644 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001645 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1646 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001647 return rc;
1648 }
1649
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001650 if (!g_cfg->source_addr) {
1651 fprintf(stderr, "You need to specify a bind address.\n");
1652 return -1;
1653 }
1654
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001655 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier889fe7f2020-07-06 17:44:12 +02001656 if (mgcp_trunk_equip(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001657 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001658 "Failed to initialize trunk %d (%d endpoints)\n",
1659 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001660 return -1;
1661 }
1662 }
1663 cfg->role = role;
1664
1665 return 0;
1666}