blob: 1f42d11624ce6ae7e3ae4b1c05ab4f797b67b385 [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
57static int config_write_mgcp(struct vty *vty)
58{
59 vty_out(vty, "mgcp%s", VTY_NEWLINE);
60 if (g_cfg->local_ip)
Holger Hans Peter Freyther8d9833e2010-04-16 16:59:48 +020061 vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
62 if (g_cfg->bts_ip && strlen(g_cfg->bts_ip) != 0)
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010063 vty_out(vty, " bts ip %s%s", g_cfg->bts_ip, VTY_NEWLINE);
64 vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
65 vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
Holger Hans Peter Freyther15e73892010-08-05 07:10:56 +080066
67 if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC)
68 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 +080069 else
70 vty_out(vty, " rtp bts-range %u %u%s",
71 g_cfg->bts_ports.range_start, g_cfg->bts_ports.range_end, VTY_NEWLINE);
72
Holger Hans Peter Freyther15e73892010-08-05 07:10:56 +080073 if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC)
74 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 +080075 else
76 vty_out(vty, " rtp net-range %u %u%s",
77 g_cfg->net_ports.range_start, g_cfg->net_ports.range_end, VTY_NEWLINE);
78
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +080079 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +010080 if (g_cfg->trunk.audio_payload != -1)
81 vty_out(vty, " sdp audio payload number %d%s",
82 g_cfg->trunk.audio_payload, VTY_NEWLINE);
83 if (g_cfg->trunk.audio_name)
84 vty_out(vty, " sdp audio payload name %s%s",
85 g_cfg->trunk.audio_name, VTY_NEWLINE);
86 vty_out(vty, " loop %u%s", !!g_cfg->trunk.audio_loop, VTY_NEWLINE);
87 vty_out(vty, " number endpoints %u%s", g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +020088 if (g_cfg->call_agent_addr)
Holger Hans Peter Freyther8d9833e2010-04-16 16:59:48 +020089 vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +080090 if (g_cfg->transcoder_ip)
91 vty_out(vty, " transcoder-mgw %s%s", g_cfg->transcoder_ip, VTY_NEWLINE);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +010092
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +080093 if (g_cfg->transcoder_ports.mode == PORT_ALLOC_STATIC)
94 vty_out(vty, " rtp transcoder-base %u%s", g_cfg->transcoder_ports.base_port, VTY_NEWLINE);
95 else
96 vty_out(vty, " rtp transcoder-range %u %u%s",
97 g_cfg->transcoder_ports.range_start, g_cfg->transcoder_ports.range_end, VTY_NEWLINE);
Holger Hans Peter Freytherb98ba722010-09-19 04:21:39 +080098 vty_out(vty, " transcoder-remote-base %u%s", g_cfg->transcoder_remote_base, VTY_NEWLINE);
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +080099
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100100 return CMD_SUCCESS;
101}
102
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100103static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg)
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100104{
105 int i;
106
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100107 vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
108 cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
109 cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
110
111 for (i = 1; i < cfg->number_endpoints; ++i) {
112 struct mgcp_endpoint *endp = &cfg->endpoints[i];
113 vty_out(vty,
114 " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s "
115 "traffic received bts: %u/%u remote: %u/%u transcoder: %u/%u%s",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100116 i, endp->ci,
Holger Hans Peter Freythera17d7012010-08-05 01:34:51 +0800117 ntohs(endp->net_end.rtp_port), ntohs(endp->net_end.rtcp_port),
118 ntohs(endp->bts_end.rtp_port), ntohs(endp->bts_end.rtcp_port),
119 inet_ntoa(endp->bts_end.addr),
120 endp->bts_end.packets, endp->bts_state.lost_no,
121 endp->net_end.packets, endp->net_state.lost_no,
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100122 endp->trans_net.packets, endp->trans_bts.packets,
Holger Hans Peter Freytherb4b135e2010-04-07 09:37:17 +0200123 VTY_NEWLINE);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100124 }
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100125}
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100126
Holger Hans Peter Freytherd011c912011-02-28 01:12:33 +0100127DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp",
128 SHOW_STR "Display information about the MGCP Media Gateway")
129{
130 dump_trunk(vty, &g_cfg->trunk);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100131 return CMD_SUCCESS;
132}
133
134DEFUN(cfg_mgcp,
135 cfg_mgcp_cmd,
136 "mgcp",
137 "Configure the MGCP")
138{
139 vty->node = MGCP_NODE;
140 return CMD_SUCCESS;
141}
142
143DEFUN(cfg_mgcp_local_ip,
144 cfg_mgcp_local_ip_cmd,
Holger Hans Peter Freyther1384af62010-05-14 02:27:50 +0800145 "local ip A.B.C.D",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100146 "Set the IP to be used in SDP records")
147{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200148 bsc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100149 return CMD_SUCCESS;
150}
151
152DEFUN(cfg_mgcp_bts_ip,
153 cfg_mgcp_bts_ip_cmd,
Holger Hans Peter Freyther1384af62010-05-14 02:27:50 +0800154 "bts ip A.B.C.D",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100155 "Set the IP of the BTS for RTP forwarding")
156{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200157 bsc_replace_string(g_cfg, &g_cfg->bts_ip, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100158 inet_aton(g_cfg->bts_ip, &g_cfg->bts_in);
159 return CMD_SUCCESS;
160}
161
162DEFUN(cfg_mgcp_bind_ip,
163 cfg_mgcp_bind_ip_cmd,
Holger Hans Peter Freyther1384af62010-05-14 02:27:50 +0800164 "bind ip A.B.C.D",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100165 "Bind the MGCP to this local addr")
166{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200167 bsc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100168 return CMD_SUCCESS;
169}
170
171DEFUN(cfg_mgcp_bind_port,
172 cfg_mgcp_bind_port_cmd,
173 "bind port <0-65534>",
174 "Bind the MGCP to this port")
175{
176 unsigned int port = atoi(argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100177 g_cfg->source_port = port;
178 return CMD_SUCCESS;
179}
180
181DEFUN(cfg_mgcp_bind_early,
182 cfg_mgcp_bind_early_cmd,
183 "bind early (0|1)",
184 "Bind all RTP ports early")
185{
Holger Hans Peter Freytherf1a168d2010-08-05 03:22:24 +0800186 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
187 return CMD_WARNING;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100188}
189
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800190static void parse_base(struct mgcp_port_range *range, const char **argv)
191{
192 unsigned int port = atoi(argv[0]);
193 range->mode = PORT_ALLOC_STATIC;
194 range->base_port = port;
195}
196
197static void parse_range(struct mgcp_port_range *range, const char **argv)
198{
199 range->mode = PORT_ALLOC_DYNAMIC;
200 range->range_start = atoi(argv[0]);
201 range->range_end = atoi(argv[1]);
202 range->last_port = g_cfg->bts_ports.range_start;
203}
204
205
Holger Hans Peter Freyther196349d2010-08-05 03:46:07 +0800206DEFUN(cfg_mgcp_rtp_bts_base_port,
207 cfg_mgcp_rtp_bts_base_port_cmd,
208 "rtp bts-base <0-65534>",
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100209 "Base port to use")
210{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800211 parse_base(&g_cfg->bts_ports, argv);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100212 return CMD_SUCCESS;
213}
214
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800215DEFUN(cfg_mgcp_rtp_bts_range,
216 cfg_mgcp_rtp_bts_range_cmd,
217 "rtp bts-range <0-65534> <0-65534>",
218 "Range of ports to allocate for endpoints\n"
219 "Start of the range of ports\n" "End of the range of ports\n")
220{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800221 parse_range(&g_cfg->bts_ports, argv);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800222 return CMD_SUCCESS;
223}
224
225DEFUN(cfg_mgcp_rtp_net_range,
226 cfg_mgcp_rtp_net_range_cmd,
227 "rtp net-range <0-65534> <0-65534>",
228 "Range of ports to allocate for endpoints\n"
229 "Start of the range of ports\n" "End of the range of ports\n")
230{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800231 parse_range(&g_cfg->net_ports, argv);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800232 return CMD_SUCCESS;
233}
234
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800235DEFUN(cfg_mgcp_rtp_net_base_port,
236 cfg_mgcp_rtp_net_base_port_cmd,
237 "rtp net-base <0-65534>",
238 "Base port to use for network port\n" "Port\n")
239{
Holger Hans Peter Freytherc5f92482010-09-17 23:34:36 +0800240 parse_base(&g_cfg->net_ports, argv);
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800241 return CMD_SUCCESS;
242}
243
Holger Hans Peter Freyther196349d2010-08-05 03:46:07 +0800244ALIAS_DEPRECATED(cfg_mgcp_rtp_bts_base_port, cfg_mgcp_rtp_base_port_cmd,
245 "rtp base <0-65534>", "Base port to use")
246
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +0800247DEFUN(cfg_mgcp_rtp_transcoder_range,
248 cfg_mgcp_rtp_transcoder_range_cmd,
249 "rtp transcoder-range <0-65534> <0-65534>",
250 "Range of ports to allocate for the transcoder\n"
251 "Start of the range of ports\n" "End of the range of ports\n")
252{
253 parse_range(&g_cfg->transcoder_ports, argv);
254 return CMD_SUCCESS;
255}
256
257DEFUN(cfg_mgcp_rtp_transcoder_base,
258 cfg_mgcp_rtp_transcoder_base_cmd,
259 "rtp transcoder-base <0-65534>",
260 "Base port for the transcoder range\n" "Port\n")
261{
262 parse_base(&g_cfg->transcoder_ports, argv);
263 return CMD_SUCCESS;
264}
265
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800266DEFUN(cfg_mgcp_rtp_ip_dscp,
267 cfg_mgcp_rtp_ip_dscp_cmd,
268 "rtp ip-dscp <0-255>",
269 "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.")
Holger Hans Peter Freyther75492e62010-05-31 10:22:00 +0800270{
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800271 int dscp = atoi(argv[0]);
272 g_cfg->endp_dscp = dscp;
Holger Hans Peter Freyther75492e62010-05-31 10:22:00 +0800273 return CMD_SUCCESS;
274}
275
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800276ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
277 "rtp ip-tos <0-255>",
278 "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.")
279
280
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100281DEFUN(cfg_mgcp_sdp_payload_number,
282 cfg_mgcp_sdp_payload_number_cmd,
283 "sdp audio payload number <1-255>",
284 "Set the audio codec to use")
285{
286 unsigned int payload = atoi(argv[0]);
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100287 g_cfg->trunk.audio_payload = payload;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100288 return CMD_SUCCESS;
289}
290
291DEFUN(cfg_mgcp_sdp_payload_name,
292 cfg_mgcp_sdp_payload_name_cmd,
293 "sdp audio payload name NAME",
294 "Set the audio name to use")
295{
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100296 bsc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100297 return CMD_SUCCESS;
298}
299
300DEFUN(cfg_mgcp_loop,
301 cfg_mgcp_loop_cmd,
302 "loop (0|1)",
303 "Loop the audio")
304{
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100305 g_cfg->trunk.audio_loop = atoi(argv[0]);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100306 return CMD_SUCCESS;
307}
308
309DEFUN(cfg_mgcp_number_endp,
310 cfg_mgcp_number_endp_cmd,
311 "number endpoints <0-65534>",
312 "The number of endpoints to allocate. This is not dynamic.")
313{
314 /* + 1 as we start counting at one */
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100315 g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100316 return CMD_SUCCESS;
317}
318
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +0200319DEFUN(cfg_mgcp_agent_addr,
320 cfg_mgcp_agent_addr_cmd,
321 "call agent ip IP",
322 "Set the address of the call agent.")
323{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200324 bsc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +0200325 return CMD_SUCCESS;
326}
327
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +0800328DEFUN(cfg_mgcp_transcoder,
329 cfg_mgcp_transcoder_cmd,
330 "transcoder-mgw A.B.C.D",
331 "Use a MGW to detranscoder RTP\n"
332 "The IP address of the MGW")
333{
Holger Hans Peter Freyther3e9a7f82010-10-12 23:21:54 +0200334 bsc_replace_string(g_cfg, &g_cfg->transcoder_ip, argv[0]);
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +0800335 inet_aton(g_cfg->transcoder_ip, &g_cfg->transcoder_in);
336
337 return CMD_SUCCESS;
338}
339
Holger Hans Peter Freyther88b597e2010-11-01 20:06:45 +0100340DEFUN(cfg_mgcp_no_transcoder,
341 cfg_mgcp_no_transcoder_cmd,
342 NO_STR "transcoder-mgw",
343 "Disable the transcoding\n")
344{
345 if (g_cfg->transcoder_ip) {
346 LOGP(DMGCP, LOGL_NOTICE, "Disabling transcoding on future calls.\n");
347 talloc_free(g_cfg->transcoder_ip);
348 g_cfg->transcoder_ip = NULL;
349 }
350
351 return CMD_SUCCESS;
352}
353
Holger Hans Peter Freytherb98ba722010-09-19 04:21:39 +0800354DEFUN(cfg_mgcp_transcoder_remote_base,
355 cfg_mgcp_transcoder_remote_base_cmd,
356 "transcoder-remote-base <0-65534>",
357 "Set the base port for the transcoder\n" "The RTP base port on the transcoder")
358{
359 g_cfg->transcoder_remote_base = atoi(argv[0]);
360 return CMD_SUCCESS;
361}
362
363
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800364DEFUN(loop_endp,
365 loop_endp_cmd,
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100366 "loop-endpoint <0-64> NAME (0|1)",
367 "Loop a given endpoint\n" "Trunk number\n"
Holger Hans Peter Freytherebc824c2010-08-03 23:00:03 +0800368 "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 +0800369{
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100370 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800371 struct mgcp_endpoint *endp;
372
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100373 trunk = find_trunk(g_cfg, atoi(argv[0]));
374 if (!trunk) {
375 vty_out(vty, "%%Trunk %d not found in the config.%s",
376 atoi(argv[0]), VTY_NEWLINE);
377 return CMD_WARNING;
378 }
379
380 int endp_no = strtoul(argv[1], NULL, 16);
381 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800382 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100383 argv[1], endp_no, VTY_NEWLINE);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800384 return CMD_WARNING;
385 }
386
387
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100388 endp = &trunk->endpoints[endp_no];
389 int loop = atoi(argv[2]);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800390
391 if (loop)
392 endp->conn_mode = MGCP_CONN_LOOPBACK;
393 else
394 endp->conn_mode = endp->orig_mode;
Holger Hans Peter Freyther6357a8e2010-08-05 12:07:00 +0000395 endp->allow_patch = 1;
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800396
397 return CMD_SUCCESS;
398}
399
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800400DEFUN(tap_call,
401 tap_call_cmd,
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100402 "tap-call <0-64> ENDPOINT (bts-in|bts-out|net-in|net-out) A.B.C.D <0-65534>",
403 "Forward data on endpoint to a different system\n" "Trunk number\n"
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800404 "The endpoint in hex\n"
405 "Forward the data coming from the bts\n"
406 "Forward the data coming from the bts leaving to the network\n"
407 "Forward the data coming from the net\n"
408 "Forward the data coming from the net leaving to the bts\n"
409 "destination IP of the data\n" "destination port\n")
410{
411 struct mgcp_rtp_tap *tap;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100412 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800413 struct mgcp_endpoint *endp;
414 int port = 0;
415
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100416 trunk = find_trunk(g_cfg, atoi(argv[0]));
417 if (!trunk) {
418 vty_out(vty, "%%Trunk %d not found in the config.%s",
419 atoi(argv[0]), VTY_NEWLINE);
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800420 return CMD_WARNING;
421 }
422
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100423 int endp_no = strtoul(argv[1], NULL, 16);
424 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
425 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
426 argv[1], endp_no, VTY_NEWLINE);
427 return CMD_WARNING;
428 }
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800429
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100430 endp = &trunk->endpoints[endp_no];
431
432 if (strcmp(argv[2], "bts-in") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800433 port = MGCP_TAP_BTS_IN;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100434 } else if (strcmp(argv[2], "bts-out") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800435 port = MGCP_TAP_BTS_OUT;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100436 } else if (strcmp(argv[2], "net-in") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800437 port = MGCP_TAP_NET_IN;
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100438 } else if (strcmp(argv[2], "net-out") == 0) {
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800439 port = MGCP_TAP_NET_OUT;
440 } else {
441 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
442 return CMD_WARNING;
443 }
444
445 tap = &endp->taps[port];
446 memset(&tap->forward, 0, sizeof(tap->forward));
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100447 inet_aton(argv[3], &tap->forward.sin_addr);
448 tap->forward.sin_port = htons(atoi(argv[4]));
Holger Hans Peter Freyther0e01d092010-08-06 02:05:15 +0800449 tap->enabled = 1;
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800450 return CMD_SUCCESS;
451}
452
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800453DEFUN(free_endp, free_endp_cmd,
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100454 "free-endpoint <0-64> NUMBER",
455 "Free the given endpoint\n" "Trunk number\n"
456 "Endpoint number in hex.\n")
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800457{
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100458 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800459 struct mgcp_endpoint *endp;
460
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100461 trunk = find_trunk(g_cfg, atoi(argv[0]));
462 if (!trunk) {
463 vty_out(vty, "%%Trunk %d not found in the config.%s",
464 atoi(argv[0]), VTY_NEWLINE);
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800465 return CMD_WARNING;
466 }
467
Holger Hans Peter Freytherab3bb9d2011-02-28 01:29:02 +0100468 int endp_no = strtoul(argv[1], NULL, 16);
469 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
470 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
471 argv[1], endp_no, VTY_NEWLINE);
472 return CMD_WARNING;
473 }
474
475 endp = &trunk->endpoints[endp_no];
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800476 mgcp_free_endp(endp);
477 return CMD_SUCCESS;
478}
479
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100480int mgcp_vty_init(void)
481{
Holger Hans Peter Freytherb5be7ac2010-05-14 02:45:52 +0800482 install_element_ve(&show_mgcp_cmd);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800483 install_element(ENABLE_NODE, &loop_endp_cmd);
Holger Hans Peter Freyther260d6ed2010-08-06 01:12:21 +0800484 install_element(ENABLE_NODE, &tap_call_cmd);
Holger Hans Peter Freyther5508fe32010-08-08 16:39:57 +0800485 install_element(ENABLE_NODE, &free_endp_cmd);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100486
487 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
488 install_node(&mgcp_node, config_write_mgcp);
Holger Hans Peter Freytherc597a4e2010-08-03 02:57:02 +0800489
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100490 install_default(MGCP_NODE);
Harald Welte62ab20c2010-05-14 18:59:17 +0200491 install_element(MGCP_NODE, &ournode_exit_cmd);
Harald Welte54f74242010-05-14 19:11:04 +0200492 install_element(MGCP_NODE, &ournode_end_cmd);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100493 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
494 install_element(MGCP_NODE, &cfg_mgcp_bts_ip_cmd);
495 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
496 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
497 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
498 install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_cmd);
Holger Hans Peter Freyther196349d2010-08-05 03:46:07 +0800499 install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_base_port_cmd);
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800500 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_base_port_cmd);
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800501 install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_range_cmd);
502 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Holger Hans Peter Freyther54aaa0f2010-09-17 23:35:53 +0800503 install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_range_cmd);
504 install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_base_cmd);
Holger Hans Peter Freytherd0c32292010-07-27 20:34:45 +0800505 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
Holger Hans Peter Freyther75492e62010-05-31 10:22:00 +0800506 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100507 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
508 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
509 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
510 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
Holger Hans Peter Freytherb79994c2010-03-31 11:46:41 +0200511 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
Holger Hans Peter Freythera2a10eb2010-09-17 03:58:52 +0800512 install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd);
Holger Hans Peter Freyther88b597e2010-11-01 20:06:45 +0100513 install_element(MGCP_NODE, &cfg_mgcp_no_transcoder_cmd);
Holger Hans Peter Freytherb98ba722010-09-19 04:21:39 +0800514 install_element(MGCP_NODE, &cfg_mgcp_transcoder_remote_base_cmd);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100515 return 0;
516}
517
518int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
519{
520 int i, rc;
521
522 g_cfg = cfg;
Harald Weltedcccb182010-05-16 20:52:23 +0200523 rc = vty_read_config_file(config_file, NULL);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100524 if (rc < 0) {
525 fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
526 return rc;
527 }
528
529
530 if (!g_cfg->bts_ip)
531 fprintf(stderr, "No BTS ip address specified. This will allow everyone to connect.\n");
532
Holger Hans Peter Freyther95e4d342010-03-30 13:00:10 +0200533 if (!g_cfg->source_addr) {
534 fprintf(stderr, "You need to specify a bind address.\n");
535 return -1;
536 }
537
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100538 if (mgcp_endpoints_allocate(g_cfg) != 0) {
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100539 fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n",
540 g_cfg->trunk.number_endpoints);
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100541 return -1;
542 }
543
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100544 /* early bind */
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100545 for (i = 1; i < g_cfg->trunk.number_endpoints; ++i) {
546 struct mgcp_endpoint *endp = &g_cfg->trunk.endpoints[i];
Holger Hans Peter Freytherf1a168d2010-08-05 03:22:24 +0800547 int rtp_port;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100548
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800549 if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC) {
550 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
551 g_cfg->bts_ports.base_port);
552 if (mgcp_bind_bts_rtp_port(endp, rtp_port) != 0) {
553 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
554 return -1;
555 }
Holger Hans Peter Freytherf138f912010-08-05 08:08:17 +0800556 endp->bts_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100557 }
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800558
Holger Hans Peter Freyther1be9f2f2010-08-05 07:20:09 +0800559 if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC) {
560 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
561 g_cfg->net_ports.base_port);
562 if (mgcp_bind_net_rtp_port(endp, rtp_port) != 0) {
563 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
564 return -1;
565 }
Holger Hans Peter Freytherf138f912010-08-05 08:08:17 +0800566 endp->net_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther314584a2010-08-05 04:10:21 +0800567 }
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800568
569 if (g_cfg->transcoder_ip && g_cfg->transcoder_ports.mode == PORT_ALLOC_STATIC) {
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100570 /* network side */
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800571 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
572 g_cfg->transcoder_ports.base_port);
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100573 if (mgcp_bind_trans_net_rtp_port(endp, rtp_port) != 0) {
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800574 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
575 return -1;
576 }
Holger Hans Peter Freyther21262332010-11-01 20:53:31 +0100577 endp->trans_net.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freytherbd7b3c52010-11-01 21:04:54 +0100578
579 /* bts side */
580 rtp_port = rtp_calculate_port(endp_back_channel(ENDPOINT_NUMBER(endp)),
581 g_cfg->transcoder_ports.base_port);
582 if (mgcp_bind_trans_bts_rtp_port(endp, rtp_port) != 0) {
583 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
584 return -1;
585 }
586 endp->trans_bts.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther218f8562010-09-18 02:30:02 +0800587 }
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100588 }
589
Holger Hans Peter Freyther8b5772e2010-08-05 01:28:22 +0800590 return 0;
Holger Hans Peter Freyther7bdc6372010-02-20 21:21:02 +0100591}
592