blob: 4cfe3b58497a88540990ae97a1d353f94ae91507 [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>
Stefan Sperling1e174872018-10-25 18:36:10 +020025#include <osmocom/vty/misc.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020026#include <osmocom/mgcp/mgcp.h>
Neels Hofmeyr67793542017-09-08 04:25:16 +020027#include <osmocom/mgcp/mgcp_common.h>
Philipp Maier87bd9be2017-08-22 16:35:41 +020028#include <osmocom/mgcp/mgcp_internal.h>
29#include <osmocom/mgcp/vty.h>
30#include <osmocom/mgcp/mgcp_conn.h>
Philipp Maier37d11c82018-02-01 14:38:12 +010031#include <osmocom/mgcp/mgcp_endp.h>
Philipp Maierc66ab2c2020-06-02 20:55:34 +020032#include <osmocom/mgcp/mgcp_trunk.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020033
34#include <string.h>
Philipp Maierbca0ef62018-07-09 17:20:51 +020035#include <inttypes.h>
Stefan Sperling12086582018-06-26 15:26:28 +020036#include <limits.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020037
38#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
39#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
40#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
Philipp Maier9fc8a022019-02-20 12:26:52 +010041#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"
42
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020043
44static struct mgcp_config *g_cfg = NULL;
45
Philipp Maier14b27a82020-06-02 20:15:30 +020046static struct mgcp_trunk *find_trunk(struct mgcp_config *cfg, int nr)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020047{
Philipp Maier14b27a82020-06-02 20:15:30 +020048 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020049
50 if (nr == 0)
Harald Weltec39b1bf2020-03-08 11:29:39 +010051 trunk = cfg->virt_trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020052 else
Philipp Maierc66ab2c2020-06-02 20:55:34 +020053 trunk = mgcp_trunk_by_num(cfg, nr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020054
55 return trunk;
56}
57
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020058struct cmd_node mgcp_node = {
59 MGCP_NODE,
60 "%s(config-mgcp)# ",
61 1,
62};
63
64struct cmd_node trunk_node = {
65 TRUNK_NODE,
66 "%s(config-mgcp-trunk)# ",
67 1,
68};
69
70static int config_write_mgcp(struct vty *vty)
71{
Philipp Maier14b27a82020-06-02 20:15:30 +020072 struct mgcp_trunk *trunk = g_cfg->virt_trunk;
Harald Weltec39b1bf2020-03-08 11:29:39 +010073
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020074 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020075 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020076 if (g_cfg->local_ip)
77 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020078 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
79 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
80 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020081 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
82 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020083 if (g_cfg->net_ports.bind_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +020084 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020085 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010086 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020087 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010088 else
Philipp Maierf53796c2020-06-02 20:38:28 +020089 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
90 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010091 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020092 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010093 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020094 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010095 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020096 else
Philipp Maierf53796c2020-06-02 20:38:28 +020097 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020098
Harald Weltec39b1bf2020-03-08 11:29:39 +010099 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +0200100 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200101 else
Philipp Maierf53796c2020-06-02 20:38:28 +0200102 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100103 if (trunk->force_constant_ssrc
104 || trunk->force_aligned_timing
105 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200106 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100107 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200108 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200109 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100110 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200111 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200112 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100113 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100114 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200115 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200116 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100117 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200118 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100119 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200120 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100121 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200122 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100123 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200124 vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
125 vty_out(vty, " number endpoints %u%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100126 trunk->vty_number_endpoints - 1, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200127 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100128 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200129 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200130 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200131 VTY_NEWLINE);
132 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200133 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200134 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200135
136 switch (g_cfg->osmux) {
137 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200138 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200139 break;
140 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200141 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200142 break;
143 case OSMUX_USAGE_OFF:
144 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200145 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200146 break;
147 }
148 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200149 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200150 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200151 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200152 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200153 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200154 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200155 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200156 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200157 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200158 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
159 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100160
161 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200162 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100163
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200164 return CMD_SUCCESS;
165}
166
Philipp Maiercede2a42018-07-03 14:14:21 +0200167static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200168{
Philipp Maiercede2a42018-07-03 14:14:21 +0200169 struct mgcp_rtp_state *state = &conn->state;
170 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200171 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100172 struct rate_ctr *tx_packets, *tx_bytes;
173 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200174 struct rate_ctr *dropped_packets;
175
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100176 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
177 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
178 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
179 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200180 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200181
182 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100183 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
184 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200185 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
186 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200187 " Payload Type: %d Rate: %u Channels: %d %s"
188 " Frame Duration: %u Frame Denominator: %u%s"
189 " FPP: %d Packet Duration: %u%s"
190 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
191 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100192 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
193 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200194 state->in_stream.err_ts_ctr->current,
195 state->out_stream.err_ts_ctr->current,
196 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200197 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200198 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200199 codec->frame_duration_num, codec->frame_duration_den,
200 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
201 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
202 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
203 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200204}
205
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200206static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
Stefan Sperling12086582018-06-26 15:26:28 +0200207 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200208{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200209 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200210
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200211 vty_out(vty, "%s trunk %d endpoint %s:%s",
212 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
Stefan Sperling12086582018-06-26 15:26:28 +0200213
214 if (llist_empty(&endp->conns)) {
215 vty_out(vty, " No active connections%s", VTY_NEWLINE);
216 return;
217 }
218
219 llist_for_each_entry(conn, &endp->conns, entry) {
220 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
221
222 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100223 if (endp->cfg->conn_timeout) {
224 struct timeval remaining;
225 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
226 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
227 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
228 }
229
Stefan Sperling12086582018-06-26 15:26:28 +0200230 /* FIXME: Also add verbosity for other
231 * connection types (E1) as soon as
232 * the implementation is available */
233 if (conn->type == MGCP_CONN_TYPE_RTP) {
234 dump_rtp_end(vty, &conn->u.rtp);
235 }
236 }
237 }
238}
239
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200240static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
241{
242 vty_out(vty, "%s", VTY_NEWLINE);
243 vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
244
245 if (ratectr->mgcp_general_ctr_group) {
246 vty_out(vty, " %s:%s",
247 ratectr->mgcp_general_ctr_group->desc->
248 group_description, VTY_NEWLINE);
249 vty_out_rate_ctr_group_fmt(vty,
250 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
251 ratectr->mgcp_general_ctr_group);
252 }
253}
254
255static void dump_ratectr_trunk(struct vty *vty, struct mgcp_ratectr_trunk *ratectr)
256{
257 vty_out(vty, "%s", VTY_NEWLINE);
258 vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
259
260 if (ratectr->mgcp_crcx_ctr_group) {
261 vty_out(vty, " %s:%s",
262 ratectr->mgcp_crcx_ctr_group->desc->group_description,
263 VTY_NEWLINE);
264 vty_out_rate_ctr_group_fmt(vty,
265 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
266 ratectr->mgcp_crcx_ctr_group);
267 }
268 if (ratectr->mgcp_dlcx_ctr_group) {
269 vty_out(vty, " %s:%s",
270 ratectr->mgcp_dlcx_ctr_group->desc->group_description,
271 VTY_NEWLINE);
272 vty_out_rate_ctr_group_fmt(vty,
273 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
274 ratectr->mgcp_dlcx_ctr_group);
275 }
276 if (ratectr->mgcp_mdcx_ctr_group) {
277 vty_out(vty, " %s:%s",
278 ratectr->mgcp_mdcx_ctr_group->desc->group_description,
279 VTY_NEWLINE);
280 vty_out_rate_ctr_group_fmt(vty,
281 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
282 ratectr->mgcp_mdcx_ctr_group);
283 }
284 if (ratectr->all_rtp_conn_stats) {
285 vty_out(vty, " %s:%s",
286 ratectr->all_rtp_conn_stats->desc->group_description,
287 VTY_NEWLINE);
288 vty_out_rate_ctr_group_fmt(vty,
289 " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
290 ratectr->all_rtp_conn_stats);
291 }
292}
293
294
295static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200296{
297 int i;
298
299 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200300 trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
301 trunk->trunk_nr, trunk->number_endpoints - 1, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200302
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200303 if (!trunk->endpoints) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200304 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
305 return;
306 }
307
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200308 for (i = 0; i < trunk->number_endpoints; ++i) {
309 struct mgcp_endpoint *endp = trunk->endpoints[i];
310 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
311 show_stats);
312 if (i < trunk->number_endpoints - 1)
Stefan Sperling12086582018-06-26 15:26:28 +0200313 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200314 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200315
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200316 if (show_stats)
317 dump_ratectr_trunk(vty, &trunk->ratectr);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200318}
319
Stefan Sperling12086582018-06-26 15:26:28 +0200320#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
321
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200322DEFUN(show_mcgp, show_mgcp_cmd,
323 "show mgcp [stats]",
324 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200325 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200326 "Include Statistics\n")
327{
Philipp Maier14b27a82020-06-02 20:15:30 +0200328 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200329 int show_stats = argc >= 1;
330
Harald Weltec39b1bf2020-03-08 11:29:39 +0100331 dump_trunk(vty, g_cfg->virt_trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200332
333 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200334 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200335
336 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200337 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200338 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200339
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200340 if (show_stats)
341 dump_ratectr_global(vty, &g_cfg->ratectr);
342
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200343 return CMD_SUCCESS;
344}
345
Stefan Sperling12086582018-06-26 15:26:28 +0200346static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200347dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200348{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200349 struct mgcp_endpoint *endp;
Stefan Sperling12086582018-06-26 15:26:28 +0200350
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200351 if (trunk) {
352 /* If a trunk is given, search on that specific trunk only */
353 endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
354 if (!endp) {
355 vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
356 return;
357 }
358 } else {
359 /* If no trunk is given, search on all possible trunks */
360 endp = mgcp_endp_by_name(NULL, epname, g_cfg);
361 if (!endp) {
362 vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
363 return;
Stefan Sperling12086582018-06-26 15:26:28 +0200364 }
365 }
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200366
367 trunk = endp->trunk;
368 dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
Stefan Sperling12086582018-06-26 15:26:28 +0200369}
370
371DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
372 "show mgcp endpoint NAME",
373 SHOW_STR
374 SHOW_MGCP_STR
375 "Display information about an endpoint\n" "The name of the endpoint\n")
376{
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200377 dump_mgcp_endpoint(vty, NULL, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200378 return CMD_SUCCESS;
379}
380
381DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
382 "show mgcp trunk <0-64> endpoint NAME",
383 SHOW_STR
384 SHOW_MGCP_STR
385 "Display information about a trunk\n" "Trunk number\n"
386 "Display information about an endpoint\n" "The name of the endpoint\n")
387{
Philipp Maier14b27a82020-06-02 20:15:30 +0200388 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200389 int trunkidx = atoi(argv[0]);
390
391 trunk = find_trunk(g_cfg, trunkidx);
392 if (!trunk) {
393 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
394 return CMD_WARNING;
395 }
396
397 dump_mgcp_endpoint(vty, trunk, argv[1]);
398 return CMD_SUCCESS;
399}
400
Philipp Maier87bd9be2017-08-22 16:35:41 +0200401DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200402{
403 vty->node = MGCP_NODE;
404 return CMD_SUCCESS;
405}
406
407DEFUN(cfg_mgcp_local_ip,
408 cfg_mgcp_local_ip_cmd,
409 "local ip A.B.C.D",
410 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200411 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200412{
413 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
414 return CMD_SUCCESS;
415}
416
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200417#define BIND_STR "Listen/Bind related socket option\n"
418DEFUN(cfg_mgcp_bind_ip,
419 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200420 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200421{
422 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
423 return CMD_SUCCESS;
424}
425
426DEFUN(cfg_mgcp_bind_port,
427 cfg_mgcp_bind_port_cmd,
428 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200429 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200430{
431 unsigned int port = atoi(argv[0]);
432 g_cfg->source_port = port;
433 return CMD_SUCCESS;
434}
435
436DEFUN(cfg_mgcp_bind_early,
437 cfg_mgcp_bind_early_cmd,
438 "bind early (0|1)",
439 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200440 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200441{
442 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
443 return CMD_WARNING;
444}
445
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200446#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200447#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200448#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200449#define RANGE_START_STR "Start of the range of ports\n"
450#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200451
Philipp Maierf1889d82017-11-08 14:59:39 +0100452DEFUN(cfg_mgcp_rtp_port_range,
453 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200454 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200455 RTP_STR "Range of ports to use for the NET side\n"
456 RANGE_START_STR RANGE_END_STR)
457{
Philipp Maiera19547b2018-05-22 13:44:34 +0200458 int start;
459 int end;
460
461 start = atoi(argv[0]);
462 end = atoi(argv[1]);
463
464 if (end < start) {
465 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
466 end, start, VTY_NEWLINE);
467 return CMD_WARNING;
468 }
469
470 if (start & 1) {
471 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
472 start, start & 0xFFFE, VTY_NEWLINE);
473 start &= 0xFFFE;
474 }
475
476 if ((end & 1) == 0) {
477 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
478 end, end | 1, VTY_NEWLINE);
479 end |= 1;
480 }
481
482 g_cfg->net_ports.range_start = start;
483 g_cfg->net_ports.range_end = end;
484 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
485
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200486 return CMD_SUCCESS;
487}
Philipp Maierf1889d82017-11-08 14:59:39 +0100488ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
489 cfg_mgcp_rtp_net_range_cmd,
490 "rtp net-range <0-65534> <0-65534>",
491 RTP_STR "Range of ports to use for the NET side\n"
492 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200493
Philipp Maierf1889d82017-11-08 14:59:39 +0100494DEFUN(cfg_mgcp_rtp_bind_ip,
495 cfg_mgcp_rtp_bind_ip_cmd,
496 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200497 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
498{
499 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
500 return CMD_SUCCESS;
501}
Philipp Maierf1889d82017-11-08 14:59:39 +0100502ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
503 cfg_mgcp_rtp_net_bind_ip_cmd,
504 "rtp net-bind-ip A.B.C.D",
505 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200506
Philipp Maierf1889d82017-11-08 14:59:39 +0100507DEFUN(cfg_mgcp_rtp_no_bind_ip,
508 cfg_mgcp_rtp_no_bind_ip_cmd,
509 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200510 NO_STR RTP_STR "Bind endpoints facing the Network\n"
511 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200512{
513 talloc_free(g_cfg->net_ports.bind_addr);
514 g_cfg->net_ports.bind_addr = NULL;
515 return CMD_SUCCESS;
516}
Philipp Maierf1889d82017-11-08 14:59:39 +0100517ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
518 cfg_mgcp_rtp_no_net_bind_ip_cmd,
519 "no rtp net-bind-ip",
520 NO_STR RTP_STR "Bind endpoints facing the Network\n"
521 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200522
Philipp Maier1cb1e382017-11-02 17:16:04 +0100523DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
524 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
525 "rtp ip-probing",
526 RTP_STR "automatic rtp bind ip selection\n")
527{
528 g_cfg->net_ports.bind_addr_probe = true;
529 return CMD_SUCCESS;
530}
531
532DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
533 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
534 "no rtp ip-probing",
535 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
536{
537 g_cfg->net_ports.bind_addr_probe = false;
538 return CMD_SUCCESS;
539}
540
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200541DEFUN(cfg_mgcp_rtp_ip_dscp,
542 cfg_mgcp_rtp_ip_dscp_cmd,
543 "rtp ip-dscp <0-255>",
544 RTP_STR
545 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
546{
547 int dscp = atoi(argv[0]);
548 g_cfg->endp_dscp = dscp;
549 return CMD_SUCCESS;
550}
551
552ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200553 "rtp ip-tos <0-255>",
554 RTP_STR
555 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
556#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200557DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200558 cfg_mgcp_rtp_force_ptime_cmd,
559 "rtp force-ptime (10|20|40)",
560 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200561 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200562{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200563 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200564 return CMD_SUCCESS;
565}
566
567DEFUN(cfg_mgcp_no_rtp_force_ptime,
568 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200569 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200570{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200571 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200572 return CMD_SUCCESS;
573}
574
575DEFUN(cfg_mgcp_sdp_fmtp_extra,
576 cfg_mgcp_sdp_fmtp_extra_cmd,
577 "sdp audio fmtp-extra .NAME",
578 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
579 "Extra Information\n")
580{
581 char *txt = argv_concat(argv, argc, 0);
582 if (!txt)
583 return CMD_WARNING;
584
Harald Weltec39b1bf2020-03-08 11:29:39 +0100585 osmo_talloc_replace_string(g_cfg, &g_cfg->virt_trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200586 talloc_free(txt);
587 return CMD_SUCCESS;
588}
589
590DEFUN(cfg_mgcp_allow_transcoding,
591 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200592 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200593{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100594 g_cfg->virt_trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200595 return CMD_SUCCESS;
596}
597
598DEFUN(cfg_mgcp_no_allow_transcoding,
599 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200600 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200601{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100602 g_cfg->virt_trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200603 return CMD_SUCCESS;
604}
605
606#define SDP_STR "SDP File related options\n"
607#define AUDIO_STR "Audio payload options\n"
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200608DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200609 cfg_mgcp_sdp_payload_number_cmd,
610 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200611 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200612{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200613 return CMD_SUCCESS;
614}
615
Philipp Maier87bd9be2017-08-22 16:35:41 +0200616ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
617 cfg_mgcp_sdp_payload_number_cmd_old,
618 "sdp audio payload number <0-255>",
619 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200620
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200621DEFUN_DEPRECATED(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200622 cfg_mgcp_sdp_payload_name_cmd,
623 "sdp audio-payload name NAME",
624 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
625{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200626 return CMD_SUCCESS;
627}
628
629ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200630 "sdp audio payload name NAME",
631 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200632
Philipp Maier21be42a2020-05-29 21:39:48 +0200633DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200634 cfg_mgcp_sdp_payload_send_ptime_cmd,
635 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200636 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200637{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100638 g_cfg->virt_trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200639 return CMD_SUCCESS;
640}
641
642DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
643 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
644 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200645 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200646{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100647 g_cfg->virt_trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200648 return CMD_SUCCESS;
649}
650
651DEFUN(cfg_mgcp_sdp_payload_send_name,
652 cfg_mgcp_sdp_payload_send_name_cmd,
653 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200654 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200655{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100656 g_cfg->virt_trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200657 return CMD_SUCCESS;
658}
659
660DEFUN(cfg_mgcp_no_sdp_payload_send_name,
661 cfg_mgcp_no_sdp_payload_send_name_cmd,
662 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200663 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200664{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100665 g_cfg->virt_trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200666 return CMD_SUCCESS;
667}
668
669DEFUN(cfg_mgcp_loop,
670 cfg_mgcp_loop_cmd,
671 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200672 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200673{
674 if (g_cfg->osmux) {
675 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
676 return CMD_WARNING;
677 }
Harald Weltec39b1bf2020-03-08 11:29:39 +0100678 g_cfg->virt_trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200679 return CMD_SUCCESS;
680}
681
682DEFUN(cfg_mgcp_force_realloc,
683 cfg_mgcp_force_realloc_cmd,
684 "force-realloc (0|1)",
685 "Force endpoint reallocation when the endpoint is still seized\n"
686 "Don't force reallocation\n" "force reallocation\n")
687{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100688 g_cfg->virt_trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200689 return CMD_SUCCESS;
690}
691
Philipp Maier87bd9be2017-08-22 16:35:41 +0200692DEFUN(cfg_mgcp_rtp_accept_all,
693 cfg_mgcp_rtp_accept_all_cmd,
694 "rtp-accept-all (0|1)",
695 "Accept all RTP packets, even when the originating IP/Port does not match\n"
696 "enable filter\n" "disable filter\n")
697{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100698 g_cfg->virt_trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200699 return CMD_SUCCESS;
700}
701
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200702DEFUN(cfg_mgcp_number_endp,
703 cfg_mgcp_number_endp_cmd,
704 "number endpoints <0-65534>",
705 "Number options\n" "Endpoints available\n" "Number endpoints\n")
706{
707 /* + 1 as we start counting at one */
Harald Weltec39b1bf2020-03-08 11:29:39 +0100708 g_cfg->virt_trunk->vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200709 return CMD_SUCCESS;
710}
711
Philipp Maier87bd9be2017-08-22 16:35:41 +0200712DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200713{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100714 g_cfg->virt_trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200715 return CMD_SUCCESS;
716}
717
718DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200719 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200720{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100721 g_cfg->virt_trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200722 return CMD_SUCCESS;
723}
724
725DEFUN(cfg_mgcp_patch_rtp_ssrc,
726 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200727 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200728{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100729 g_cfg->virt_trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730 return CMD_SUCCESS;
731}
732
733DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
734 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200735 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200736{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100737 g_cfg->virt_trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200738 return CMD_SUCCESS;
739}
740
741DEFUN(cfg_mgcp_patch_rtp_ts,
742 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200743 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200744{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100745 g_cfg->virt_trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200746 return CMD_SUCCESS;
747}
748
749DEFUN(cfg_mgcp_no_patch_rtp_ts,
750 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200751 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200752{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100753 g_cfg->virt_trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200754 return CMD_SUCCESS;
755}
756
Philipp Maier9fc8a022019-02-20 12:26:52 +0100757DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
758 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
759 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
760{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100761 g_cfg->virt_trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100762 return CMD_SUCCESS;
763}
764
765DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
766 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
767 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
768{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100769 g_cfg->virt_trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100770 return CMD_SUCCESS;
771}
772
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200773DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200774 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200775{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100776 g_cfg->virt_trunk->force_constant_ssrc = 0;
777 g_cfg->virt_trunk->force_aligned_timing = 0;
778 g_cfg->virt_trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200779 return CMD_SUCCESS;
780}
781
782DEFUN(cfg_mgcp_rtp_keepalive,
783 cfg_mgcp_rtp_keepalive_cmd,
784 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200785 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200786{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100787 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200788 return CMD_SUCCESS;
789}
790
791DEFUN(cfg_mgcp_rtp_keepalive_once,
792 cfg_mgcp_rtp_keepalive_once_cmd,
793 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200794 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200795{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100796 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200797 return CMD_SUCCESS;
798}
799
800DEFUN(cfg_mgcp_no_rtp_keepalive,
801 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200802 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200803{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100804 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200805 return CMD_SUCCESS;
806}
807
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200808#define CALL_AGENT_STR "Callagent information\n"
809DEFUN(cfg_mgcp_agent_addr,
810 cfg_mgcp_agent_addr_cmd,
811 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200812 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200813{
814 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
815 return CMD_SUCCESS;
816}
817
818ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200819 "call agent ip A.B.C.D",
820 CALL_AGENT_STR CALL_AGENT_STR IP_STR
821 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200822
Philipp Maier21be42a2020-05-29 21:39:48 +0200823DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200824 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200825{
Philipp Maier14b27a82020-06-02 20:15:30 +0200826 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200827 int index = atoi(argv[0]);
828
Philipp Maierc66ab2c2020-06-02 20:55:34 +0200829 trunk = mgcp_trunk_by_num(g_cfg, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100830 if (!trunk) {
831 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200832 if (!trunk) {
833 vty_out(vty, "%%Unable to allocate trunk %u.%s",
834 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100835 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200836 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200837 }
838
839 vty->node = TRUNK_NODE;
840 vty->index = trunk;
841 return CMD_SUCCESS;
842}
843
844static int config_write_trunk(struct vty *vty)
845{
Philipp Maier14b27a82020-06-02 20:15:30 +0200846 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200847
848 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
849 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200850 vty_out(vty, " %ssdp audio-payload send-ptime%s",
851 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
852 vty_out(vty, " %ssdp audio-payload send-name%s",
853 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
854
855 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
856 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
857 else if (trunk->keepalive_interval)
858 vty_out(vty, " rtp keep-alive %d%s",
859 trunk->keepalive_interval, VTY_NEWLINE);
860 else
861 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200862 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200863 vty_out(vty, " force-realloc %d%s",
864 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200865 vty_out(vty, " rtp-accept-all %d%s",
866 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200867 if (trunk->omit_rtcp)
868 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
869 else
870 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100871 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Harald Weltec39b1bf2020-03-08 11:29:39 +0100872 || g_cfg->virt_trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200873 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200874 trunk->force_constant_ssrc ? "" : "no ",
875 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200876 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200877 trunk->force_aligned_timing ? "" : "no ",
878 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100879 vty_out(vty, " %srtp-patch rfc5993hr%s",
880 trunk->rfc5993_hr_convert ? "" : "no ",
881 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200882 } else
883 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
884 if (trunk->audio_fmtp_extra)
885 vty_out(vty, " sdp audio fmtp-extra %s%s",
886 trunk->audio_fmtp_extra, VTY_NEWLINE);
887 vty_out(vty, " %sallow-transcoding%s",
888 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
889 }
890
891 return CMD_SUCCESS;
892}
893
894DEFUN(cfg_trunk_sdp_fmtp_extra,
895 cfg_trunk_sdp_fmtp_extra_cmd,
896 "sdp audio fmtp-extra .NAME",
897 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
898 "Extra Information\n")
899{
Philipp Maier14b27a82020-06-02 20:15:30 +0200900 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200901 char *txt = argv_concat(argv, argc, 0);
902 if (!txt)
903 return CMD_WARNING;
904
905 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
906 talloc_free(txt);
907 return CMD_SUCCESS;
908}
909
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200910DEFUN_DEPRECATED(cfg_trunk_payload_number,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200911 cfg_trunk_payload_number_cmd,
912 "sdp audio-payload number <0-255>",
913 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
914{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200915 return CMD_SUCCESS;
916}
917
918ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200919 "sdp audio payload number <0-255>",
920 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200921
Philipp Maier7f90ddb2020-06-02 21:52:53 +0200922DEFUN_DEPRECATED(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200923 cfg_trunk_payload_name_cmd,
924 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200925 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200926{
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200927 return CMD_SUCCESS;
928}
929
930ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200931 "sdp audio payload name NAME",
932 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200933
Philipp Maier21be42a2020-05-29 21:39:48 +0200934DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200935 cfg_trunk_loop_cmd,
936 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200937 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200938{
Philipp Maier14b27a82020-06-02 20:15:30 +0200939 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200940
941 if (g_cfg->osmux) {
942 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
943 return CMD_WARNING;
944 }
945 trunk->audio_loop = atoi(argv[0]);
946 return CMD_SUCCESS;
947}
948
949DEFUN(cfg_trunk_sdp_payload_send_ptime,
950 cfg_trunk_sdp_payload_send_ptime_cmd,
951 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200952 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200953{
Philipp Maier14b27a82020-06-02 20:15:30 +0200954 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200955 trunk->audio_send_ptime = 1;
956 return CMD_SUCCESS;
957}
958
959DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
960 cfg_trunk_no_sdp_payload_send_ptime_cmd,
961 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200962 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200963{
Philipp Maier14b27a82020-06-02 20:15:30 +0200964 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200965 trunk->audio_send_ptime = 0;
966 return CMD_SUCCESS;
967}
968
969DEFUN(cfg_trunk_sdp_payload_send_name,
970 cfg_trunk_sdp_payload_send_name_cmd,
971 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200972 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200973{
Philipp Maier14b27a82020-06-02 20:15:30 +0200974 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200975 trunk->audio_send_name = 1;
976 return CMD_SUCCESS;
977}
978
979DEFUN(cfg_trunk_no_sdp_payload_send_name,
980 cfg_trunk_no_sdp_payload_send_name_cmd,
981 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200982 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200983{
Philipp Maier14b27a82020-06-02 20:15:30 +0200984 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200985 trunk->audio_send_name = 0;
986 return CMD_SUCCESS;
987}
988
Philipp Maier87bd9be2017-08-22 16:35:41 +0200989DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200990{
Philipp Maier14b27a82020-06-02 20:15:30 +0200991 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200992 trunk->omit_rtcp = 1;
993 return CMD_SUCCESS;
994}
995
996DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200997 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200998{
Philipp Maier14b27a82020-06-02 20:15:30 +0200999 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001000 trunk->omit_rtcp = 0;
1001 return CMD_SUCCESS;
1002}
1003
1004DEFUN(cfg_trunk_patch_rtp_ssrc,
1005 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001006 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001007{
Philipp Maier14b27a82020-06-02 20:15:30 +02001008 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001009 trunk->force_constant_ssrc = 1;
1010 return CMD_SUCCESS;
1011}
1012
1013DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1014 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001015 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001016{
Philipp Maier14b27a82020-06-02 20:15:30 +02001017 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001018 trunk->force_constant_ssrc = 0;
1019 return CMD_SUCCESS;
1020}
1021
1022DEFUN(cfg_trunk_patch_rtp_ts,
1023 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001024 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001025{
Philipp Maier14b27a82020-06-02 20:15:30 +02001026 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001027 trunk->force_aligned_timing = 1;
1028 return CMD_SUCCESS;
1029}
1030
1031DEFUN(cfg_trunk_no_patch_rtp_ts,
1032 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001033 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\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->force_aligned_timing = 0;
1037 return CMD_SUCCESS;
1038}
1039
Philipp Maier9fc8a022019-02-20 12:26:52 +01001040DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1041 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1042 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1043{
Philipp Maier14b27a82020-06-02 20:15:30 +02001044 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001045 trunk->rfc5993_hr_convert = true;
1046 return CMD_SUCCESS;
1047}
1048
1049DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1050 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1051 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1052{
Philipp Maier14b27a82020-06-02 20:15:30 +02001053 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001054 trunk->rfc5993_hr_convert = false;
1055 return CMD_SUCCESS;
1056}
1057
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001058DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001059 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001060{
Philipp Maier14b27a82020-06-02 20:15:30 +02001061 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001062 trunk->force_constant_ssrc = 0;
1063 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001064 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001065 return CMD_SUCCESS;
1066}
1067
1068DEFUN(cfg_trunk_rtp_keepalive,
1069 cfg_trunk_rtp_keepalive_cmd,
1070 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001071 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001072{
Philipp Maier14b27a82020-06-02 20:15:30 +02001073 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001074 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1075 return CMD_SUCCESS;
1076}
1077
1078DEFUN(cfg_trunk_rtp_keepalive_once,
1079 cfg_trunk_rtp_keepalive_once_cmd,
1080 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001081 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001082{
Philipp Maier14b27a82020-06-02 20:15:30 +02001083 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001084 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1085 return CMD_SUCCESS;
1086}
1087
1088DEFUN(cfg_trunk_no_rtp_keepalive,
1089 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001090 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001091{
Philipp Maier14b27a82020-06-02 20:15:30 +02001092 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001093 mgcp_trunk_set_keepalive(trunk, 0);
1094 return CMD_SUCCESS;
1095}
1096
1097DEFUN(cfg_trunk_allow_transcoding,
1098 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001099 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001100{
Philipp Maier14b27a82020-06-02 20:15:30 +02001101 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001102 trunk->no_audio_transcoding = 0;
1103 return CMD_SUCCESS;
1104}
1105
1106DEFUN(cfg_trunk_no_allow_transcoding,
1107 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001108 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001109{
Philipp Maier14b27a82020-06-02 20:15:30 +02001110 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001111 trunk->no_audio_transcoding = 1;
1112 return CMD_SUCCESS;
1113}
1114
Philipp Maier87bd9be2017-08-22 16:35:41 +02001115DEFUN(loop_conn,
1116 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001117 "loop-endpoint <0-64> NAME (0|1)",
1118 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001119 "The name in hex of the endpoint\n" "Disable the loop\n"
1120 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001121{
Philipp Maier14b27a82020-06-02 20:15:30 +02001122 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001123 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001124 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001125
1126 trunk = find_trunk(g_cfg, atoi(argv[0]));
1127 if (!trunk) {
1128 vty_out(vty, "%%Trunk %d not found in the config.%s",
1129 atoi(argv[0]), VTY_NEWLINE);
1130 return CMD_WARNING;
1131 }
1132
1133 if (!trunk->endpoints) {
1134 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1135 trunk->trunk_nr, VTY_NEWLINE);
1136 return CMD_WARNING;
1137 }
1138
1139 int endp_no = strtoul(argv[1], NULL, 16);
1140 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1141 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001142 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001143 return CMD_WARNING;
1144 }
1145
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001146 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001147 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001148 llist_for_each_entry(conn, &endp->conns, entry) {
1149 if (conn->type == MGCP_CONN_TYPE_RTP)
1150 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1151 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1152 else {
1153 /* FIXME: Introduce support for other connection (E1)
1154 * types when implementation is available */
1155 vty_out(vty, "%%Can't enable SSRC patching,"
1156 "connection %s is not an RTP connection.%s",
1157 mgcp_conn_dump(conn), VTY_NEWLINE);
1158 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001159
Philipp Maier87bd9be2017-08-22 16:35:41 +02001160 if (loop)
1161 conn->mode = MGCP_CONN_LOOPBACK;
1162 else
1163 conn->mode = conn->mode_orig;
1164 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001165
1166 return CMD_SUCCESS;
1167}
1168
Philipp Maier87bd9be2017-08-22 16:35:41 +02001169DEFUN(tap_rtp,
1170 tap_rtp_cmd,
1171 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001172 "Forward data on endpoint to a different system\n" "Trunk number\n"
1173 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001174 "The connection id in hex\n"
1175 "Forward incoming data\n"
1176 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001177 "destination IP of the data\n" "destination port\n")
1178{
1179 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001180 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001181 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001182 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001183 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001184
1185 trunk = find_trunk(g_cfg, atoi(argv[0]));
1186 if (!trunk) {
1187 vty_out(vty, "%%Trunk %d not found in the config.%s",
1188 atoi(argv[0]), VTY_NEWLINE);
1189 return CMD_WARNING;
1190 }
1191
1192 if (!trunk->endpoints) {
1193 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1194 trunk->trunk_nr, VTY_NEWLINE);
1195 return CMD_WARNING;
1196 }
1197
1198 int endp_no = strtoul(argv[1], NULL, 16);
1199 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1200 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001201 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001202 return CMD_WARNING;
1203 }
1204
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001205 endp = trunk->endpoints[endp_no];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001206
Philipp Maier01d24a32017-11-21 17:26:09 +01001207 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001208 conn = mgcp_conn_get_rtp(endp, conn_id);
1209 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001210 vty_out(vty, "Conn ID %s is invalid.%s",
1211 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001212 return CMD_WARNING;
1213 }
1214
1215 if (strcmp(argv[3], "in") == 0)
1216 tap = &conn->tap_in;
1217 else if (strcmp(argv[3], "out") == 0)
1218 tap = &conn->tap_out;
1219 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001220 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1221 return CMD_WARNING;
1222 }
1223
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001224 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001225 inet_aton(argv[4], &tap->forward.sin_addr);
1226 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001227 tap->enabled = 1;
1228 return CMD_SUCCESS;
1229}
1230
1231DEFUN(free_endp, free_endp_cmd,
1232 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001233 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001234{
Philipp Maier14b27a82020-06-02 20:15:30 +02001235 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001236 struct mgcp_endpoint *endp;
1237
1238 trunk = find_trunk(g_cfg, atoi(argv[0]));
1239 if (!trunk) {
1240 vty_out(vty, "%%Trunk %d not found in the config.%s",
1241 atoi(argv[0]), VTY_NEWLINE);
1242 return CMD_WARNING;
1243 }
1244
1245 if (!trunk->endpoints) {
1246 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1247 trunk->trunk_nr, VTY_NEWLINE);
1248 return CMD_WARNING;
1249 }
1250
1251 int endp_no = strtoul(argv[1], NULL, 16);
1252 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1253 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001254 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001255 return CMD_WARNING;
1256 }
1257
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001258 endp = trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001259 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001260 return CMD_SUCCESS;
1261}
1262
1263DEFUN(reset_endp, reset_endp_cmd,
1264 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001265 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001266{
Philipp Maier14b27a82020-06-02 20:15:30 +02001267 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001268 struct mgcp_endpoint *endp;
1269 int endp_no, rc;
1270
1271 trunk = find_trunk(g_cfg, atoi(argv[0]));
1272 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 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];
1292 rc = mgcp_send_reset_ep(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001293 if (rc < 0) {
1294 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1295 return CMD_WARNING;
1296 }
1297 return CMD_SUCCESS;
1298}
1299
1300DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001301 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001302{
1303 int rc;
1304
1305 rc = mgcp_send_reset_all(g_cfg);
1306 if (rc < 0) {
1307 vty_out(vty, "Error %d during endpoint reset.%s",
1308 rc, VTY_NEWLINE);
1309 return CMD_WARNING;
1310 }
1311 return CMD_SUCCESS;
1312}
1313
1314#define OSMUX_STR "RTP multiplexing\n"
1315DEFUN(cfg_mgcp_osmux,
1316 cfg_mgcp_osmux_cmd,
1317 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001318 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001319{
1320 if (strcmp(argv[0], "off") == 0) {
1321 g_cfg->osmux = OSMUX_USAGE_OFF;
1322 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001323 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001324 g_cfg->osmux = OSMUX_USAGE_ON;
1325 else if (strcmp(argv[0], "only") == 0)
1326 g_cfg->osmux = OSMUX_USAGE_ONLY;
1327
Harald Weltec39b1bf2020-03-08 11:29:39 +01001328 if (g_cfg->virt_trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001329 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001330 return CMD_WARNING;
1331 }
1332
1333 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001334
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001335}
1336
1337DEFUN(cfg_mgcp_osmux_ip,
1338 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001339 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001340{
1341 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1342 return CMD_SUCCESS;
1343}
1344
1345DEFUN(cfg_mgcp_osmux_batch_factor,
1346 cfg_mgcp_osmux_batch_factor_cmd,
1347 "osmux batch-factor <1-8>",
1348 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1349{
1350 g_cfg->osmux_batch = atoi(argv[0]);
1351 return CMD_SUCCESS;
1352}
1353
1354DEFUN(cfg_mgcp_osmux_batch_size,
1355 cfg_mgcp_osmux_batch_size_cmd,
1356 "osmux batch-size <1-65535>",
1357 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1358{
1359 g_cfg->osmux_batch_size = atoi(argv[0]);
1360 return CMD_SUCCESS;
1361}
1362
1363DEFUN(cfg_mgcp_osmux_port,
1364 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001365 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001366{
1367 g_cfg->osmux_port = atoi(argv[0]);
1368 return CMD_SUCCESS;
1369}
1370
1371DEFUN(cfg_mgcp_osmux_dummy,
1372 cfg_mgcp_osmux_dummy_cmd,
1373 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001374 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1375 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001376{
1377 if (strcmp(argv[0], "on") == 0)
1378 g_cfg->osmux_dummy = 1;
1379 else if (strcmp(argv[0], "off") == 0)
1380 g_cfg->osmux_dummy = 0;
1381
1382 return CMD_SUCCESS;
1383}
1384
Philipp Maier12943ea2018-01-17 15:40:25 +01001385DEFUN(cfg_mgcp_domain,
1386 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001387 "domain NAME",
1388 "Set the domain part expected in MGCP messages' endpoint names\n"
1389 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001390{
1391 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1392 return CMD_SUCCESS;
1393}
1394
Oliver Smithe36b7752019-01-22 16:31:36 +01001395DEFUN(cfg_mgcp_conn_timeout,
1396 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001397 "conn-timeout <0-65534>",
1398 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1399 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001400 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1401 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001402 "Timeout value (sec.)\n")
1403{
1404 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1405 return CMD_SUCCESS;
1406}
1407
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001408int mgcp_vty_init(void)
1409{
1410 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001411 install_element_ve(&show_mgcp_endpoint_cmd);
1412 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001413 install_element(ENABLE_NODE, &loop_conn_cmd);
1414 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001415 install_element(ENABLE_NODE, &free_endp_cmd);
1416 install_element(ENABLE_NODE, &reset_endp_cmd);
1417 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1418
1419 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1420 install_node(&mgcp_node, config_write_mgcp);
1421
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001422 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001423 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1424 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1425 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001426 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001427 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001428 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001429 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001430 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001431 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001432 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1433 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001434 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1435 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1436 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1437 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1438 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1439 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1440 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1441 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1442 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001443 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1444 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1445 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1446 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1447 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1448 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001449 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001450 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1451 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1452 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1453 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1454 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1455 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1456 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1457 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001458 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1459 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001460 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1461 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1462 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1463 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1464 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1465 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1466 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1467 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1468 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1469 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1470 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1471 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1472 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001473 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001474 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001475
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001476 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1477 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001478 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1479 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1480 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1481 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1482 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1483 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1484 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1485 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1486 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1487 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1488 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1489 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1490 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001491 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1492 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001493 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1494 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1495 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1496 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1497 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1498 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1499 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1500 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1501 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1502
1503 return 0;
1504}
1505
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001506int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1507 enum mgcp_role role)
1508{
1509 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001510 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001511
1512 cfg->osmux_port = OSMUX_PORT;
1513 cfg->osmux_batch = 4;
1514 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1515
1516 g_cfg = cfg;
1517 rc = vty_read_config_file(config_file, NULL);
1518 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001519 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1520 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001521 return rc;
1522 }
1523
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001524 if (!g_cfg->source_addr) {
1525 fprintf(stderr, "You need to specify a bind address.\n");
1526 return -1;
1527 }
1528
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001529 if (mgcp_trunk_alloc_endpts(g_cfg->virt_trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001530 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001531 "Failed to initialize the virtual trunk (%d endpoints)\n",
Harald Weltec39b1bf2020-03-08 11:29:39 +01001532 g_cfg->virt_trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001533 return -1;
1534 }
1535
1536 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maierc66ab2c2020-06-02 20:55:34 +02001537 if (mgcp_trunk_alloc_endpts(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001538 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001539 "Failed to initialize trunk %d (%d endpoints)\n",
1540 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001541 return -1;
1542 }
1543 }
1544 cfg->role = role;
1545
1546 return 0;
1547}