blob: 1f42d11624ce6ae7e3ae4b1c05ab4f797b67b385 [file] [log] [blame]
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +01001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
Holger Hans Peter Freytherab56ce12011-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 Freyther6f38c062010-02-20 21:21:02 +01007 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte0e3e88e2011-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 Freyther6f38c062010-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 Welte0e3e88e2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +010018 *
Harald Welte0e3e88e2011-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 Freyther6f38c062010-02-20 21:21:02 +010021 *
22 */
23
24#include <sys/types.h>
25
Holger Hans Peter Freytherf41fb1f2010-02-26 20:16:37 +010026#include <osmocore/talloc.h>
27
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +010028#include <openbsc/debug.h>
29#include <openbsc/mgcp.h>
30#include <openbsc/mgcp_internal.h>
Harald Welte58ed1cb2010-05-14 18:59:17 +020031#include <openbsc/vty.h>
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +010032
Harald Weltebd9591f2010-05-19 19:45:32 +020033#include <osmocom/vty/command.h>
34#include <osmocom/vty/vty.h>
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +010035
Holger Hans Peter Freythere8d13712010-04-16 16:59:48 +020036#include <string.h>
37
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +010038static struct mgcp_config *g_cfg = NULL;
39
Holger Hans Peter Freyther75cf62d2011-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 Freyther6f38c062010-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 Freythere8d13712010-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 Freyther6f38c062010-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 Freyther2ea91182010-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 Freytherf3307292010-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 Freyther2ea91182010-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 Freytherf3307292010-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 Freyther3140c4f2010-07-27 20:34:45 +080079 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Holger Hans Peter Freytherab56ce12011-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 Freyther19ff6792010-03-31 11:46:41 +020088 if (g_cfg->call_agent_addr)
Holger Hans Peter Freythere8d13712010-04-16 16:59:48 +020089 vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
Holger Hans Peter Freythercab38342010-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 Freyther6f38c062010-02-20 21:21:02 +010092
Holger Hans Peter Freyther39f2f6d2010-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 Freytherd582b202010-09-19 04:21:39 +080098 vty_out(vty, " transcoder-remote-base %u%s", g_cfg->transcoder_remote_base, VTY_NEWLINE);
Holger Hans Peter Freyther39f2f6d2010-09-17 23:35:53 +080099
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100100 return CMD_SUCCESS;
101}
102
Holger Hans Peter Freyther1584bdb2011-02-28 01:12:33 +0100103static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg)
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100104{
105 int i;
106
Holger Hans Peter Freyther1584bdb2011-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 Freyther6f38c062010-02-20 21:21:02 +0100116 i, endp->ci,
Holger Hans Peter Freytherfab76aa2010-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 Freytherc983f832010-11-01 21:04:54 +0100122 endp->trans_net.packets, endp->trans_bts.packets,
Holger Hans Peter Freyther6de5b112010-04-07 09:37:17 +0200123 VTY_NEWLINE);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100124 }
Holger Hans Peter Freyther1584bdb2011-02-28 01:12:33 +0100125}
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100126
Holger Hans Peter Freyther1584bdb2011-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 Freyther6f38c062010-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 Freyther5c9a6452010-05-14 02:27:50 +0800145 "local ip A.B.C.D",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100146 "Set the IP to be used in SDP records")
147{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200148 bsc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
Holger Hans Peter Freyther6f38c062010-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 Freyther5c9a6452010-05-14 02:27:50 +0800154 "bts ip A.B.C.D",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100155 "Set the IP of the BTS for RTP forwarding")
156{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200157 bsc_replace_string(g_cfg, &g_cfg->bts_ip, argv[0]);
Holger Hans Peter Freyther6f38c062010-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 Freyther5c9a6452010-05-14 02:27:50 +0800164 "bind ip A.B.C.D",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100165 "Bind the MGCP to this local addr")
166{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200167 bsc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
Holger Hans Peter Freyther6f38c062010-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 Freyther6f38c062010-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 Freyther7140dae2010-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 Freyther6f38c062010-02-20 21:21:02 +0100188}
189
Holger Hans Peter Freytherd3b7d772010-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 Freytheree4657c2010-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 Freyther6f38c062010-02-20 21:21:02 +0100209 "Base port to use")
210{
Holger Hans Peter Freytherd3b7d772010-09-17 23:34:36 +0800211 parse_base(&g_cfg->bts_ports, argv);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100212 return CMD_SUCCESS;
213}
214
Holger Hans Peter Freytherf3307292010-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 Freytherd3b7d772010-09-17 23:34:36 +0800221 parse_range(&g_cfg->bts_ports, argv);
Holger Hans Peter Freytherf3307292010-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 Freytherd3b7d772010-09-17 23:34:36 +0800231 parse_range(&g_cfg->net_ports, argv);
Holger Hans Peter Freytherf3307292010-08-05 07:20:09 +0800232 return CMD_SUCCESS;
233}
234
Holger Hans Peter Freyther81938e92010-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 Freytherd3b7d772010-09-17 23:34:36 +0800240 parse_base(&g_cfg->net_ports, argv);
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800241 return CMD_SUCCESS;
242}
243
Holger Hans Peter Freytheree4657c2010-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 Freyther39f2f6d2010-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 Freyther3140c4f2010-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 Freyther489d0a62010-05-31 10:22:00 +0800270{
Holger Hans Peter Freyther3140c4f2010-07-27 20:34:45 +0800271 int dscp = atoi(argv[0]);
272 g_cfg->endp_dscp = dscp;
Holger Hans Peter Freyther489d0a62010-05-31 10:22:00 +0800273 return CMD_SUCCESS;
274}
275
Holger Hans Peter Freyther3140c4f2010-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 Freyther6f38c062010-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 Freytherab56ce12011-02-28 00:56:17 +0100287 g_cfg->trunk.audio_payload = payload;
Holger Hans Peter Freyther6f38c062010-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 Freytherab56ce12011-02-28 00:56:17 +0100296 bsc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
Holger Hans Peter Freyther6f38c062010-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 Freytherab56ce12011-02-28 00:56:17 +0100305 g_cfg->trunk.audio_loop = atoi(argv[0]);
Holger Hans Peter Freyther6f38c062010-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 Freytherab56ce12011-02-28 00:56:17 +0100315 g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100316 return CMD_SUCCESS;
317}
318
Holger Hans Peter Freyther19ff6792010-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 Freyther7c831f62010-10-12 23:21:54 +0200324 bsc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
Holger Hans Peter Freyther19ff6792010-03-31 11:46:41 +0200325 return CMD_SUCCESS;
326}
327
Holger Hans Peter Freythercab38342010-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 Freyther7c831f62010-10-12 23:21:54 +0200334 bsc_replace_string(g_cfg, &g_cfg->transcoder_ip, argv[0]);
Holger Hans Peter Freythercab38342010-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 Freythered1a5a52010-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 Freytherd582b202010-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 Freytherb33ded12010-08-03 02:57:02 +0800364DEFUN(loop_endp,
365 loop_endp_cmd,
Holger Hans Peter Freyther75cf62d2011-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 Freyther84d88992010-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 Freytherb33ded12010-08-03 02:57:02 +0800369{
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100370 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800371 struct mgcp_endpoint *endp;
372
Holger Hans Peter Freyther75cf62d2011-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 Freytherb33ded12010-08-03 02:57:02 +0800382 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100383 argv[1], endp_no, VTY_NEWLINE);
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800384 return CMD_WARNING;
385 }
386
387
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100388 endp = &trunk->endpoints[endp_no];
389 int loop = atoi(argv[2]);
Holger Hans Peter Freytherb33ded12010-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 Freyther73aa5142010-08-05 12:07:00 +0000395 endp->allow_patch = 1;
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800396
397 return CMD_SUCCESS;
398}
399
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800400DEFUN(tap_call,
401 tap_call_cmd,
Holger Hans Peter Freyther75cf62d2011-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 Freyther8fdb95e2010-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 Freyther75cf62d2011-02-28 01:29:02 +0100412 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800413 struct mgcp_endpoint *endp;
414 int port = 0;
415
Holger Hans Peter Freyther75cf62d2011-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 Freyther8fdb95e2010-08-06 01:12:21 +0800420 return CMD_WARNING;
421 }
422
Holger Hans Peter Freyther75cf62d2011-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 Freyther8fdb95e2010-08-06 01:12:21 +0800429
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100430 endp = &trunk->endpoints[endp_no];
431
432 if (strcmp(argv[2], "bts-in") == 0) {
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800433 port = MGCP_TAP_BTS_IN;
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100434 } else if (strcmp(argv[2], "bts-out") == 0) {
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800435 port = MGCP_TAP_BTS_OUT;
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100436 } else if (strcmp(argv[2], "net-in") == 0) {
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800437 port = MGCP_TAP_NET_IN;
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100438 } else if (strcmp(argv[2], "net-out") == 0) {
Holger Hans Peter Freyther8fdb95e2010-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 Freyther75cf62d2011-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 Freyther079f0332010-08-06 02:05:15 +0800449 tap->enabled = 1;
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800450 return CMD_SUCCESS;
451}
452
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800453DEFUN(free_endp, free_endp_cmd,
Holger Hans Peter Freyther75cf62d2011-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 Freyther175b9a12010-08-08 16:39:57 +0800457{
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100458 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800459 struct mgcp_endpoint *endp;
460
Holger Hans Peter Freyther75cf62d2011-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 Freyther175b9a12010-08-08 16:39:57 +0800465 return CMD_WARNING;
466 }
467
Holger Hans Peter Freyther75cf62d2011-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 Freyther175b9a12010-08-08 16:39:57 +0800476 mgcp_free_endp(endp);
477 return CMD_SUCCESS;
478}
479
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100480int mgcp_vty_init(void)
481{
Holger Hans Peter Freyther8a223852010-05-14 02:45:52 +0800482 install_element_ve(&show_mgcp_cmd);
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800483 install_element(ENABLE_NODE, &loop_endp_cmd);
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800484 install_element(ENABLE_NODE, &tap_call_cmd);
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800485 install_element(ENABLE_NODE, &free_endp_cmd);
Holger Hans Peter Freyther6f38c062010-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 Freytherb33ded12010-08-03 02:57:02 +0800489
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100490 install_default(MGCP_NODE);
Harald Welte58ed1cb2010-05-14 18:59:17 +0200491 install_element(MGCP_NODE, &ournode_exit_cmd);
Harald Weltedc82b9b2010-05-14 19:11:04 +0200492 install_element(MGCP_NODE, &ournode_end_cmd);
Holger Hans Peter Freyther6f38c062010-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 Freytheree4657c2010-08-05 03:46:07 +0800499 install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_base_port_cmd);
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800500 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_base_port_cmd);
Holger Hans Peter Freytherf3307292010-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 Freyther39f2f6d2010-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 Freyther3140c4f2010-07-27 20:34:45 +0800505 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
Holger Hans Peter Freyther489d0a62010-05-31 10:22:00 +0800506 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
Holger Hans Peter Freyther6f38c062010-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 Freyther19ff6792010-03-31 11:46:41 +0200511 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
Holger Hans Peter Freythercab38342010-09-17 03:58:52 +0800512 install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd);
Holger Hans Peter Freythered1a5a52010-11-01 20:06:45 +0100513 install_element(MGCP_NODE, &cfg_mgcp_no_transcoder_cmd);
Holger Hans Peter Freytherd582b202010-09-19 04:21:39 +0800514 install_element(MGCP_NODE, &cfg_mgcp_transcoder_remote_base_cmd);
Holger Hans Peter Freyther6f38c062010-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 Welte40152872010-05-16 20:52:23 +0200523 rc = vty_read_config_file(config_file, NULL);
Holger Hans Peter Freyther6f38c062010-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 Freytherbdd3cc32010-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 Freyther6f38c062010-02-20 21:21:02 +0100538 if (mgcp_endpoints_allocate(g_cfg) != 0) {
Holger Hans Peter Freytherab56ce12011-02-28 00:56:17 +0100539 fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n",
540 g_cfg->trunk.number_endpoints);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100541 return -1;
542 }
543
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100544 /* early bind */
Holger Hans Peter Freytherab56ce12011-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 Freyther7140dae2010-08-05 03:22:24 +0800547 int rtp_port;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100548
Holger Hans Peter Freytherf3307292010-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 Freyther05d8f5f2010-08-05 08:08:17 +0800556 endp->bts_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100557 }
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800558
Holger Hans Peter Freytherf3307292010-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 Freyther05d8f5f2010-08-05 08:08:17 +0800566 endp->net_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800567 }
Holger Hans Peter Freyther56ac2692010-09-18 02:30:02 +0800568
569 if (g_cfg->transcoder_ip && g_cfg->transcoder_ports.mode == PORT_ALLOC_STATIC) {
Holger Hans Peter Freytherc983f832010-11-01 21:04:54 +0100570 /* network side */
Holger Hans Peter Freyther56ac2692010-09-18 02:30:02 +0800571 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
572 g_cfg->transcoder_ports.base_port);
Holger Hans Peter Freytherc983f832010-11-01 21:04:54 +0100573 if (mgcp_bind_trans_net_rtp_port(endp, rtp_port) != 0) {
Holger Hans Peter Freyther56ac2692010-09-18 02:30:02 +0800574 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
575 return -1;
576 }
Holger Hans Peter Freytherb6345ab2010-11-01 20:53:31 +0100577 endp->trans_net.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freytherc983f832010-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 Freyther56ac2692010-09-18 02:30:02 +0800587 }
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100588 }
589
Holger Hans Peter Freyther64344522010-08-05 01:28:22 +0800590 return 0;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100591}
592