blob: 88c097d9cbd99ba9a65f99e8e92af094ddea210b [file] [log] [blame]
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +01001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +01005 * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
6 * (C) 2009-2011 by On-Waves
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +01007 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * 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
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010012 * (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
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * 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/>.
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010021 *
22 */
23
24#include <sys/types.h>
25
Holger Hans Peter Freyther1ebad742010-02-26 20:16:37 +010026#include <osmocore/talloc.h>
27
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010028#include <openbsc/debug.h>
29#include <openbsc/mgcp.h>
30#include <openbsc/mgcp_internal.h>
Harald Welte62ab20c2010-05-14 18:59:17 +020031#include <openbsc/vty.h>
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010032
Harald Welte4b037e42010-05-19 19:45:32 +020033#include <osmocom/vty/command.h>
34#include <osmocom/vty/vty.h>
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010035
Holger Hans Peter Freyther8d9833e2010-04-16 16:59:48 +020036#include <string.h>
37
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010038static struct mgcp_config *g_cfg = NULL;
39
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +010040static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int trunk)
41{
42 if (trunk != 0)
43 return NULL;
44
45 return &cfg->trunk;
46}
47
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010048/*
49 * vty code for mgcp below
50 */
51struct cmd_node mgcp_node = {
52 MGCP_NODE,
53 "%s(mgcp)#",
54 1,
55};
56
Holger Hans Peter Freyther0e939fe2011-02-28 12:11:02 +010057struct cmd_node trunk_node = {
58 TRUNK_NODE,
59 "%s(trunk)#",
60 1,
61};
62
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010063static int config_write_mgcp(struct vty *vty)
64{
65 vty_out(vty, "mgcp%s", VTY_NEWLINE);
66 if (g_cfg->local_ip)
Holger Hans Peter Freyther8d9833e2010-04-16 16:59:48 +020067 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
68 if (g_cfg->bts_ip && strlen(g_cfg->bts_ip) != 0)
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010069 vty_out(vty, " bts ip %s%s", g_cfg->bts_ip, VTY_NEWLINE);
70 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
71 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Holger Hans Peter Freyther15e73892010-08-05 07:10:56 +080072
73 if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC)
74 vty_out(vty, " rtp bts-base %u%s", g_cfg->bts_ports.base_port, VTY_NEWLINE);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +080075 else
76 vty_out(vty, " rtp bts-range %u %u%s",
77 g_cfg->bts_ports.range_start, g_cfg->bts_ports.range_end, VTY_NEWLINE);
78
Holger Hans Peter Freyther15e73892010-08-05 07:10:56 +080079 if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC)
80 vty_out(vty, " rtp net-base %u%s", g_cfg->net_ports.base_port, VTY_NEWLINE);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +080081 else
82 vty_out(vty, " rtp net-range %u %u%s",
83 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end, VTY_NEWLINE);
84
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +080085 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +010086 if (g_cfg->trunk.audio_payload != -1)
87 vty_out(vty, " sdp audio payload number %d%s",
88 g_cfg->trunk.audio_payload, VTY_NEWLINE);
89 if (g_cfg->trunk.audio_name)
90 vty_out(vty, " sdp audio payload name %s%s",
91 g_cfg->trunk.audio_name, VTY_NEWLINE);
92 vty_out(vty, " loop %u%s", !!g_cfg->trunk.audio_loop, VTY_NEWLINE);
93 vty_out(vty, " number endpoints %u%s", g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +020094 if (g_cfg->call_agent_addr)
Holger Hans Peter Freyther8d9833e2010-04-16 16:59:48 +020095 vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +080096 if (g_cfg->transcoder_ip)
97 vty_out(vty, " transcoder-mgw %s%s", g_cfg->transcoder_ip, VTY_NEWLINE);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010098
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +080099 if (g_cfg->transcoder_ports.mode == PORT_ALLOC_STATIC)
100 vty_out(vty, " rtp transcoder-base %u%s", g_cfg->transcoder_ports.base_port, VTY_NEWLINE);
101 else
102 vty_out(vty, " rtp transcoder-range %u %u%s",
103 g_cfg->transcoder_ports.range_start, g_cfg->transcoder_ports.range_end, VTY_NEWLINE);
Holger Hans Peter Freytherb98ba722010-09-19 04:21:39 +0800104 vty_out(vty, " transcoder-remote-base %u%s", g_cfg->transcoder_remote_base, VTY_NEWLINE);
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +0800105
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100106 return CMD_SUCCESS;
107}
108
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100109static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg)
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100110{
111 int i;
112
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100113 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
114 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
115 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
116
Holger Hans Peter Freythercdba0492011-02-28 12:27:47 +0100117 if (!cfg->endpoints) {
118 vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
119 return;
120 }
121
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100122 for (i = 1; i < cfg->number_endpoints; ++i) {
123 struct mgcp_endpoint *endp = &cfg->endpoints[i];
124 vty_out(vty,
125 " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s "
126 "traffic received bts: %u/%u remote: %u/%u transcoder: %u/%u%s",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100127 i, endp->ci,
Holger Hans Peter Freythera17d7012010-08-05 01:34:51 +0800128 ntohs(endp->net_end.rtp_port), ntohs(endp->net_end.rtcp_port),
129 ntohs(endp->bts_end.rtp_port), ntohs(endp->bts_end.rtcp_port),
130 inet_ntoa(endp->bts_end.addr),
131 endp->bts_end.packets, endp->bts_state.lost_no,
132 endp->net_end.packets, endp->net_state.lost_no,
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100133 endp->trans_net.packets, endp->trans_bts.packets,
Holger Hans Peter Freytherb4b135e2010-04-07 09:37:17 +0200134 VTY_NEWLINE);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100135 }
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100136}
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100137
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100138DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp",
139 SHOW_STR "Display information about the MGCP Media Gateway")
140{
Holger Hans Peter Freythercdba0492011-02-28 12:27:47 +0100141 struct mgcp_trunk_config *trunk;
142
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100143 dump_trunk(vty, &g_cfg->trunk);
Holger Hans Peter Freythercdba0492011-02-28 12:27:47 +0100144
145 llist_for_each_entry(trunk, &g_cfg->trunks, entry)
146 dump_trunk(vty, trunk);
147
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100148 return CMD_SUCCESS;
149}
150
151DEFUN(cfg_mgcp,
152 cfg_mgcp_cmd,
153 "mgcp",
154 "Configure the MGCP")
155{
156 vty->node = MGCP_NODE;
157 return CMD_SUCCESS;
158}
159
160DEFUN(cfg_mgcp_local_ip,
161 cfg_mgcp_local_ip_cmd,
Holger Hans Peter Freyther1384af62010-05-14 02:27:50 +0800162 "local ip A.B.C.D",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100163 "Set the IP to be used in SDP records")
164{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200165 bsc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100166 return CMD_SUCCESS;
167}
168
169DEFUN(cfg_mgcp_bts_ip,
170 cfg_mgcp_bts_ip_cmd,
Holger Hans Peter Freyther1384af62010-05-14 02:27:50 +0800171 "bts ip A.B.C.D",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100172 "Set the IP of the BTS for RTP forwarding")
173{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200174 bsc_replace_string(g_cfg, &g_cfg->bts_ip, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100175 inet_aton(g_cfg->bts_ip, &g_cfg->bts_in);
176 return CMD_SUCCESS;
177}
178
179DEFUN(cfg_mgcp_bind_ip,
180 cfg_mgcp_bind_ip_cmd,
Holger Hans Peter Freyther1384af62010-05-14 02:27:50 +0800181 "bind ip A.B.C.D",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100182 "Bind the MGCP to this local addr")
183{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200184 bsc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100185 return CMD_SUCCESS;
186}
187
188DEFUN(cfg_mgcp_bind_port,
189 cfg_mgcp_bind_port_cmd,
190 "bind port <0-65534>",
191 "Bind the MGCP to this port")
192{
193 unsigned int port = atoi(argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100194 g_cfg->source_port = port;
195 return CMD_SUCCESS;
196}
197
198DEFUN(cfg_mgcp_bind_early,
199 cfg_mgcp_bind_early_cmd,
200 "bind early (0|1)",
201 "Bind all RTP ports early")
202{
Holger Hans Peter Freytherf1a168d2010-08-05 03:22:24 +0800203 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
204 return CMD_WARNING;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100205}
206
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800207static void parse_base(struct mgcp_port_range *range, const char **argv)
208{
209 unsigned int port = atoi(argv[0]);
210 range->mode = PORT_ALLOC_STATIC;
211 range->base_port = port;
212}
213
214static void parse_range(struct mgcp_port_range *range, const char **argv)
215{
216 range->mode = PORT_ALLOC_DYNAMIC;
217 range->range_start = atoi(argv[0]);
218 range->range_end = atoi(argv[1]);
219 range->last_port = g_cfg->bts_ports.range_start;
220}
221
222
Holger Hans Peter Freyther196349d2010-08-05 03:46:07 +0800223DEFUN(cfg_mgcp_rtp_bts_base_port,
224 cfg_mgcp_rtp_bts_base_port_cmd,
225 "rtp bts-base <0-65534>",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100226 "Base port to use")
227{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800228 parse_base(&g_cfg->bts_ports, argv);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100229 return CMD_SUCCESS;
230}
231
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800232DEFUN(cfg_mgcp_rtp_bts_range,
233 cfg_mgcp_rtp_bts_range_cmd,
234 "rtp bts-range <0-65534> <0-65534>",
235 "Range of ports to allocate for endpoints\n"
236 "Start of the range of ports\n" "End of the range of ports\n")
237{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800238 parse_range(&g_cfg->bts_ports, argv);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800239 return CMD_SUCCESS;
240}
241
242DEFUN(cfg_mgcp_rtp_net_range,
243 cfg_mgcp_rtp_net_range_cmd,
244 "rtp net-range <0-65534> <0-65534>",
245 "Range of ports to allocate for endpoints\n"
246 "Start of the range of ports\n" "End of the range of ports\n")
247{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800248 parse_range(&g_cfg->net_ports, argv);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800249 return CMD_SUCCESS;
250}
251
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800252DEFUN(cfg_mgcp_rtp_net_base_port,
253 cfg_mgcp_rtp_net_base_port_cmd,
254 "rtp net-base <0-65534>",
255 "Base port to use for network port\n" "Port\n")
256{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800257 parse_base(&g_cfg->net_ports, argv);
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800258 return CMD_SUCCESS;
259}
260
Holger Hans Peter Freyther196349d2010-08-05 03:46:07 +0800261ALIAS_DEPRECATED(cfg_mgcp_rtp_bts_base_port, cfg_mgcp_rtp_base_port_cmd,
262 "rtp base <0-65534>", "Base port to use")
263
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +0800264DEFUN(cfg_mgcp_rtp_transcoder_range,
265 cfg_mgcp_rtp_transcoder_range_cmd,
266 "rtp transcoder-range <0-65534> <0-65534>",
267 "Range of ports to allocate for the transcoder\n"
268 "Start of the range of ports\n" "End of the range of ports\n")
269{
270 parse_range(&g_cfg->transcoder_ports, argv);
271 return CMD_SUCCESS;
272}
273
274DEFUN(cfg_mgcp_rtp_transcoder_base,
275 cfg_mgcp_rtp_transcoder_base_cmd,
276 "rtp transcoder-base <0-65534>",
277 "Base port for the transcoder range\n" "Port\n")
278{
279 parse_base(&g_cfg->transcoder_ports, argv);
280 return CMD_SUCCESS;
281}
282
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800283DEFUN(cfg_mgcp_rtp_ip_dscp,
284 cfg_mgcp_rtp_ip_dscp_cmd,
285 "rtp ip-dscp <0-255>",
286 "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.")
Holger Hans Peter Freyther75492e62010-05-31 10:22:00 +0800287{
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800288 int dscp = atoi(argv[0]);
289 g_cfg->endp_dscp = dscp;
Holger Hans Peter Freyther75492e62010-05-31 10:22:00 +0800290 return CMD_SUCCESS;
291}
292
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800293ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
294 "rtp ip-tos <0-255>",
295 "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.")
296
297
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100298DEFUN(cfg_mgcp_sdp_payload_number,
299 cfg_mgcp_sdp_payload_number_cmd,
300 "sdp audio payload number <1-255>",
301 "Set the audio codec to use")
302{
303 unsigned int payload = atoi(argv[0]);
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100304 g_cfg->trunk.audio_payload = payload;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100305 return CMD_SUCCESS;
306}
307
308DEFUN(cfg_mgcp_sdp_payload_name,
309 cfg_mgcp_sdp_payload_name_cmd,
310 "sdp audio payload name NAME",
311 "Set the audio name to use")
312{
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100313 bsc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100314 return CMD_SUCCESS;
315}
316
317DEFUN(cfg_mgcp_loop,
318 cfg_mgcp_loop_cmd,
319 "loop (0|1)",
320 "Loop the audio")
321{
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100322 g_cfg->trunk.audio_loop = atoi(argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100323 return CMD_SUCCESS;
324}
325
326DEFUN(cfg_mgcp_number_endp,
327 cfg_mgcp_number_endp_cmd,
328 "number endpoints <0-65534>",
329 "The number of endpoints to allocate. This is not dynamic.")
330{
331 /* + 1 as we start counting at one */
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100332 g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100333 return CMD_SUCCESS;
334}
335
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +0200336DEFUN(cfg_mgcp_agent_addr,
337 cfg_mgcp_agent_addr_cmd,
338 "call agent ip IP",
339 "Set the address of the call agent.")
340{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200341 bsc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +0200342 return CMD_SUCCESS;
343}
344
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +0800345DEFUN(cfg_mgcp_transcoder,
346 cfg_mgcp_transcoder_cmd,
347 "transcoder-mgw A.B.C.D",
348 "Use a MGW to detranscoder RTP\n"
349 "The IP address of the MGW")
350{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200351 bsc_replace_string(g_cfg, &g_cfg->transcoder_ip, argv[0]);
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +0800352 inet_aton(g_cfg->transcoder_ip, &g_cfg->transcoder_in);
353
354 return CMD_SUCCESS;
355}
356
Holger Hans Peter Freyther88b597e2010-11-01 20:06:45 +0100357DEFUN(cfg_mgcp_no_transcoder,
358 cfg_mgcp_no_transcoder_cmd,
359 NO_STR "transcoder-mgw",
360 "Disable the transcoding\n")
361{
362 if (g_cfg->transcoder_ip) {
363 LOGP(DMGCP, LOGL_NOTICE, "Disabling transcoding on future calls.\n");
364 talloc_free(g_cfg->transcoder_ip);
365 g_cfg->transcoder_ip = NULL;
366 }
367
368 return CMD_SUCCESS;
369}
370
Holger Hans Peter Freytherb98ba722010-09-19 04:21:39 +0800371DEFUN(cfg_mgcp_transcoder_remote_base,
372 cfg_mgcp_transcoder_remote_base_cmd,
373 "transcoder-remote-base <0-65534>",
374 "Set the base port for the transcoder\n" "The RTP base port on the transcoder")
375{
376 g_cfg->transcoder_remote_base = atoi(argv[0]);
377 return CMD_SUCCESS;
378}
379
Holger Hans Peter Freyther0e939fe2011-02-28 12:11:02 +0100380DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
381 "trunk <1-64>",
382 "Configure a SS7 trunk\n" "Trunk Nr\n")
383{
384 struct mgcp_trunk_config *trunk;
385 int index = atoi(argv[0]);
386
387 trunk = mgcp_trunk_num(g_cfg, index);
388 if (!trunk)
389 trunk = mgcp_trunk_alloc(g_cfg, index);
390
391 if (!trunk) {
392 vty_out(vty, "%%Unable to allocate trunk %u.%s",
393 index, VTY_NEWLINE);
394 return CMD_WARNING;
395 }
396
397 vty->node = TRUNK_NODE;
398 vty->index = trunk;
399 return CMD_SUCCESS;
400}
401
402static int config_write_trunk(struct vty *vty)
403{
404 struct mgcp_trunk_config *trunk;
405
406 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
407 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
408 vty_out(vty, " sdp audio payload number %d%s",
409 trunk->audio_payload, VTY_NEWLINE);
410 vty_out(vty, " sdp audio payload name %s%s",
411 trunk->audio_name, VTY_NEWLINE);
412 vty_out(vty, " loop %d%s",
413 trunk->audio_loop, VTY_NEWLINE);
414 }
415
416 return CMD_SUCCESS;
417}
418
419DEFUN(cfg_trunk_payload_number,
420 cfg_trunk_payload_number_cmd,
421 "sdp audio payload number <1-255>",
422 "SDP related\n" "Audio\n" "Payload\n" "Payload Number\n")
423{
424 struct mgcp_trunk_config *trunk = vty->index;
425 unsigned int payload = atoi(argv[0]);
426
427 trunk->audio_payload = payload;
428 return CMD_SUCCESS;
429}
430
431DEFUN(cfg_trunk_payload_name,
432 cfg_trunk_payload_name_cmd,
433 "sdp audio payload name NAME",
434 "SDP related\n" "Audio\n" "Payload\n" "Payload Name\n")
435{
436 struct mgcp_trunk_config *trunk = vty->index;
437
438 bsc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
439 return CMD_SUCCESS;
440}
441
442DEFUN(cfg_trunk_loop,
443 cfg_trunk_loop_cmd,
444 "loop (0|1)",
445 "Loop the audio")
446{
447 struct mgcp_trunk_config *trunk = vty->index;
448
449 trunk->audio_loop = atoi(argv[0]);
450 return CMD_SUCCESS;
451}
Holger Hans Peter Freytherb98ba722010-09-19 04:21:39 +0800452
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800453DEFUN(loop_endp,
454 loop_endp_cmd,
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100455 "loop-endpoint <0-64> NAME (0|1)",
456 "Loop a given endpoint\n" "Trunk number\n"
Holger Hans Peter Freytherebc824c2010-08-03 23:00:03 +0800457 "The name in hex of the endpoint\n" "Disable the loop\n" "Enable the loop\n")
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800458{
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100459 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800460 struct mgcp_endpoint *endp;
461
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100462 trunk = find_trunk(g_cfg, atoi(argv[0]));
463 if (!trunk) {
464 vty_out(vty, "%%Trunk %d not found in the config.%s",
465 atoi(argv[0]), VTY_NEWLINE);
466 return CMD_WARNING;
467 }
468
469 int endp_no = strtoul(argv[1], NULL, 16);
470 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800471 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100472 argv[1], endp_no, VTY_NEWLINE);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800473 return CMD_WARNING;
474 }
475
476
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100477 endp = &trunk->endpoints[endp_no];
478 int loop = atoi(argv[2]);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800479
480 if (loop)
481 endp->conn_mode = MGCP_CONN_LOOPBACK;
482 else
483 endp->conn_mode = endp->orig_mode;
Holger Hans Peter Freyther6357a8e2010-08-05 12:07:00 +0000484 endp->allow_patch = 1;
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800485
486 return CMD_SUCCESS;
487}
488
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800489DEFUN(tap_call,
490 tap_call_cmd,
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100491 "tap-call <0-64> ENDPOINT (bts-in|bts-out|net-in|net-out) A.B.C.D <0-65534>",
492 "Forward data on endpoint to a different system\n" "Trunk number\n"
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800493 "The endpoint in hex\n"
494 "Forward the data coming from the bts\n"
495 "Forward the data coming from the bts leaving to the network\n"
496 "Forward the data coming from the net\n"
497 "Forward the data coming from the net leaving to the bts\n"
498 "destination IP of the data\n" "destination port\n")
499{
500 struct mgcp_rtp_tap *tap;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100501 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800502 struct mgcp_endpoint *endp;
503 int port = 0;
504
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100505 trunk = find_trunk(g_cfg, atoi(argv[0]));
506 if (!trunk) {
507 vty_out(vty, "%%Trunk %d not found in the config.%s",
508 atoi(argv[0]), VTY_NEWLINE);
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800509 return CMD_WARNING;
510 }
511
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100512 int endp_no = strtoul(argv[1], NULL, 16);
513 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
514 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
515 argv[1], endp_no, VTY_NEWLINE);
516 return CMD_WARNING;
517 }
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800518
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100519 endp = &trunk->endpoints[endp_no];
520
521 if (strcmp(argv[2], "bts-in") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800522 port = MGCP_TAP_BTS_IN;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100523 } else if (strcmp(argv[2], "bts-out") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800524 port = MGCP_TAP_BTS_OUT;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100525 } else if (strcmp(argv[2], "net-in") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800526 port = MGCP_TAP_NET_IN;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100527 } else if (strcmp(argv[2], "net-out") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800528 port = MGCP_TAP_NET_OUT;
529 } else {
530 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
531 return CMD_WARNING;
532 }
533
534 tap = &endp->taps[port];
535 memset(&tap->forward, 0, sizeof(tap->forward));
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100536 inet_aton(argv[3], &tap->forward.sin_addr);
537 tap->forward.sin_port = htons(atoi(argv[4]));
Holger Hans Peter Freyther0e01d092010-08-06 02:05:15 +0800538 tap->enabled = 1;
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800539 return CMD_SUCCESS;
540}
541
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800542DEFUN(free_endp, free_endp_cmd,
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100543 "free-endpoint <0-64> NUMBER",
544 "Free the given endpoint\n" "Trunk number\n"
545 "Endpoint number in hex.\n")
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800546{
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100547 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800548 struct mgcp_endpoint *endp;
549
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100550 trunk = find_trunk(g_cfg, atoi(argv[0]));
551 if (!trunk) {
552 vty_out(vty, "%%Trunk %d not found in the config.%s",
553 atoi(argv[0]), VTY_NEWLINE);
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800554 return CMD_WARNING;
555 }
556
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100557 int endp_no = strtoul(argv[1], NULL, 16);
558 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
559 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
560 argv[1], endp_no, VTY_NEWLINE);
561 return CMD_WARNING;
562 }
563
564 endp = &trunk->endpoints[endp_no];
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800565 mgcp_free_endp(endp);
566 return CMD_SUCCESS;
567}
568
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100569int mgcp_vty_init(void)
570{
Holger Hans Peter Freytherb5be7ac2010-05-14 02:45:52 +0800571 install_element_ve(&show_mgcp_cmd);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800572 install_element(ENABLE_NODE, &loop_endp_cmd);
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800573 install_element(ENABLE_NODE, &tap_call_cmd);
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800574 install_element(ENABLE_NODE, &free_endp_cmd);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100575
576 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
577 install_node(&mgcp_node, config_write_mgcp);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800578
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100579 install_default(MGCP_NODE);
Harald Welte62ab20c2010-05-14 18:59:17 +0200580 install_element(MGCP_NODE, &ournode_exit_cmd);
Harald Welte54f74242010-05-14 19:11:04 +0200581 install_element(MGCP_NODE, &ournode_end_cmd);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100582 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
583 install_element(MGCP_NODE, &cfg_mgcp_bts_ip_cmd);
584 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
585 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
586 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
587 install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_cmd);
Holger Hans Peter Freyther196349d2010-08-05 03:46:07 +0800588 install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_base_port_cmd);
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800589 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_base_port_cmd);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800590 install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_range_cmd);
591 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +0800592 install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_range_cmd);
593 install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_base_cmd);
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800594 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
Holger Hans Peter Freyther75492e62010-05-31 10:22:00 +0800595 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +0200596 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +0800597 install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd);
Holger Hans Peter Freyther88b597e2010-11-01 20:06:45 +0100598 install_element(MGCP_NODE, &cfg_mgcp_no_transcoder_cmd);
Holger Hans Peter Freytherb98ba722010-09-19 04:21:39 +0800599 install_element(MGCP_NODE, &cfg_mgcp_transcoder_remote_base_cmd);
Holger Hans Peter Freyther0e939fe2011-02-28 12:11:02 +0100600 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
601 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
602 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
603 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
604
605 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
606 install_node(&trunk_node, config_write_trunk);
607 install_default(TRUNK_NODE);
608 install_element(TRUNK_NODE, &ournode_exit_cmd);
609 install_element(TRUNK_NODE, &ournode_end_cmd);
610 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
611 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
612 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
613
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100614 return 0;
615}
616
617int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
618{
619 int i, rc;
620
621 g_cfg = cfg;
Harald Weltedcccb182010-05-16 20:52:23 +0200622 rc = vty_read_config_file(config_file, NULL);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100623 if (rc < 0) {
624 fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
625 return rc;
626 }
627
628
629 if (!g_cfg->bts_ip)
630 fprintf(stderr, "No BTS ip address specified. This will allow everyone to connect.\n");
631
Holger Hans Peter Freyther95e4d342010-03-30 13:00:10 +0200632 if (!g_cfg->source_addr) {
633 fprintf(stderr, "You need to specify a bind address.\n");
634 return -1;
635 }
636
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100637 if (mgcp_endpoints_allocate(g_cfg) != 0) {
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100638 fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n",
639 g_cfg->trunk.number_endpoints);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100640 return -1;
641 }
642
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100643 /* early bind */
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100644 for (i = 1; i < g_cfg->trunk.number_endpoints; ++i) {
645 struct mgcp_endpoint *endp = &g_cfg->trunk.endpoints[i];
Holger Hans Peter Freytherf1a168d2010-08-05 03:22:24 +0800646 int rtp_port;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100647
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800648 if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC) {
649 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
650 g_cfg->bts_ports.base_port);
651 if (mgcp_bind_bts_rtp_port(endp, rtp_port) != 0) {
652 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
653 return -1;
654 }
Holger Hans Peter Freytherf138f912010-08-05 08:08:17 +0800655 endp->bts_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100656 }
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800657
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800658 if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC) {
659 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
660 g_cfg->net_ports.base_port);
661 if (mgcp_bind_net_rtp_port(endp, rtp_port) != 0) {
662 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
663 return -1;
664 }
Holger Hans Peter Freytherf138f912010-08-05 08:08:17 +0800665 endp->net_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800666 }
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800667
668 if (g_cfg->transcoder_ip && g_cfg->transcoder_ports.mode == PORT_ALLOC_STATIC) {
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100669 /* network side */
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800670 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
671 g_cfg->transcoder_ports.base_port);
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100672 if (mgcp_bind_trans_net_rtp_port(endp, rtp_port) != 0) {
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800673 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
674 return -1;
675 }
Holger Hans Peter Freyther21262332010-11-01 20:53:31 +0100676 endp->trans_net.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100677
678 /* bts side */
679 rtp_port = rtp_calculate_port(endp_back_channel(ENDPOINT_NUMBER(endp)),
680 g_cfg->transcoder_ports.base_port);
681 if (mgcp_bind_trans_bts_rtp_port(endp, rtp_port) != 0) {
682 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
683 return -1;
684 }
685 endp->trans_bts.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800686 }
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100687 }
688
Holger Hans Peter Freyther8b5772e2010-08-05 01:28:22 +0800689 return 0;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100690}
691