blob: 7278c1cc0e8a2ce7289215857dfabbbc1fe00e92 [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>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020032
33#include <string.h>
Philipp Maierbca0ef62018-07-09 17:20:51 +020034#include <inttypes.h>
Stefan Sperling12086582018-06-26 15:26:28 +020035#include <limits.h>
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020036
37#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
38#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
39#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
Philipp Maier9fc8a022019-02-20 12:26:52 +010040#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"
41
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020042
43static struct mgcp_config *g_cfg = NULL;
44
Philipp Maier14b27a82020-06-02 20:15:30 +020045static struct mgcp_trunk *find_trunk(struct mgcp_config *cfg, int nr)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020046{
Philipp Maier14b27a82020-06-02 20:15:30 +020047 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020048
49 if (nr == 0)
Harald Weltec39b1bf2020-03-08 11:29:39 +010050 trunk = cfg->virt_trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020051 else
52 trunk = mgcp_trunk_num(cfg, nr);
53
54 return trunk;
55}
56
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020057struct cmd_node mgcp_node = {
58 MGCP_NODE,
59 "%s(config-mgcp)# ",
60 1,
61};
62
63struct cmd_node trunk_node = {
64 TRUNK_NODE,
65 "%s(config-mgcp-trunk)# ",
66 1,
67};
68
69static int config_write_mgcp(struct vty *vty)
70{
Philipp Maier14b27a82020-06-02 20:15:30 +020071 struct mgcp_trunk *trunk = g_cfg->virt_trunk;
Harald Weltec39b1bf2020-03-08 11:29:39 +010072
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020073 vty_out(vty, "mgcp%s", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020074 vty_out(vty, " domain %s%s", g_cfg->domain, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020075 if (g_cfg->local_ip)
76 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +020077 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
78 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
79 vty_out(vty, " rtp port-range %u %u%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020080 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
81 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020082 if (g_cfg->net_ports.bind_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +020083 vty_out(vty, " rtp bind-ip %s%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +020084 g_cfg->net_ports.bind_addr, VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010085 if (g_cfg->net_ports.bind_addr_probe)
Philipp Maierf53796c2020-06-02 20:38:28 +020086 vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
Philipp Maier1cb1e382017-11-02 17:16:04 +010087 else
Philipp Maierf53796c2020-06-02 20:38:28 +020088 vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
89 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010090 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
Philipp Maierf53796c2020-06-02 20:38:28 +020091 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +010092 else if (trunk->keepalive_interval)
Philipp Maierf53796c2020-06-02 20:38:28 +020093 vty_out(vty, " rtp keep-alive %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +010094 trunk->keepalive_interval, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020095 else
Philipp Maierf53796c2020-06-02 20:38:28 +020096 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +020097
Harald Weltec39b1bf2020-03-08 11:29:39 +010098 if (trunk->omit_rtcp)
Philipp Maierf53796c2020-06-02 20:38:28 +020099 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200100 else
Philipp Maierf53796c2020-06-02 20:38:28 +0200101 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100102 if (trunk->force_constant_ssrc
103 || trunk->force_aligned_timing
104 || trunk->rfc5993_hr_convert) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200105 vty_out(vty, " %srtp-patch ssrc%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100106 trunk->force_constant_ssrc ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200107 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200108 vty_out(vty, " %srtp-patch timestamp%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100109 trunk->force_aligned_timing ? "" : "no ",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200110 VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200111 vty_out(vty, " %srtp-patch rfc5993hr%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100112 trunk->rfc5993_hr_convert ? "" : "no ",
Philipp Maier9fc8a022019-02-20 12:26:52 +0100113 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200114 } else
Philipp Maierf53796c2020-06-02 20:38:28 +0200115 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100116 if (trunk->audio_payload != -1)
Philipp Maierf53796c2020-06-02 20:38:28 +0200117 vty_out(vty, " sdp audio-payload number %d%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100118 trunk->audio_payload, VTY_NEWLINE);
119 if (trunk->audio_name)
Philipp Maierf53796c2020-06-02 20:38:28 +0200120 vty_out(vty, " sdp audio-payload name %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100121 trunk->audio_name, VTY_NEWLINE);
122 if (trunk->audio_fmtp_extra)
Philipp Maierf53796c2020-06-02 20:38:28 +0200123 vty_out(vty, " sdp audio fmtp-extra %s%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100124 trunk->audio_fmtp_extra, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200125 vty_out(vty, " %ssdp audio-payload send-ptime%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100126 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200127 vty_out(vty, " %ssdp audio-payload send-name%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100128 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200129 vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
130 vty_out(vty, " number endpoints %u%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100131 trunk->vty_number_endpoints - 1, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200132 vty_out(vty, " %sallow-transcoding%s",
Harald Weltec39b1bf2020-03-08 11:29:39 +0100133 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200134 if (g_cfg->call_agent_addr)
Philipp Maierf53796c2020-06-02 20:38:28 +0200135 vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200136 VTY_NEWLINE);
137 if (g_cfg->force_ptime > 0)
Philipp Maierf53796c2020-06-02 20:38:28 +0200138 vty_out(vty, " rtp force-ptime %d%s", g_cfg->force_ptime,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200139 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200140
141 switch (g_cfg->osmux) {
142 case OSMUX_USAGE_ON:
Philipp Maierf53796c2020-06-02 20:38:28 +0200143 vty_out(vty, " osmux on%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200144 break;
145 case OSMUX_USAGE_ONLY:
Philipp Maierf53796c2020-06-02 20:38:28 +0200146 vty_out(vty, " osmux only%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200147 break;
148 case OSMUX_USAGE_OFF:
149 default:
Philipp Maierf53796c2020-06-02 20:38:28 +0200150 vty_out(vty, " osmux off%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200151 break;
152 }
153 if (g_cfg->osmux) {
Philipp Maierf53796c2020-06-02 20:38:28 +0200154 vty_out(vty, " osmux bind-ip %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200155 g_cfg->osmux_addr, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200156 vty_out(vty, " osmux batch-factor %d%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200157 g_cfg->osmux_batch, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200158 vty_out(vty, " osmux batch-size %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200159 g_cfg->osmux_batch_size, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200160 vty_out(vty, " osmux port %u%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200161 g_cfg->osmux_port, VTY_NEWLINE);
Philipp Maierf53796c2020-06-02 20:38:28 +0200162 vty_out(vty, " osmux dummy %s%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200163 g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
164 }
Oliver Smithe36b7752019-01-22 16:31:36 +0100165
166 if (g_cfg->conn_timeout)
Philipp Maierf53796c2020-06-02 20:38:28 +0200167 vty_out(vty, " conn-timeout %u%s", g_cfg->conn_timeout, VTY_NEWLINE);
Oliver Smithe36b7752019-01-22 16:31:36 +0100168
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200169 return CMD_SUCCESS;
170}
171
Philipp Maiercede2a42018-07-03 14:14:21 +0200172static void dump_rtp_end(struct vty *vty, struct mgcp_conn_rtp *conn)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200173{
Philipp Maiercede2a42018-07-03 14:14:21 +0200174 struct mgcp_rtp_state *state = &conn->state;
175 struct mgcp_rtp_end *end = &conn->end;
Philipp Maierbc0346e2018-06-07 09:52:16 +0200176 struct mgcp_rtp_codec *codec = end->codec;
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100177 struct rate_ctr *tx_packets, *tx_bytes;
178 struct rate_ctr *rx_packets, *rx_bytes;
Philipp Maiercede2a42018-07-03 14:14:21 +0200179 struct rate_ctr *dropped_packets;
180
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100181 tx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR];
182 tx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR];
183 rx_packets = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR];
184 rx_bytes = &conn->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR];
Philipp Maiercede2a42018-07-03 14:14:21 +0200185 dropped_packets = &conn->rate_ctr_group->ctr[RTP_DROPPED_PACKETS_CTR];
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200186
187 vty_out(vty,
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100188 " Packets Sent: %" PRIu64 " (%" PRIu64 " bytes total)%s"
189 " Packets Received: %" PRIu64 " (%" PRIu64 " bytes total)%s"
Philipp Maierbca0ef62018-07-09 17:20:51 +0200190 " Timestamp Errs: %" PRIu64 "->%" PRIu64 "%s"
191 " Dropped Packets: %" PRIu64 "%s"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200192 " Payload Type: %d Rate: %u Channels: %d %s"
193 " Frame Duration: %u Frame Denominator: %u%s"
194 " FPP: %d Packet Duration: %u%s"
195 " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
196 " Output-Enabled: %d Force-PTIME: %d%s",
Stefan Sperlingb7974e22018-10-29 13:22:00 +0100197 tx_packets->current, tx_bytes->current, VTY_NEWLINE,
198 rx_packets->current, rx_bytes->current, VTY_NEWLINE,
Philipp Maier9e1d1642018-05-09 16:26:34 +0200199 state->in_stream.err_ts_ctr->current,
200 state->out_stream.err_ts_ctr->current,
201 VTY_NEWLINE,
Philipp Maiercede2a42018-07-03 14:14:21 +0200202 dropped_packets->current, VTY_NEWLINE,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200203 codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200204 codec->frame_duration_num, codec->frame_duration_den,
205 VTY_NEWLINE, end->frames_per_packet, end->packet_duration_ms,
206 VTY_NEWLINE, end->fmtp_extra, codec->audio_name,
207 codec->subtype_name, VTY_NEWLINE, end->output_enabled,
208 end->force_output_ptime, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200209}
210
Stefan Sperling12086582018-06-26 15:26:28 +0200211static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp, int epidx,
212 int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200213{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200214 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200215
Stefan Sperling12086582018-06-26 15:26:28 +0200216 vty_out(vty, "%s trunk %d endpoint %s%.2x:%s",
217 trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr,
218 trunk_type == MGCP_TRUNK_VIRTUAL ? MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK : "",
219 epidx, VTY_NEWLINE);
220
221 if (llist_empty(&endp->conns)) {
222 vty_out(vty, " No active connections%s", VTY_NEWLINE);
223 return;
224 }
225
226 llist_for_each_entry(conn, &endp->conns, entry) {
227 vty_out(vty, " CONN: %s%s", mgcp_conn_dump(conn), VTY_NEWLINE);
228
229 if (show_stats) {
Oliver Smithe36b7752019-01-22 16:31:36 +0100230 if (endp->cfg->conn_timeout) {
231 struct timeval remaining;
232 osmo_timer_remaining(&conn->watchdog, NULL, &remaining);
233 vty_out(vty, " Currently remaining timeout (seconds): %d.%06d%s",
234 (int)remaining.tv_sec, (int)remaining.tv_usec, VTY_NEWLINE);
235 }
236
Stefan Sperling12086582018-06-26 15:26:28 +0200237 /* FIXME: Also add verbosity for other
238 * connection types (E1) as soon as
239 * the implementation is available */
240 if (conn->type == MGCP_CONN_TYPE_RTP) {
241 dump_rtp_end(vty, &conn->u.rtp);
242 }
243 }
244 }
245}
246
Philipp Maier14b27a82020-06-02 20:15:30 +0200247static void dump_trunk(struct vty *vty, struct mgcp_trunk *cfg, int show_stats)
Stefan Sperling12086582018-06-26 15:26:28 +0200248{
249 int i;
250
251 vty_out(vty, "%s trunk %d with %d endpoints:%s",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200252 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
253 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
254
255 if (!cfg->endpoints) {
256 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
257 return;
258 }
259
Neels Hofmeyr6c92f9d2020-03-05 23:09:13 +0100260 for (i = 0; i < cfg->number_endpoints; ++i) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200261 struct mgcp_endpoint *endp = &cfg->endpoints[i];
Stefan Sperling12086582018-06-26 15:26:28 +0200262 dump_endpoint(vty, endp, i, cfg->trunk_nr, cfg->trunk_type, show_stats);
263 if (i < cfg->number_endpoints - 1)
264 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200265 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200266
Alexander Chemerisdab89af2020-05-05 17:15:21 +0300267 if (show_stats) {
268 vty_out(vty, "%s", VTY_NEWLINE);
269 vty_out(vty, "Rate counters:%s", VTY_NEWLINE);
270 }
Alexander Chemeris63866002020-05-05 17:18:40 +0300271 if (show_stats && cfg->mgcp_general_ctr_group) {
272 vty_out(vty, " %s:%s", cfg->mgcp_general_ctr_group->desc->group_description, VTY_NEWLINE);
273 vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_general_ctr_group);
274 }
Stefan Sperling1e174872018-10-25 18:36:10 +0200275 if (show_stats && cfg->mgcp_crcx_ctr_group) {
276 vty_out(vty, " %s:%s", cfg->mgcp_crcx_ctr_group->desc->group_description, VTY_NEWLINE);
277 vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_crcx_ctr_group);
278 }
Stefan Sperling8ab3fbb2018-10-30 14:57:25 +0100279 if (show_stats && cfg->mgcp_dlcx_ctr_group) {
280 vty_out(vty, " %s:%s", cfg->mgcp_dlcx_ctr_group->desc->group_description, VTY_NEWLINE);
281 vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_dlcx_ctr_group);
282 }
Stefan Sperlingaa823bf2018-10-29 14:51:41 +0100283 if (show_stats && cfg->mgcp_mdcx_ctr_group) {
284 vty_out(vty, " %s:%s", cfg->mgcp_mdcx_ctr_group->desc->group_description, VTY_NEWLINE);
285 vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_mdcx_ctr_group);
286 }
Stefan Sperlingba25eab2018-10-30 14:32:31 +0100287 if (show_stats && cfg->all_rtp_conn_stats) {
288 vty_out(vty, " %s:%s", cfg->all_rtp_conn_stats->desc->group_description, VTY_NEWLINE);
289 vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->all_rtp_conn_stats);
290 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200291}
292
Stefan Sperling12086582018-06-26 15:26:28 +0200293#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
294
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200295DEFUN(show_mcgp, show_mgcp_cmd,
296 "show mgcp [stats]",
297 SHOW_STR
Stefan Sperling12086582018-06-26 15:26:28 +0200298 SHOW_MGCP_STR
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200299 "Include Statistics\n")
300{
Philipp Maier14b27a82020-06-02 20:15:30 +0200301 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200302 int show_stats = argc >= 1;
303
Harald Weltec39b1bf2020-03-08 11:29:39 +0100304 dump_trunk(vty, g_cfg->virt_trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200305
306 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
Philipp Maier87bd9be2017-08-22 16:35:41 +0200307 dump_trunk(vty, trunk, show_stats);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200308
309 if (g_cfg->osmux)
Pau Espin Pedrol8de58e72019-04-24 13:33:46 +0200310 vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
Philipp Maier87bd9be2017-08-22 16:35:41 +0200311 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200312
313 return CMD_SUCCESS;
314}
315
Stefan Sperling12086582018-06-26 15:26:28 +0200316static void
Philipp Maier14b27a82020-06-02 20:15:30 +0200317dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
Stefan Sperling12086582018-06-26 15:26:28 +0200318{
319 const size_t virt_prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK) - 1;
320 unsigned long epidx;
321 char *endp;
322 int i;
323
324 if (strncmp(epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, virt_prefix_len) == 0)
325 epname += virt_prefix_len;
326 errno = 0;
327 epidx = strtoul(epname, &endp, 16);
328 if (epname[0] == '\0' || *endp != '\0') {
329 vty_out(vty, "endpoint name '%s' is not a hex number%s", epname, VTY_NEWLINE);
330 return;
331 }
332 if ((errno == ERANGE && epidx == ULONG_MAX) /* parsed value out of range */
333 || epidx >= trunk->number_endpoints) {
334 vty_out(vty, "endpoint %.2lx not configured on trunk %d%s", epidx, trunk->trunk_nr, VTY_NEWLINE);
335 return;
336 }
337
338 for (i = 0; i < trunk->number_endpoints; ++i) {
339 struct mgcp_endpoint *endp = &trunk->endpoints[i];
340 if (i == epidx) {
341 dump_endpoint(vty, endp, i, trunk->trunk_nr, trunk->trunk_type, true);
342 break;
343 }
344 }
345}
346
347DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
348 "show mgcp endpoint NAME",
349 SHOW_STR
350 SHOW_MGCP_STR
351 "Display information about an endpoint\n" "The name of the endpoint\n")
352{
Philipp Maier14b27a82020-06-02 20:15:30 +0200353 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200354
Harald Weltec39b1bf2020-03-08 11:29:39 +0100355 dump_mgcp_endpoint(vty, g_cfg->virt_trunk, argv[0]);
Stefan Sperling12086582018-06-26 15:26:28 +0200356 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
357 dump_mgcp_endpoint(vty, trunk, argv[0]);
358
359 return CMD_SUCCESS;
360}
361
362DEFUN(show_mcgp_trunk_endpoint, show_mgcp_trunk_endpoint_cmd,
363 "show mgcp trunk <0-64> endpoint NAME",
364 SHOW_STR
365 SHOW_MGCP_STR
366 "Display information about a trunk\n" "Trunk number\n"
367 "Display information about an endpoint\n" "The name of the endpoint\n")
368{
Philipp Maier14b27a82020-06-02 20:15:30 +0200369 struct mgcp_trunk *trunk;
Stefan Sperling12086582018-06-26 15:26:28 +0200370 int trunkidx = atoi(argv[0]);
371
372 trunk = find_trunk(g_cfg, trunkidx);
373 if (!trunk) {
374 vty_out(vty, "trunk %d not found%s", trunkidx, VTY_NEWLINE);
375 return CMD_WARNING;
376 }
377
378 dump_mgcp_endpoint(vty, trunk, argv[1]);
379 return CMD_SUCCESS;
380}
381
Philipp Maier87bd9be2017-08-22 16:35:41 +0200382DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200383{
384 vty->node = MGCP_NODE;
385 return CMD_SUCCESS;
386}
387
388DEFUN(cfg_mgcp_local_ip,
389 cfg_mgcp_local_ip_cmd,
390 "local ip A.B.C.D",
391 "Local options for the SDP record\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200392 IP_STR "IPv4 Address to use in SDP record\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200393{
394 osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
395 return CMD_SUCCESS;
396}
397
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200398#define BIND_STR "Listen/Bind related socket option\n"
399DEFUN(cfg_mgcp_bind_ip,
400 cfg_mgcp_bind_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200401 "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200402{
403 osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
404 return CMD_SUCCESS;
405}
406
407DEFUN(cfg_mgcp_bind_port,
408 cfg_mgcp_bind_port_cmd,
409 "bind port <0-65534>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200410 BIND_STR "Port information\n" "UDP port to listen for MGCP messages\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200411{
412 unsigned int port = atoi(argv[0]);
413 g_cfg->source_port = port;
414 return CMD_SUCCESS;
415}
416
417DEFUN(cfg_mgcp_bind_early,
418 cfg_mgcp_bind_early_cmd,
419 "bind early (0|1)",
420 BIND_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200421 "Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200422{
423 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
424 return CMD_WARNING;
425}
426
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200427#define RTP_STR "RTP configuration\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200428#define UDP_PORT_STR "UDP Port number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +0200429#define NET_START_STR "First UDP port allocated\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200430#define RANGE_START_STR "Start of the range of ports\n"
431#define RANGE_END_STR "End of the range of ports\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200432
Philipp Maierf1889d82017-11-08 14:59:39 +0100433DEFUN(cfg_mgcp_rtp_port_range,
434 cfg_mgcp_rtp_port_range_cmd,
Philipp Maiera19547b2018-05-22 13:44:34 +0200435 "rtp port-range <1024-65534> <1025-65535>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200436 RTP_STR "Range of ports to use for the NET side\n"
437 RANGE_START_STR RANGE_END_STR)
438{
Philipp Maiera19547b2018-05-22 13:44:34 +0200439 int start;
440 int end;
441
442 start = atoi(argv[0]);
443 end = atoi(argv[1]);
444
445 if (end < start) {
446 vty_out(vty, "range end port (%i) must be greater than the range start port (%i)!%s",
447 end, start, VTY_NEWLINE);
448 return CMD_WARNING;
449 }
450
451 if (start & 1) {
452 vty_out(vty, "range must begin at an even port number, autocorrecting port (%i) to: %i%s",
453 start, start & 0xFFFE, VTY_NEWLINE);
454 start &= 0xFFFE;
455 }
456
457 if ((end & 1) == 0) {
458 vty_out(vty, "range must end at an odd port number, autocorrecting port (%i) to: %i%s",
459 end, end | 1, VTY_NEWLINE);
460 end |= 1;
461 }
462
463 g_cfg->net_ports.range_start = start;
464 g_cfg->net_ports.range_end = end;
465 g_cfg->net_ports.last_port = g_cfg->net_ports.range_start;
466
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200467 return CMD_SUCCESS;
468}
Philipp Maierf1889d82017-11-08 14:59:39 +0100469ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
470 cfg_mgcp_rtp_net_range_cmd,
471 "rtp net-range <0-65534> <0-65534>",
472 RTP_STR "Range of ports to use for the NET side\n"
473 RANGE_START_STR RANGE_END_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200474
Philipp Maierf1889d82017-11-08 14:59:39 +0100475DEFUN(cfg_mgcp_rtp_bind_ip,
476 cfg_mgcp_rtp_bind_ip_cmd,
477 "rtp bind-ip A.B.C.D",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200478 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
479{
480 osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
481 return CMD_SUCCESS;
482}
Philipp Maierf1889d82017-11-08 14:59:39 +0100483ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
484 cfg_mgcp_rtp_net_bind_ip_cmd,
485 "rtp net-bind-ip A.B.C.D",
486 RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200487
Philipp Maierf1889d82017-11-08 14:59:39 +0100488DEFUN(cfg_mgcp_rtp_no_bind_ip,
489 cfg_mgcp_rtp_no_bind_ip_cmd,
490 "no rtp bind-ip",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200491 NO_STR RTP_STR "Bind endpoints facing the Network\n"
492 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200493{
494 talloc_free(g_cfg->net_ports.bind_addr);
495 g_cfg->net_ports.bind_addr = NULL;
496 return CMD_SUCCESS;
497}
Philipp Maierf1889d82017-11-08 14:59:39 +0100498ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
499 cfg_mgcp_rtp_no_net_bind_ip_cmd,
500 "no rtp net-bind-ip",
501 NO_STR RTP_STR "Bind endpoints facing the Network\n"
502 "Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200503
Philipp Maier1cb1e382017-11-02 17:16:04 +0100504DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
505 cfg_mgcp_rtp_net_bind_ip_probing_cmd,
506 "rtp ip-probing",
507 RTP_STR "automatic rtp bind ip selection\n")
508{
509 g_cfg->net_ports.bind_addr_probe = true;
510 return CMD_SUCCESS;
511}
512
513DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
514 cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
515 "no rtp ip-probing",
516 NO_STR RTP_STR "no automatic rtp bind ip selection\n")
517{
518 g_cfg->net_ports.bind_addr_probe = false;
519 return CMD_SUCCESS;
520}
521
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200522DEFUN(cfg_mgcp_rtp_ip_dscp,
523 cfg_mgcp_rtp_ip_dscp_cmd,
524 "rtp ip-dscp <0-255>",
525 RTP_STR
526 "Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
527{
528 int dscp = atoi(argv[0]);
529 g_cfg->endp_dscp = dscp;
530 return CMD_SUCCESS;
531}
532
533ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200534 "rtp ip-tos <0-255>",
535 RTP_STR
536 "Apply IP_TOS to the audio stream\n" "The DSCP value\n")
537#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
Philipp Maier21be42a2020-05-29 21:39:48 +0200538DEFUN(cfg_mgcp_rtp_force_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200539 cfg_mgcp_rtp_force_ptime_cmd,
540 "rtp force-ptime (10|20|40)",
541 RTP_STR FORCE_PTIME_STR
Philipp Maier87bd9be2017-08-22 16:35:41 +0200542 "The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200543{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200544 g_cfg->force_ptime = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200545 return CMD_SUCCESS;
546}
547
548DEFUN(cfg_mgcp_no_rtp_force_ptime,
549 cfg_mgcp_no_rtp_force_ptime_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200550 "no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200551{
Philipp Maier87bd9be2017-08-22 16:35:41 +0200552 g_cfg->force_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200553 return CMD_SUCCESS;
554}
555
556DEFUN(cfg_mgcp_sdp_fmtp_extra,
557 cfg_mgcp_sdp_fmtp_extra_cmd,
558 "sdp audio fmtp-extra .NAME",
559 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
560 "Extra Information\n")
561{
562 char *txt = argv_concat(argv, argc, 0);
563 if (!txt)
564 return CMD_WARNING;
565
Harald Weltec39b1bf2020-03-08 11:29:39 +0100566 osmo_talloc_replace_string(g_cfg, &g_cfg->virt_trunk->audio_fmtp_extra, txt);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200567 talloc_free(txt);
568 return CMD_SUCCESS;
569}
570
571DEFUN(cfg_mgcp_allow_transcoding,
572 cfg_mgcp_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200573 "allow-transcoding", "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200574{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100575 g_cfg->virt_trunk->no_audio_transcoding = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200576 return CMD_SUCCESS;
577}
578
579DEFUN(cfg_mgcp_no_allow_transcoding,
580 cfg_mgcp_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200581 "no allow-transcoding", NO_STR "Allow transcoding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200582{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100583 g_cfg->virt_trunk->no_audio_transcoding = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200584 return CMD_SUCCESS;
585}
586
587#define SDP_STR "SDP File related options\n"
588#define AUDIO_STR "Audio payload options\n"
589DEFUN(cfg_mgcp_sdp_payload_number,
590 cfg_mgcp_sdp_payload_number_cmd,
591 "sdp audio-payload number <0-255>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200592 SDP_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200593{
594 unsigned int payload = atoi(argv[0]);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100595 g_cfg->virt_trunk->audio_payload = payload;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200596 return CMD_SUCCESS;
597}
598
Philipp Maier87bd9be2017-08-22 16:35:41 +0200599ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number,
600 cfg_mgcp_sdp_payload_number_cmd_old,
601 "sdp audio payload number <0-255>",
602 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200603
Philipp Maier21be42a2020-05-29 21:39:48 +0200604DEFUN(cfg_mgcp_sdp_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200605 cfg_mgcp_sdp_payload_name_cmd,
606 "sdp audio-payload name NAME",
607 SDP_STR AUDIO_STR "Name\n" "Payload name\n")
608{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100609 osmo_talloc_replace_string(g_cfg, &g_cfg->virt_trunk->audio_name, argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200610 return CMD_SUCCESS;
611}
612
613ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200614 "sdp audio payload name NAME",
615 SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200616
Philipp Maier21be42a2020-05-29 21:39:48 +0200617DEFUN(cfg_mgcp_sdp_payload_send_ptime,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200618 cfg_mgcp_sdp_payload_send_ptime_cmd,
619 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200620 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200621{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100622 g_cfg->virt_trunk->audio_send_ptime = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200623 return CMD_SUCCESS;
624}
625
626DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
627 cfg_mgcp_no_sdp_payload_send_ptime_cmd,
628 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200629 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200630{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100631 g_cfg->virt_trunk->audio_send_ptime = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200632 return CMD_SUCCESS;
633}
634
635DEFUN(cfg_mgcp_sdp_payload_send_name,
636 cfg_mgcp_sdp_payload_send_name_cmd,
637 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200638 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200639{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100640 g_cfg->virt_trunk->audio_send_name = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200641 return CMD_SUCCESS;
642}
643
644DEFUN(cfg_mgcp_no_sdp_payload_send_name,
645 cfg_mgcp_no_sdp_payload_send_name_cmd,
646 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200647 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200648{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100649 g_cfg->virt_trunk->audio_send_name = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200650 return CMD_SUCCESS;
651}
652
653DEFUN(cfg_mgcp_loop,
654 cfg_mgcp_loop_cmd,
655 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200656 "Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200657{
658 if (g_cfg->osmux) {
659 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
660 return CMD_WARNING;
661 }
Harald Weltec39b1bf2020-03-08 11:29:39 +0100662 g_cfg->virt_trunk->audio_loop = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200663 return CMD_SUCCESS;
664}
665
666DEFUN(cfg_mgcp_force_realloc,
667 cfg_mgcp_force_realloc_cmd,
668 "force-realloc (0|1)",
669 "Force endpoint reallocation when the endpoint is still seized\n"
670 "Don't force reallocation\n" "force reallocation\n")
671{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100672 g_cfg->virt_trunk->force_realloc = atoi(argv[0]);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200673 return CMD_SUCCESS;
674}
675
Philipp Maier87bd9be2017-08-22 16:35:41 +0200676DEFUN(cfg_mgcp_rtp_accept_all,
677 cfg_mgcp_rtp_accept_all_cmd,
678 "rtp-accept-all (0|1)",
679 "Accept all RTP packets, even when the originating IP/Port does not match\n"
680 "enable filter\n" "disable filter\n")
681{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100682 g_cfg->virt_trunk->rtp_accept_all = atoi(argv[0]);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200683 return CMD_SUCCESS;
684}
685
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200686DEFUN(cfg_mgcp_number_endp,
687 cfg_mgcp_number_endp_cmd,
688 "number endpoints <0-65534>",
689 "Number options\n" "Endpoints available\n" "Number endpoints\n")
690{
691 /* + 1 as we start counting at one */
Harald Weltec39b1bf2020-03-08 11:29:39 +0100692 g_cfg->virt_trunk->vty_number_endpoints = atoi(argv[0]) + 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200693 return CMD_SUCCESS;
694}
695
Philipp Maier87bd9be2017-08-22 16:35:41 +0200696DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200697{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100698 g_cfg->virt_trunk->omit_rtcp = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200699 return CMD_SUCCESS;
700}
701
702DEFUN(cfg_mgcp_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200703 cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200704{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100705 g_cfg->virt_trunk->omit_rtcp = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200706 return CMD_SUCCESS;
707}
708
709DEFUN(cfg_mgcp_patch_rtp_ssrc,
710 cfg_mgcp_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200711 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200712{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100713 g_cfg->virt_trunk->force_constant_ssrc = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200714 return CMD_SUCCESS;
715}
716
717DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
718 cfg_mgcp_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200719 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200720{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100721 g_cfg->virt_trunk->force_constant_ssrc = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200722 return CMD_SUCCESS;
723}
724
725DEFUN(cfg_mgcp_patch_rtp_ts,
726 cfg_mgcp_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200727 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200728{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100729 g_cfg->virt_trunk->force_aligned_timing = 1;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200730 return CMD_SUCCESS;
731}
732
733DEFUN(cfg_mgcp_no_patch_rtp_ts,
734 cfg_mgcp_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200735 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200736{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100737 g_cfg->virt_trunk->force_aligned_timing = 0;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200738 return CMD_SUCCESS;
739}
740
Philipp Maier9fc8a022019-02-20 12:26:52 +0100741DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
742 cfg_mgcp_patch_rtp_rfc5993hr_cmd,
743 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
744{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100745 g_cfg->virt_trunk->rfc5993_hr_convert = true;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100746 return CMD_SUCCESS;
747}
748
749DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
750 cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
751 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
752{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100753 g_cfg->virt_trunk->rfc5993_hr_convert = false;
Philipp Maier9fc8a022019-02-20 12:26:52 +0100754 return CMD_SUCCESS;
755}
756
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200757DEFUN(cfg_mgcp_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200758 cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200759{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100760 g_cfg->virt_trunk->force_constant_ssrc = 0;
761 g_cfg->virt_trunk->force_aligned_timing = 0;
762 g_cfg->virt_trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200763 return CMD_SUCCESS;
764}
765
766DEFUN(cfg_mgcp_rtp_keepalive,
767 cfg_mgcp_rtp_keepalive_cmd,
768 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200769 RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200770{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100771 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, atoi(argv[0]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200772 return CMD_SUCCESS;
773}
774
775DEFUN(cfg_mgcp_rtp_keepalive_once,
776 cfg_mgcp_rtp_keepalive_once_cmd,
777 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200778 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200779{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100780 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, MGCP_KEEPALIVE_ONCE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200781 return CMD_SUCCESS;
782}
783
784DEFUN(cfg_mgcp_no_rtp_keepalive,
785 cfg_mgcp_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200786 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200787{
Harald Weltec39b1bf2020-03-08 11:29:39 +0100788 mgcp_trunk_set_keepalive(g_cfg->virt_trunk, MGCP_KEEPALIVE_NEVER);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200789 return CMD_SUCCESS;
790}
791
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200792#define CALL_AGENT_STR "Callagent information\n"
793DEFUN(cfg_mgcp_agent_addr,
794 cfg_mgcp_agent_addr_cmd,
795 "call-agent ip A.B.C.D",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200796 CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200797{
798 osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
799 return CMD_SUCCESS;
800}
801
802ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200803 "call agent ip A.B.C.D",
804 CALL_AGENT_STR CALL_AGENT_STR IP_STR
805 "IPv4 Address of the callagent\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200806
Philipp Maier21be42a2020-05-29 21:39:48 +0200807DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200808 "trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200809{
Philipp Maier14b27a82020-06-02 20:15:30 +0200810 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200811 int index = atoi(argv[0]);
812
813 trunk = mgcp_trunk_num(g_cfg, index);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100814 if (!trunk) {
815 trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
Philipp Maier2d681fd2020-05-29 16:20:25 +0200816 if (!trunk) {
817 vty_out(vty, "%%Unable to allocate trunk %u.%s",
818 index, VTY_NEWLINE);
Harald Weltec39b1bf2020-03-08 11:29:39 +0100819 return CMD_WARNING;
Philipp Maier2d681fd2020-05-29 16:20:25 +0200820 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200821 }
822
823 vty->node = TRUNK_NODE;
824 vty->index = trunk;
825 return CMD_SUCCESS;
826}
827
828static int config_write_trunk(struct vty *vty)
829{
Philipp Maier14b27a82020-06-02 20:15:30 +0200830 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200831
832 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
833 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
834 vty_out(vty, " sdp audio-payload number %d%s",
835 trunk->audio_payload, VTY_NEWLINE);
836 vty_out(vty, " sdp audio-payload name %s%s",
837 trunk->audio_name, VTY_NEWLINE);
838 vty_out(vty, " %ssdp audio-payload send-ptime%s",
839 trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
840 vty_out(vty, " %ssdp audio-payload send-name%s",
841 trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
842
843 if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
844 vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
845 else if (trunk->keepalive_interval)
846 vty_out(vty, " rtp keep-alive %d%s",
847 trunk->keepalive_interval, VTY_NEWLINE);
848 else
849 vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200850 vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200851 vty_out(vty, " force-realloc %d%s",
852 trunk->force_realloc, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +0200853 vty_out(vty, " rtp-accept-all %d%s",
854 trunk->rtp_accept_all, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200855 if (trunk->omit_rtcp)
856 vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
857 else
858 vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100859 if (trunk->force_constant_ssrc || trunk->force_aligned_timing
Harald Weltec39b1bf2020-03-08 11:29:39 +0100860 || g_cfg->virt_trunk->rfc5993_hr_convert) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200861 vty_out(vty, " %srtp-patch ssrc%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200862 trunk->force_constant_ssrc ? "" : "no ",
863 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200864 vty_out(vty, " %srtp-patch timestamp%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200865 trunk->force_aligned_timing ? "" : "no ",
866 VTY_NEWLINE);
Philipp Maier9fc8a022019-02-20 12:26:52 +0100867 vty_out(vty, " %srtp-patch rfc5993hr%s",
868 trunk->rfc5993_hr_convert ? "" : "no ",
869 VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200870 } else
871 vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
872 if (trunk->audio_fmtp_extra)
873 vty_out(vty, " sdp audio fmtp-extra %s%s",
874 trunk->audio_fmtp_extra, VTY_NEWLINE);
875 vty_out(vty, " %sallow-transcoding%s",
876 trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
877 }
878
879 return CMD_SUCCESS;
880}
881
882DEFUN(cfg_trunk_sdp_fmtp_extra,
883 cfg_trunk_sdp_fmtp_extra_cmd,
884 "sdp audio fmtp-extra .NAME",
885 "Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
886 "Extra Information\n")
887{
Philipp Maier14b27a82020-06-02 20:15:30 +0200888 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200889 char *txt = argv_concat(argv, argc, 0);
890 if (!txt)
891 return CMD_WARNING;
892
893 osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
894 talloc_free(txt);
895 return CMD_SUCCESS;
896}
897
898DEFUN(cfg_trunk_payload_number,
899 cfg_trunk_payload_number_cmd,
900 "sdp audio-payload number <0-255>",
901 SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
902{
Philipp Maier14b27a82020-06-02 20:15:30 +0200903 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200904 unsigned int payload = atoi(argv[0]);
905
906 trunk->audio_payload = payload;
907 return CMD_SUCCESS;
908}
909
910ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200911 "sdp audio payload number <0-255>",
912 SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200913
Philipp Maier21be42a2020-05-29 21:39:48 +0200914DEFUN(cfg_trunk_payload_name,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200915 cfg_trunk_payload_name_cmd,
916 "sdp audio-payload name NAME",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200917 SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200918{
Philipp Maier14b27a82020-06-02 20:15:30 +0200919 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200920
921 osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
922 return CMD_SUCCESS;
923}
924
925ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200926 "sdp audio payload name NAME",
927 SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200928
Philipp Maier21be42a2020-05-29 21:39:48 +0200929DEFUN(cfg_trunk_loop,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200930 cfg_trunk_loop_cmd,
931 "loop (0|1)",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200932 "Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200933{
Philipp Maier14b27a82020-06-02 20:15:30 +0200934 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200935
936 if (g_cfg->osmux) {
937 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
938 return CMD_WARNING;
939 }
940 trunk->audio_loop = atoi(argv[0]);
941 return CMD_SUCCESS;
942}
943
944DEFUN(cfg_trunk_sdp_payload_send_ptime,
945 cfg_trunk_sdp_payload_send_ptime_cmd,
946 "sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200947 SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200948{
Philipp Maier14b27a82020-06-02 20:15:30 +0200949 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200950 trunk->audio_send_ptime = 1;
951 return CMD_SUCCESS;
952}
953
954DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
955 cfg_trunk_no_sdp_payload_send_ptime_cmd,
956 "no sdp audio-payload send-ptime",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200957 NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200958{
Philipp Maier14b27a82020-06-02 20:15:30 +0200959 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200960 trunk->audio_send_ptime = 0;
961 return CMD_SUCCESS;
962}
963
964DEFUN(cfg_trunk_sdp_payload_send_name,
965 cfg_trunk_sdp_payload_send_name_cmd,
966 "sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200967 SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200968{
Philipp Maier14b27a82020-06-02 20:15:30 +0200969 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200970 trunk->audio_send_name = 1;
971 return CMD_SUCCESS;
972}
973
974DEFUN(cfg_trunk_no_sdp_payload_send_name,
975 cfg_trunk_no_sdp_payload_send_name_cmd,
976 "no sdp audio-payload send-name",
Philipp Maier87bd9be2017-08-22 16:35:41 +0200977 NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200978{
Philipp Maier14b27a82020-06-02 20:15:30 +0200979 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200980 trunk->audio_send_name = 0;
981 return CMD_SUCCESS;
982}
983
Philipp Maier87bd9be2017-08-22 16:35:41 +0200984DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200985{
Philipp Maier14b27a82020-06-02 20:15:30 +0200986 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200987 trunk->omit_rtcp = 1;
988 return CMD_SUCCESS;
989}
990
991DEFUN(cfg_trunk_no_omit_rtcp,
Philipp Maier87bd9be2017-08-22 16:35:41 +0200992 cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200993{
Philipp Maier14b27a82020-06-02 20:15:30 +0200994 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +0200995 trunk->omit_rtcp = 0;
996 return CMD_SUCCESS;
997}
998
999DEFUN(cfg_trunk_patch_rtp_ssrc,
1000 cfg_trunk_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001001 "rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001002{
Philipp Maier14b27a82020-06-02 20:15:30 +02001003 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001004 trunk->force_constant_ssrc = 1;
1005 return CMD_SUCCESS;
1006}
1007
1008DEFUN(cfg_trunk_no_patch_rtp_ssrc,
1009 cfg_trunk_no_patch_rtp_ssrc_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001010 "no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001011{
Philipp Maier14b27a82020-06-02 20:15:30 +02001012 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001013 trunk->force_constant_ssrc = 0;
1014 return CMD_SUCCESS;
1015}
1016
1017DEFUN(cfg_trunk_patch_rtp_ts,
1018 cfg_trunk_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001019 "rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001020{
Philipp Maier14b27a82020-06-02 20:15:30 +02001021 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001022 trunk->force_aligned_timing = 1;
1023 return CMD_SUCCESS;
1024}
1025
1026DEFUN(cfg_trunk_no_patch_rtp_ts,
1027 cfg_trunk_no_patch_rtp_ts_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001028 "no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001029{
Philipp Maier14b27a82020-06-02 20:15:30 +02001030 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001031 trunk->force_aligned_timing = 0;
1032 return CMD_SUCCESS;
1033}
1034
Philipp Maier9fc8a022019-02-20 12:26:52 +01001035DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
1036 cfg_trunk_patch_rtp_rfc5993hr_cmd,
1037 "rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1038{
Philipp Maier14b27a82020-06-02 20:15:30 +02001039 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001040 trunk->rfc5993_hr_convert = true;
1041 return CMD_SUCCESS;
1042}
1043
1044DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
1045 cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
1046 "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
1047{
Philipp Maier14b27a82020-06-02 20:15:30 +02001048 struct mgcp_trunk *trunk = vty->index;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001049 trunk->rfc5993_hr_convert = false;
1050 return CMD_SUCCESS;
1051}
1052
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001053DEFUN(cfg_trunk_no_patch_rtp,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001054 cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001055{
Philipp Maier14b27a82020-06-02 20:15:30 +02001056 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001057 trunk->force_constant_ssrc = 0;
1058 trunk->force_aligned_timing = 0;
Philipp Maier9fc8a022019-02-20 12:26:52 +01001059 trunk->rfc5993_hr_convert = false;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001060 return CMD_SUCCESS;
1061}
1062
1063DEFUN(cfg_trunk_rtp_keepalive,
1064 cfg_trunk_rtp_keepalive_cmd,
1065 "rtp keep-alive <1-120>",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001066 RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001067{
Philipp Maier14b27a82020-06-02 20:15:30 +02001068 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001069 mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
1070 return CMD_SUCCESS;
1071}
1072
1073DEFUN(cfg_trunk_rtp_keepalive_once,
1074 cfg_trunk_rtp_keepalive_once_cmd,
1075 "rtp keep-alive once",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001076 RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001077{
Philipp Maier14b27a82020-06-02 20:15:30 +02001078 struct mgcp_trunk *trunk = vty->index;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001079 mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
1080 return CMD_SUCCESS;
1081}
1082
1083DEFUN(cfg_trunk_no_rtp_keepalive,
1084 cfg_trunk_no_rtp_keepalive_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001085 "no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_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 mgcp_trunk_set_keepalive(trunk, 0);
1089 return CMD_SUCCESS;
1090}
1091
1092DEFUN(cfg_trunk_allow_transcoding,
1093 cfg_trunk_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001094 "allow-transcoding", "Allow transcoding\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->no_audio_transcoding = 0;
1098 return CMD_SUCCESS;
1099}
1100
1101DEFUN(cfg_trunk_no_allow_transcoding,
1102 cfg_trunk_no_allow_transcoding_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001103 "no allow-transcoding", NO_STR "Allow transcoding\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->no_audio_transcoding = 1;
1107 return CMD_SUCCESS;
1108}
1109
Philipp Maier87bd9be2017-08-22 16:35:41 +02001110DEFUN(loop_conn,
1111 loop_conn_cmd,
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001112 "loop-endpoint <0-64> NAME (0|1)",
1113 "Loop a given endpoint\n" "Trunk number\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001114 "The name in hex of the endpoint\n" "Disable the loop\n"
1115 "Enable the loop\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001116{
Philipp Maier14b27a82020-06-02 20:15:30 +02001117 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001118 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001119 struct mgcp_conn *conn;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001120
1121 trunk = find_trunk(g_cfg, atoi(argv[0]));
1122 if (!trunk) {
1123 vty_out(vty, "%%Trunk %d not found in the config.%s",
1124 atoi(argv[0]), VTY_NEWLINE);
1125 return CMD_WARNING;
1126 }
1127
1128 if (!trunk->endpoints) {
1129 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1130 trunk->trunk_nr, VTY_NEWLINE);
1131 return CMD_WARNING;
1132 }
1133
1134 int endp_no = strtoul(argv[1], NULL, 16);
1135 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1136 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001137 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001138 return CMD_WARNING;
1139 }
1140
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001141 endp = &trunk->endpoints[endp_no];
1142 int loop = atoi(argv[2]);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001143 llist_for_each_entry(conn, &endp->conns, entry) {
1144 if (conn->type == MGCP_CONN_TYPE_RTP)
1145 /* Handle it like a MDCX, switch on SSRC patching if enabled */
1146 mgcp_rtp_end_config(endp, 1, &conn->u.rtp.end);
1147 else {
1148 /* FIXME: Introduce support for other connection (E1)
1149 * types when implementation is available */
1150 vty_out(vty, "%%Can't enable SSRC patching,"
1151 "connection %s is not an RTP connection.%s",
1152 mgcp_conn_dump(conn), VTY_NEWLINE);
1153 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001154
Philipp Maier87bd9be2017-08-22 16:35:41 +02001155 if (loop)
1156 conn->mode = MGCP_CONN_LOOPBACK;
1157 else
1158 conn->mode = conn->mode_orig;
1159 }
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001160
1161 return CMD_SUCCESS;
1162}
1163
Philipp Maier87bd9be2017-08-22 16:35:41 +02001164DEFUN(tap_rtp,
1165 tap_rtp_cmd,
1166 "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001167 "Forward data on endpoint to a different system\n" "Trunk number\n"
1168 "The endpoint in hex\n"
Philipp Maier87bd9be2017-08-22 16:35:41 +02001169 "The connection id in hex\n"
1170 "Forward incoming data\n"
1171 "Forward leaving data\n"
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001172 "destination IP of the data\n" "destination port\n")
1173{
1174 struct mgcp_rtp_tap *tap;
Philipp Maier14b27a82020-06-02 20:15:30 +02001175 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001176 struct mgcp_endpoint *endp;
Philipp Maier87bd9be2017-08-22 16:35:41 +02001177 struct mgcp_conn_rtp *conn;
Philipp Maier01d24a32017-11-21 17:26:09 +01001178 const char *conn_id = NULL;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001179
1180 trunk = find_trunk(g_cfg, atoi(argv[0]));
1181 if (!trunk) {
1182 vty_out(vty, "%%Trunk %d not found in the config.%s",
1183 atoi(argv[0]), VTY_NEWLINE);
1184 return CMD_WARNING;
1185 }
1186
1187 if (!trunk->endpoints) {
1188 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1189 trunk->trunk_nr, VTY_NEWLINE);
1190 return CMD_WARNING;
1191 }
1192
1193 int endp_no = strtoul(argv[1], NULL, 16);
1194 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1195 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001196 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001197 return CMD_WARNING;
1198 }
1199
1200 endp = &trunk->endpoints[endp_no];
1201
Philipp Maier01d24a32017-11-21 17:26:09 +01001202 conn_id = argv[2];
Philipp Maier87bd9be2017-08-22 16:35:41 +02001203 conn = mgcp_conn_get_rtp(endp, conn_id);
1204 if (!conn) {
Philipp Maier01d24a32017-11-21 17:26:09 +01001205 vty_out(vty, "Conn ID %s is invalid.%s",
1206 conn_id, VTY_NEWLINE);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001207 return CMD_WARNING;
1208 }
1209
1210 if (strcmp(argv[3], "in") == 0)
1211 tap = &conn->tap_in;
1212 else if (strcmp(argv[3], "out") == 0)
1213 tap = &conn->tap_out;
1214 else {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001215 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
1216 return CMD_WARNING;
1217 }
1218
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001219 memset(&tap->forward, 0, sizeof(tap->forward));
Philipp Maier87bd9be2017-08-22 16:35:41 +02001220 inet_aton(argv[4], &tap->forward.sin_addr);
1221 tap->forward.sin_port = htons(atoi(argv[5]));
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001222 tap->enabled = 1;
1223 return CMD_SUCCESS;
1224}
1225
1226DEFUN(free_endp, free_endp_cmd,
1227 "free-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001228 "Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001229{
Philipp Maier14b27a82020-06-02 20:15:30 +02001230 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001231 struct mgcp_endpoint *endp;
1232
1233 trunk = find_trunk(g_cfg, atoi(argv[0]));
1234 if (!trunk) {
1235 vty_out(vty, "%%Trunk %d not found in the config.%s",
1236 atoi(argv[0]), VTY_NEWLINE);
1237 return CMD_WARNING;
1238 }
1239
1240 if (!trunk->endpoints) {
1241 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1242 trunk->trunk_nr, VTY_NEWLINE);
1243 return CMD_WARNING;
1244 }
1245
1246 int endp_no = strtoul(argv[1], NULL, 16);
1247 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1248 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001249 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001250 return CMD_WARNING;
1251 }
1252
1253 endp = &trunk->endpoints[endp_no];
Philipp Maier1355d7e2018-02-01 14:30:06 +01001254 mgcp_endp_release(endp);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001255 return CMD_SUCCESS;
1256}
1257
1258DEFUN(reset_endp, reset_endp_cmd,
1259 "reset-endpoint <0-64> NUMBER",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001260 "Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001261{
Philipp Maier14b27a82020-06-02 20:15:30 +02001262 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001263 struct mgcp_endpoint *endp;
1264 int endp_no, rc;
1265
1266 trunk = find_trunk(g_cfg, atoi(argv[0]));
1267 if (!trunk) {
1268 vty_out(vty, "%%Trunk %d not found in the config.%s",
1269 atoi(argv[0]), VTY_NEWLINE);
1270 return CMD_WARNING;
1271 }
1272
1273 if (!trunk->endpoints) {
1274 vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
1275 trunk->trunk_nr, VTY_NEWLINE);
1276 return CMD_WARNING;
1277 }
1278
1279 endp_no = strtoul(argv[1], NULL, 16);
1280 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
1281 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001282 argv[1], endp_no, VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001283 return CMD_WARNING;
1284 }
1285
1286 endp = &trunk->endpoints[endp_no];
1287 rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
1288 if (rc < 0) {
1289 vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
1290 return CMD_WARNING;
1291 }
1292 return CMD_SUCCESS;
1293}
1294
1295DEFUN(reset_all_endp, reset_all_endp_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001296 "reset-all-endpoints", "Reset all endpoints\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001297{
1298 int rc;
1299
1300 rc = mgcp_send_reset_all(g_cfg);
1301 if (rc < 0) {
1302 vty_out(vty, "Error %d during endpoint reset.%s",
1303 rc, VTY_NEWLINE);
1304 return CMD_WARNING;
1305 }
1306 return CMD_SUCCESS;
1307}
1308
1309#define OSMUX_STR "RTP multiplexing\n"
1310DEFUN(cfg_mgcp_osmux,
1311 cfg_mgcp_osmux_cmd,
1312 "osmux (on|off|only)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001313 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001314{
1315 if (strcmp(argv[0], "off") == 0) {
1316 g_cfg->osmux = OSMUX_USAGE_OFF;
1317 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001318 } else if (strcmp(argv[0], "on") == 0)
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001319 g_cfg->osmux = OSMUX_USAGE_ON;
1320 else if (strcmp(argv[0], "only") == 0)
1321 g_cfg->osmux = OSMUX_USAGE_ONLY;
1322
Harald Weltec39b1bf2020-03-08 11:29:39 +01001323 if (g_cfg->virt_trunk->audio_loop) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001324 vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001325 return CMD_WARNING;
1326 }
1327
1328 return CMD_SUCCESS;
Pau Espin Pedrolb542b042019-04-23 13:09:32 +02001329
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001330}
1331
1332DEFUN(cfg_mgcp_osmux_ip,
1333 cfg_mgcp_osmux_ip_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001334 "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001335{
1336 osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
1337 return CMD_SUCCESS;
1338}
1339
1340DEFUN(cfg_mgcp_osmux_batch_factor,
1341 cfg_mgcp_osmux_batch_factor_cmd,
1342 "osmux batch-factor <1-8>",
1343 OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
1344{
1345 g_cfg->osmux_batch = atoi(argv[0]);
1346 return CMD_SUCCESS;
1347}
1348
1349DEFUN(cfg_mgcp_osmux_batch_size,
1350 cfg_mgcp_osmux_batch_size_cmd,
1351 "osmux batch-size <1-65535>",
1352 OSMUX_STR "batch size\n" "Batch size in bytes\n")
1353{
1354 g_cfg->osmux_batch_size = atoi(argv[0]);
1355 return CMD_SUCCESS;
1356}
1357
1358DEFUN(cfg_mgcp_osmux_port,
1359 cfg_mgcp_osmux_port_cmd,
Philipp Maier87bd9be2017-08-22 16:35:41 +02001360 "osmux port <1-65535>", OSMUX_STR "port\n" "UDP port\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001361{
1362 g_cfg->osmux_port = atoi(argv[0]);
1363 return CMD_SUCCESS;
1364}
1365
1366DEFUN(cfg_mgcp_osmux_dummy,
1367 cfg_mgcp_osmux_dummy_cmd,
1368 "osmux dummy (on|off)",
Philipp Maier87bd9be2017-08-22 16:35:41 +02001369 OSMUX_STR "Dummy padding\n" "Enable dummy padding\n"
1370 "Disable dummy padding\n")
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001371{
1372 if (strcmp(argv[0], "on") == 0)
1373 g_cfg->osmux_dummy = 1;
1374 else if (strcmp(argv[0], "off") == 0)
1375 g_cfg->osmux_dummy = 0;
1376
1377 return CMD_SUCCESS;
1378}
1379
Philipp Maier12943ea2018-01-17 15:40:25 +01001380DEFUN(cfg_mgcp_domain,
1381 cfg_mgcp_domain_cmd,
Neels Hofmeyr352eed02018-08-20 23:59:32 +02001382 "domain NAME",
1383 "Set the domain part expected in MGCP messages' endpoint names\n"
1384 "Qualified domain name expected in MGCP endpoint names, or '*' to accept any domain\n")
Philipp Maier12943ea2018-01-17 15:40:25 +01001385{
1386 osmo_strlcpy(g_cfg->domain, argv[0], sizeof(g_cfg->domain));
1387 return CMD_SUCCESS;
1388}
1389
Oliver Smithe36b7752019-01-22 16:31:36 +01001390DEFUN(cfg_mgcp_conn_timeout,
1391 cfg_mgcp_conn_timeout_cmd,
Oliver Smithd2ce4442019-06-26 09:56:44 +02001392 "conn-timeout <0-65534>",
1393 "Set a time after which inactive connections (CIs) are closed. Set to 0 to disable timeout. This can be used to"
1394 " work around interoperability problems causing connections to stay open forever, and slowly exhausting all"
Oliver Smith189f29e2019-06-26 12:08:20 +02001395 " available ports. Enable keep-alive packets in MGW clients when using this option together with LCLS (OsmoBSC,"
1396 " OsmoMSC: 'rtp keep-alive')!\n"
Oliver Smithe36b7752019-01-22 16:31:36 +01001397 "Timeout value (sec.)\n")
1398{
1399 g_cfg->conn_timeout = strtoul(argv[0], NULL, 10);
1400 return CMD_SUCCESS;
1401}
1402
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001403int mgcp_vty_init(void)
1404{
1405 install_element_ve(&show_mgcp_cmd);
Stefan Sperling12086582018-06-26 15:26:28 +02001406 install_element_ve(&show_mgcp_endpoint_cmd);
1407 install_element_ve(&show_mgcp_trunk_endpoint_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001408 install_element(ENABLE_NODE, &loop_conn_cmd);
1409 install_element(ENABLE_NODE, &tap_rtp_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001410 install_element(ENABLE_NODE, &free_endp_cmd);
1411 install_element(ENABLE_NODE, &reset_endp_cmd);
1412 install_element(ENABLE_NODE, &reset_all_endp_cmd);
1413
1414 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
1415 install_node(&mgcp_node, config_write_mgcp);
1416
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001417 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001418 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
1419 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
1420 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001421 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001422 install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001423 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001424 install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001425 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
Philipp Maierf1889d82017-11-08 14:59:39 +01001426 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
Philipp Maier1cb1e382017-11-02 17:16:04 +01001427 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
1428 install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001429 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
1430 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
1431 install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
1432 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
1433 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
1434 install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
1435 install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
1436 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
1437 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001438 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
1439 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
1440 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
1441 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
1442 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
1443 install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
Philipp Maier87bd9be2017-08-22 16:35:41 +02001444 install_element(MGCP_NODE, &cfg_mgcp_rtp_accept_all_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001445 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
1446 install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
1447 install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
1448 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
1449 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
1450 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
1451 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
1452 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001453 install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);
1454 install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001455 install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
1456 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
1457 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
1458 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
1459 install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
1460 install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
1461 install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
1462 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
1463 install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
1464 install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
1465 install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
1466 install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
1467 install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
Philipp Maier12943ea2018-01-17 15:40:25 +01001468 install_element(MGCP_NODE, &cfg_mgcp_domain_cmd);
Oliver Smithe36b7752019-01-22 16:31:36 +01001469 install_element(MGCP_NODE, &cfg_mgcp_conn_timeout_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001470
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001471 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
1472 install_node(&trunk_node, config_write_trunk);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001473 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
1474 install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
1475 install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
1476 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
1477 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
1478 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
1479 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
1480 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
1481 install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
1482 install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
1483 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
1484 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
1485 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
Philipp Maier9fc8a022019-02-20 12:26:52 +01001486 install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);
1487 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001488 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
1489 install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
1490 install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
1491 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
1492 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
1493 install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
1494 install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
1495 install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
1496 install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
1497
1498 return 0;
1499}
1500
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001501int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
1502 enum mgcp_role role)
1503{
1504 int rc;
Philipp Maier14b27a82020-06-02 20:15:30 +02001505 struct mgcp_trunk *trunk;
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001506
1507 cfg->osmux_port = OSMUX_PORT;
1508 cfg->osmux_batch = 4;
1509 cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
1510
1511 g_cfg = cfg;
1512 rc = vty_read_config_file(config_file, NULL);
1513 if (rc < 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001514 fprintf(stderr, "Failed to parse the config file: '%s'\n",
1515 config_file);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001516 return rc;
1517 }
1518
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001519 if (!g_cfg->source_addr) {
1520 fprintf(stderr, "You need to specify a bind address.\n");
1521 return -1;
1522 }
1523
Harald Weltec39b1bf2020-03-08 11:29:39 +01001524 if (mgcp_endpoints_allocate(g_cfg->virt_trunk) != 0) {
Philipp Maier87bd9be2017-08-22 16:35:41 +02001525 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001526 "Failed to initialize the virtual trunk (%d endpoints)\n",
Harald Weltec39b1bf2020-03-08 11:29:39 +01001527 g_cfg->virt_trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001528 return -1;
1529 }
1530
1531 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
Philipp Maier48454982017-11-10 16:46:41 +01001532 if (mgcp_endpoints_allocate(trunk) != 0) {
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001533 LOGP(DLMGCP, LOGL_ERROR,
Philipp Maier48454982017-11-10 16:46:41 +01001534 "Failed to initialize trunk %d (%d endpoints)\n",
1535 trunk->trunk_nr, trunk->number_endpoints);
Neels Hofmeyrf83ec562017-09-07 19:18:40 +02001536 return -1;
1537 }
1538 }
1539 cfg->role = role;
1540
1541 return 0;
1542}