blob: 7052e8471a2c2265c035eed4fcd65648932bb2ca [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
Holger Hans Peter Freyther06bfe792011-02-28 12:11:02 +010057struct cmd_node trunk_node = {
58 TRUNK_NODE,
59 "%s(trunk)#",
60 1,
61};
62
Holger Hans Peter Freyther6f38c062010-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 Freythere8d13712010-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 Freyther6f38c062010-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 Freyther2ea91182010-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 Freytherf3307292010-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 Freyther2ea91182010-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 Freytherf3307292010-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 Freyther3140c4f2010-07-27 20:34:45 +080085 vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
Holger Hans Peter Freytherab56ce12011-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 Freyther19ff6792010-03-31 11:46:41 +020094 if (g_cfg->call_agent_addr)
Holger Hans Peter Freythere8d13712010-04-16 16:59:48 +020095 vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
Holger Hans Peter Freythercab38342010-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 Freyther6f38c062010-02-20 21:21:02 +010098
Holger Hans Peter Freyther39f2f6d2010-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 Freytherd582b202010-09-19 04:21:39 +0800104 vty_out(vty, " transcoder-remote-base %u%s", g_cfg->transcoder_remote_base, VTY_NEWLINE);
Holger Hans Peter Freyther39f2f6d2010-09-17 23:35:53 +0800105
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100106 return CMD_SUCCESS;
107}
108
Holger Hans Peter Freyther1584bdb2011-02-28 01:12:33 +0100109static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg)
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100110{
111 int i;
112
Holger Hans Peter Freyther1584bdb2011-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
117 for (i = 1; i < cfg->number_endpoints; ++i) {
118 struct mgcp_endpoint *endp = &cfg->endpoints[i];
119 vty_out(vty,
120 " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s "
121 "traffic received bts: %u/%u remote: %u/%u transcoder: %u/%u%s",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100122 i, endp->ci,
Holger Hans Peter Freytherfab76aa2010-08-05 01:34:51 +0800123 ntohs(endp->net_end.rtp_port), ntohs(endp->net_end.rtcp_port),
124 ntohs(endp->bts_end.rtp_port), ntohs(endp->bts_end.rtcp_port),
125 inet_ntoa(endp->bts_end.addr),
126 endp->bts_end.packets, endp->bts_state.lost_no,
127 endp->net_end.packets, endp->net_state.lost_no,
Holger Hans Peter Freytherc983f832010-11-01 21:04:54 +0100128 endp->trans_net.packets, endp->trans_bts.packets,
Holger Hans Peter Freyther6de5b112010-04-07 09:37:17 +0200129 VTY_NEWLINE);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100130 }
Holger Hans Peter Freyther1584bdb2011-02-28 01:12:33 +0100131}
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100132
Holger Hans Peter Freyther1584bdb2011-02-28 01:12:33 +0100133DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp",
134 SHOW_STR "Display information about the MGCP Media Gateway")
135{
136 dump_trunk(vty, &g_cfg->trunk);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100137 return CMD_SUCCESS;
138}
139
140DEFUN(cfg_mgcp,
141 cfg_mgcp_cmd,
142 "mgcp",
143 "Configure the MGCP")
144{
145 vty->node = MGCP_NODE;
146 return CMD_SUCCESS;
147}
148
149DEFUN(cfg_mgcp_local_ip,
150 cfg_mgcp_local_ip_cmd,
Holger Hans Peter Freyther5c9a6452010-05-14 02:27:50 +0800151 "local ip A.B.C.D",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100152 "Set the IP to be used in SDP records")
153{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200154 bsc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100155 return CMD_SUCCESS;
156}
157
158DEFUN(cfg_mgcp_bts_ip,
159 cfg_mgcp_bts_ip_cmd,
Holger Hans Peter Freyther5c9a6452010-05-14 02:27:50 +0800160 "bts ip A.B.C.D",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100161 "Set the IP of the BTS for RTP forwarding")
162{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200163 bsc_replace_string(g_cfg, &g_cfg->bts_ip, argv[0]);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100164 inet_aton(g_cfg->bts_ip, &g_cfg->bts_in);
165 return CMD_SUCCESS;
166}
167
168DEFUN(cfg_mgcp_bind_ip,
169 cfg_mgcp_bind_ip_cmd,
Holger Hans Peter Freyther5c9a6452010-05-14 02:27:50 +0800170 "bind ip A.B.C.D",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100171 "Bind the MGCP to this local addr")
172{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200173 bsc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100174 return CMD_SUCCESS;
175}
176
177DEFUN(cfg_mgcp_bind_port,
178 cfg_mgcp_bind_port_cmd,
179 "bind port <0-65534>",
180 "Bind the MGCP to this port")
181{
182 unsigned int port = atoi(argv[0]);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100183 g_cfg->source_port = port;
184 return CMD_SUCCESS;
185}
186
187DEFUN(cfg_mgcp_bind_early,
188 cfg_mgcp_bind_early_cmd,
189 "bind early (0|1)",
190 "Bind all RTP ports early")
191{
Holger Hans Peter Freyther7140dae2010-08-05 03:22:24 +0800192 vty_out(vty, "bind early is deprecated, remove it from the config.\n");
193 return CMD_WARNING;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100194}
195
Holger Hans Peter Freytherd3b7d772010-09-17 23:34:36 +0800196static void parse_base(struct mgcp_port_range *range, const char **argv)
197{
198 unsigned int port = atoi(argv[0]);
199 range->mode = PORT_ALLOC_STATIC;
200 range->base_port = port;
201}
202
203static void parse_range(struct mgcp_port_range *range, const char **argv)
204{
205 range->mode = PORT_ALLOC_DYNAMIC;
206 range->range_start = atoi(argv[0]);
207 range->range_end = atoi(argv[1]);
208 range->last_port = g_cfg->bts_ports.range_start;
209}
210
211
Holger Hans Peter Freytheree4657c2010-08-05 03:46:07 +0800212DEFUN(cfg_mgcp_rtp_bts_base_port,
213 cfg_mgcp_rtp_bts_base_port_cmd,
214 "rtp bts-base <0-65534>",
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100215 "Base port to use")
216{
Holger Hans Peter Freytherd3b7d772010-09-17 23:34:36 +0800217 parse_base(&g_cfg->bts_ports, argv);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100218 return CMD_SUCCESS;
219}
220
Holger Hans Peter Freytherf3307292010-08-05 07:20:09 +0800221DEFUN(cfg_mgcp_rtp_bts_range,
222 cfg_mgcp_rtp_bts_range_cmd,
223 "rtp bts-range <0-65534> <0-65534>",
224 "Range of ports to allocate for endpoints\n"
225 "Start of the range of ports\n" "End of the range of ports\n")
226{
Holger Hans Peter Freytherd3b7d772010-09-17 23:34:36 +0800227 parse_range(&g_cfg->bts_ports, argv);
Holger Hans Peter Freytherf3307292010-08-05 07:20:09 +0800228 return CMD_SUCCESS;
229}
230
231DEFUN(cfg_mgcp_rtp_net_range,
232 cfg_mgcp_rtp_net_range_cmd,
233 "rtp net-range <0-65534> <0-65534>",
234 "Range of ports to allocate for endpoints\n"
235 "Start of the range of ports\n" "End of the range of ports\n")
236{
Holger Hans Peter Freytherd3b7d772010-09-17 23:34:36 +0800237 parse_range(&g_cfg->net_ports, argv);
Holger Hans Peter Freytherf3307292010-08-05 07:20:09 +0800238 return CMD_SUCCESS;
239}
240
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800241DEFUN(cfg_mgcp_rtp_net_base_port,
242 cfg_mgcp_rtp_net_base_port_cmd,
243 "rtp net-base <0-65534>",
244 "Base port to use for network port\n" "Port\n")
245{
Holger Hans Peter Freytherd3b7d772010-09-17 23:34:36 +0800246 parse_base(&g_cfg->net_ports, argv);
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800247 return CMD_SUCCESS;
248}
249
Holger Hans Peter Freytheree4657c2010-08-05 03:46:07 +0800250ALIAS_DEPRECATED(cfg_mgcp_rtp_bts_base_port, cfg_mgcp_rtp_base_port_cmd,
251 "rtp base <0-65534>", "Base port to use")
252
Holger Hans Peter Freyther39f2f6d2010-09-17 23:35:53 +0800253DEFUN(cfg_mgcp_rtp_transcoder_range,
254 cfg_mgcp_rtp_transcoder_range_cmd,
255 "rtp transcoder-range <0-65534> <0-65534>",
256 "Range of ports to allocate for the transcoder\n"
257 "Start of the range of ports\n" "End of the range of ports\n")
258{
259 parse_range(&g_cfg->transcoder_ports, argv);
260 return CMD_SUCCESS;
261}
262
263DEFUN(cfg_mgcp_rtp_transcoder_base,
264 cfg_mgcp_rtp_transcoder_base_cmd,
265 "rtp transcoder-base <0-65534>",
266 "Base port for the transcoder range\n" "Port\n")
267{
268 parse_base(&g_cfg->transcoder_ports, argv);
269 return CMD_SUCCESS;
270}
271
Holger Hans Peter Freyther3140c4f2010-07-27 20:34:45 +0800272DEFUN(cfg_mgcp_rtp_ip_dscp,
273 cfg_mgcp_rtp_ip_dscp_cmd,
274 "rtp ip-dscp <0-255>",
275 "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.")
Holger Hans Peter Freyther489d0a62010-05-31 10:22:00 +0800276{
Holger Hans Peter Freyther3140c4f2010-07-27 20:34:45 +0800277 int dscp = atoi(argv[0]);
278 g_cfg->endp_dscp = dscp;
Holger Hans Peter Freyther489d0a62010-05-31 10:22:00 +0800279 return CMD_SUCCESS;
280}
281
Holger Hans Peter Freyther3140c4f2010-07-27 20:34:45 +0800282ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
283 "rtp ip-tos <0-255>",
284 "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.")
285
286
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100287DEFUN(cfg_mgcp_sdp_payload_number,
288 cfg_mgcp_sdp_payload_number_cmd,
289 "sdp audio payload number <1-255>",
290 "Set the audio codec to use")
291{
292 unsigned int payload = atoi(argv[0]);
Holger Hans Peter Freytherab56ce12011-02-28 00:56:17 +0100293 g_cfg->trunk.audio_payload = payload;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100294 return CMD_SUCCESS;
295}
296
297DEFUN(cfg_mgcp_sdp_payload_name,
298 cfg_mgcp_sdp_payload_name_cmd,
299 "sdp audio payload name NAME",
300 "Set the audio name to use")
301{
Holger Hans Peter Freytherab56ce12011-02-28 00:56:17 +0100302 bsc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100303 return CMD_SUCCESS;
304}
305
306DEFUN(cfg_mgcp_loop,
307 cfg_mgcp_loop_cmd,
308 "loop (0|1)",
309 "Loop the audio")
310{
Holger Hans Peter Freytherab56ce12011-02-28 00:56:17 +0100311 g_cfg->trunk.audio_loop = atoi(argv[0]);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100312 return CMD_SUCCESS;
313}
314
315DEFUN(cfg_mgcp_number_endp,
316 cfg_mgcp_number_endp_cmd,
317 "number endpoints <0-65534>",
318 "The number of endpoints to allocate. This is not dynamic.")
319{
320 /* + 1 as we start counting at one */
Holger Hans Peter Freytherab56ce12011-02-28 00:56:17 +0100321 g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100322 return CMD_SUCCESS;
323}
324
Holger Hans Peter Freyther19ff6792010-03-31 11:46:41 +0200325DEFUN(cfg_mgcp_agent_addr,
326 cfg_mgcp_agent_addr_cmd,
327 "call agent ip IP",
328 "Set the address of the call agent.")
329{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200330 bsc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
Holger Hans Peter Freyther19ff6792010-03-31 11:46:41 +0200331 return CMD_SUCCESS;
332}
333
Holger Hans Peter Freythercab38342010-09-17 03:58:52 +0800334DEFUN(cfg_mgcp_transcoder,
335 cfg_mgcp_transcoder_cmd,
336 "transcoder-mgw A.B.C.D",
337 "Use a MGW to detranscoder RTP\n"
338 "The IP address of the MGW")
339{
Holger Hans Peter Freyther7c831f62010-10-12 23:21:54 +0200340 bsc_replace_string(g_cfg, &g_cfg->transcoder_ip, argv[0]);
Holger Hans Peter Freythercab38342010-09-17 03:58:52 +0800341 inet_aton(g_cfg->transcoder_ip, &g_cfg->transcoder_in);
342
343 return CMD_SUCCESS;
344}
345
Holger Hans Peter Freythered1a5a52010-11-01 20:06:45 +0100346DEFUN(cfg_mgcp_no_transcoder,
347 cfg_mgcp_no_transcoder_cmd,
348 NO_STR "transcoder-mgw",
349 "Disable the transcoding\n")
350{
351 if (g_cfg->transcoder_ip) {
352 LOGP(DMGCP, LOGL_NOTICE, "Disabling transcoding on future calls.\n");
353 talloc_free(g_cfg->transcoder_ip);
354 g_cfg->transcoder_ip = NULL;
355 }
356
357 return CMD_SUCCESS;
358}
359
Holger Hans Peter Freytherd582b202010-09-19 04:21:39 +0800360DEFUN(cfg_mgcp_transcoder_remote_base,
361 cfg_mgcp_transcoder_remote_base_cmd,
362 "transcoder-remote-base <0-65534>",
363 "Set the base port for the transcoder\n" "The RTP base port on the transcoder")
364{
365 g_cfg->transcoder_remote_base = atoi(argv[0]);
366 return CMD_SUCCESS;
367}
368
Holger Hans Peter Freyther06bfe792011-02-28 12:11:02 +0100369DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
370 "trunk <1-64>",
371 "Configure a SS7 trunk\n" "Trunk Nr\n")
372{
373 struct mgcp_trunk_config *trunk;
374 int index = atoi(argv[0]);
375
376 trunk = mgcp_trunk_num(g_cfg, index);
377 if (!trunk)
378 trunk = mgcp_trunk_alloc(g_cfg, index);
379
380 if (!trunk) {
381 vty_out(vty, "%%Unable to allocate trunk %u.%s",
382 index, VTY_NEWLINE);
383 return CMD_WARNING;
384 }
385
386 vty->node = TRUNK_NODE;
387 vty->index = trunk;
388 return CMD_SUCCESS;
389}
390
391static int config_write_trunk(struct vty *vty)
392{
393 struct mgcp_trunk_config *trunk;
394
395 llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
396 vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
397 vty_out(vty, " sdp audio payload number %d%s",
398 trunk->audio_payload, VTY_NEWLINE);
399 vty_out(vty, " sdp audio payload name %s%s",
400 trunk->audio_name, VTY_NEWLINE);
401 vty_out(vty, " loop %d%s",
402 trunk->audio_loop, VTY_NEWLINE);
403 }
404
405 return CMD_SUCCESS;
406}
407
408DEFUN(cfg_trunk_payload_number,
409 cfg_trunk_payload_number_cmd,
410 "sdp audio payload number <1-255>",
411 "SDP related\n" "Audio\n" "Payload\n" "Payload Number\n")
412{
413 struct mgcp_trunk_config *trunk = vty->index;
414 unsigned int payload = atoi(argv[0]);
415
416 trunk->audio_payload = payload;
417 return CMD_SUCCESS;
418}
419
420DEFUN(cfg_trunk_payload_name,
421 cfg_trunk_payload_name_cmd,
422 "sdp audio payload name NAME",
423 "SDP related\n" "Audio\n" "Payload\n" "Payload Name\n")
424{
425 struct mgcp_trunk_config *trunk = vty->index;
426
427 bsc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
428 return CMD_SUCCESS;
429}
430
431DEFUN(cfg_trunk_loop,
432 cfg_trunk_loop_cmd,
433 "loop (0|1)",
434 "Loop the audio")
435{
436 struct mgcp_trunk_config *trunk = vty->index;
437
438 trunk->audio_loop = atoi(argv[0]);
439 return CMD_SUCCESS;
440}
Holger Hans Peter Freytherd582b202010-09-19 04:21:39 +0800441
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800442DEFUN(loop_endp,
443 loop_endp_cmd,
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100444 "loop-endpoint <0-64> NAME (0|1)",
445 "Loop a given endpoint\n" "Trunk number\n"
Holger Hans Peter Freyther84d88992010-08-03 23:00:03 +0800446 "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 +0800447{
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100448 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800449 struct mgcp_endpoint *endp;
450
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100451 trunk = find_trunk(g_cfg, atoi(argv[0]));
452 if (!trunk) {
453 vty_out(vty, "%%Trunk %d not found in the config.%s",
454 atoi(argv[0]), VTY_NEWLINE);
455 return CMD_WARNING;
456 }
457
458 int endp_no = strtoul(argv[1], NULL, 16);
459 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800460 vty_out(vty, "Loopback number %s/%d is invalid.%s",
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100461 argv[1], endp_no, VTY_NEWLINE);
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800462 return CMD_WARNING;
463 }
464
465
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100466 endp = &trunk->endpoints[endp_no];
467 int loop = atoi(argv[2]);
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800468
469 if (loop)
470 endp->conn_mode = MGCP_CONN_LOOPBACK;
471 else
472 endp->conn_mode = endp->orig_mode;
Holger Hans Peter Freyther73aa5142010-08-05 12:07:00 +0000473 endp->allow_patch = 1;
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800474
475 return CMD_SUCCESS;
476}
477
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800478DEFUN(tap_call,
479 tap_call_cmd,
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100480 "tap-call <0-64> ENDPOINT (bts-in|bts-out|net-in|net-out) A.B.C.D <0-65534>",
481 "Forward data on endpoint to a different system\n" "Trunk number\n"
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800482 "The endpoint in hex\n"
483 "Forward the data coming from the bts\n"
484 "Forward the data coming from the bts leaving to the network\n"
485 "Forward the data coming from the net\n"
486 "Forward the data coming from the net leaving to the bts\n"
487 "destination IP of the data\n" "destination port\n")
488{
489 struct mgcp_rtp_tap *tap;
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100490 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800491 struct mgcp_endpoint *endp;
492 int port = 0;
493
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100494 trunk = find_trunk(g_cfg, atoi(argv[0]));
495 if (!trunk) {
496 vty_out(vty, "%%Trunk %d not found in the config.%s",
497 atoi(argv[0]), VTY_NEWLINE);
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800498 return CMD_WARNING;
499 }
500
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100501 int endp_no = strtoul(argv[1], NULL, 16);
502 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
503 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
504 argv[1], endp_no, VTY_NEWLINE);
505 return CMD_WARNING;
506 }
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800507
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100508 endp = &trunk->endpoints[endp_no];
509
510 if (strcmp(argv[2], "bts-in") == 0) {
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800511 port = MGCP_TAP_BTS_IN;
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100512 } else if (strcmp(argv[2], "bts-out") == 0) {
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800513 port = MGCP_TAP_BTS_OUT;
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100514 } else if (strcmp(argv[2], "net-in") == 0) {
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800515 port = MGCP_TAP_NET_IN;
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100516 } else if (strcmp(argv[2], "net-out") == 0) {
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800517 port = MGCP_TAP_NET_OUT;
518 } else {
519 vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
520 return CMD_WARNING;
521 }
522
523 tap = &endp->taps[port];
524 memset(&tap->forward, 0, sizeof(tap->forward));
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100525 inet_aton(argv[3], &tap->forward.sin_addr);
526 tap->forward.sin_port = htons(atoi(argv[4]));
Holger Hans Peter Freyther079f0332010-08-06 02:05:15 +0800527 tap->enabled = 1;
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800528 return CMD_SUCCESS;
529}
530
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800531DEFUN(free_endp, free_endp_cmd,
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100532 "free-endpoint <0-64> NUMBER",
533 "Free the given endpoint\n" "Trunk number\n"
534 "Endpoint number in hex.\n")
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800535{
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100536 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800537 struct mgcp_endpoint *endp;
538
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100539 trunk = find_trunk(g_cfg, atoi(argv[0]));
540 if (!trunk) {
541 vty_out(vty, "%%Trunk %d not found in the config.%s",
542 atoi(argv[0]), VTY_NEWLINE);
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800543 return CMD_WARNING;
544 }
545
Holger Hans Peter Freyther75cf62d2011-02-28 01:29:02 +0100546 int endp_no = strtoul(argv[1], NULL, 16);
547 if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
548 vty_out(vty, "Endpoint number %s/%d is invalid.%s",
549 argv[1], endp_no, VTY_NEWLINE);
550 return CMD_WARNING;
551 }
552
553 endp = &trunk->endpoints[endp_no];
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800554 mgcp_free_endp(endp);
555 return CMD_SUCCESS;
556}
557
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100558int mgcp_vty_init(void)
559{
Holger Hans Peter Freyther8a223852010-05-14 02:45:52 +0800560 install_element_ve(&show_mgcp_cmd);
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800561 install_element(ENABLE_NODE, &loop_endp_cmd);
Holger Hans Peter Freyther8fdb95e2010-08-06 01:12:21 +0800562 install_element(ENABLE_NODE, &tap_call_cmd);
Holger Hans Peter Freyther175b9a12010-08-08 16:39:57 +0800563 install_element(ENABLE_NODE, &free_endp_cmd);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100564
565 install_element(CONFIG_NODE, &cfg_mgcp_cmd);
566 install_node(&mgcp_node, config_write_mgcp);
Holger Hans Peter Freytherb33ded12010-08-03 02:57:02 +0800567
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100568 install_default(MGCP_NODE);
Harald Welte58ed1cb2010-05-14 18:59:17 +0200569 install_element(MGCP_NODE, &ournode_exit_cmd);
Harald Weltedc82b9b2010-05-14 19:11:04 +0200570 install_element(MGCP_NODE, &ournode_end_cmd);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100571 install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
572 install_element(MGCP_NODE, &cfg_mgcp_bts_ip_cmd);
573 install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
574 install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
575 install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
576 install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_cmd);
Holger Hans Peter Freytheree4657c2010-08-05 03:46:07 +0800577 install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_base_port_cmd);
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800578 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_base_port_cmd);
Holger Hans Peter Freytherf3307292010-08-05 07:20:09 +0800579 install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_range_cmd);
580 install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
Holger Hans Peter Freyther39f2f6d2010-09-17 23:35:53 +0800581 install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_range_cmd);
582 install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_base_cmd);
Holger Hans Peter Freyther3140c4f2010-07-27 20:34:45 +0800583 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
Holger Hans Peter Freyther489d0a62010-05-31 10:22:00 +0800584 install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
Holger Hans Peter Freyther19ff6792010-03-31 11:46:41 +0200585 install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
Holger Hans Peter Freythercab38342010-09-17 03:58:52 +0800586 install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd);
Holger Hans Peter Freythered1a5a52010-11-01 20:06:45 +0100587 install_element(MGCP_NODE, &cfg_mgcp_no_transcoder_cmd);
Holger Hans Peter Freytherd582b202010-09-19 04:21:39 +0800588 install_element(MGCP_NODE, &cfg_mgcp_transcoder_remote_base_cmd);
Holger Hans Peter Freyther06bfe792011-02-28 12:11:02 +0100589 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
590 install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
591 install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
592 install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
593
594 install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
595 install_node(&trunk_node, config_write_trunk);
596 install_default(TRUNK_NODE);
597 install_element(TRUNK_NODE, &ournode_exit_cmd);
598 install_element(TRUNK_NODE, &ournode_end_cmd);
599 install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
600 install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
601 install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
602
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100603 return 0;
604}
605
606int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
607{
608 int i, rc;
609
610 g_cfg = cfg;
Harald Welte40152872010-05-16 20:52:23 +0200611 rc = vty_read_config_file(config_file, NULL);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100612 if (rc < 0) {
613 fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
614 return rc;
615 }
616
617
618 if (!g_cfg->bts_ip)
619 fprintf(stderr, "No BTS ip address specified. This will allow everyone to connect.\n");
620
Holger Hans Peter Freytherbdd3cc32010-03-30 13:00:10 +0200621 if (!g_cfg->source_addr) {
622 fprintf(stderr, "You need to specify a bind address.\n");
623 return -1;
624 }
625
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100626 if (mgcp_endpoints_allocate(g_cfg) != 0) {
Holger Hans Peter Freytherab56ce12011-02-28 00:56:17 +0100627 fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n",
628 g_cfg->trunk.number_endpoints);
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100629 return -1;
630 }
631
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100632 /* early bind */
Holger Hans Peter Freytherab56ce12011-02-28 00:56:17 +0100633 for (i = 1; i < g_cfg->trunk.number_endpoints; ++i) {
634 struct mgcp_endpoint *endp = &g_cfg->trunk.endpoints[i];
Holger Hans Peter Freyther7140dae2010-08-05 03:22:24 +0800635 int rtp_port;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100636
Holger Hans Peter Freytherf3307292010-08-05 07:20:09 +0800637 if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC) {
638 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
639 g_cfg->bts_ports.base_port);
640 if (mgcp_bind_bts_rtp_port(endp, rtp_port) != 0) {
641 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
642 return -1;
643 }
Holger Hans Peter Freyther05d8f5f2010-08-05 08:08:17 +0800644 endp->bts_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100645 }
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800646
Holger Hans Peter Freytherf3307292010-08-05 07:20:09 +0800647 if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC) {
648 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
649 g_cfg->net_ports.base_port);
650 if (mgcp_bind_net_rtp_port(endp, rtp_port) != 0) {
651 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
652 return -1;
653 }
Holger Hans Peter Freyther05d8f5f2010-08-05 08:08:17 +0800654 endp->net_end.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther81938e92010-08-05 04:10:21 +0800655 }
Holger Hans Peter Freyther56ac2692010-09-18 02:30:02 +0800656
657 if (g_cfg->transcoder_ip && g_cfg->transcoder_ports.mode == PORT_ALLOC_STATIC) {
Holger Hans Peter Freytherc983f832010-11-01 21:04:54 +0100658 /* network side */
Holger Hans Peter Freyther56ac2692010-09-18 02:30:02 +0800659 rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
660 g_cfg->transcoder_ports.base_port);
Holger Hans Peter Freytherc983f832010-11-01 21:04:54 +0100661 if (mgcp_bind_trans_net_rtp_port(endp, rtp_port) != 0) {
Holger Hans Peter Freyther56ac2692010-09-18 02:30:02 +0800662 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
663 return -1;
664 }
Holger Hans Peter Freytherb6345ab2010-11-01 20:53:31 +0100665 endp->trans_net.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freytherc983f832010-11-01 21:04:54 +0100666
667 /* bts side */
668 rtp_port = rtp_calculate_port(endp_back_channel(ENDPOINT_NUMBER(endp)),
669 g_cfg->transcoder_ports.base_port);
670 if (mgcp_bind_trans_bts_rtp_port(endp, rtp_port) != 0) {
671 LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
672 return -1;
673 }
674 endp->trans_bts.local_alloc = PORT_ALLOC_STATIC;
Holger Hans Peter Freyther56ac2692010-09-18 02:30:02 +0800675 }
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100676 }
677
Holger Hans Peter Freyther64344522010-08-05 01:28:22 +0800678 return 0;
Holger Hans Peter Freyther6f38c062010-02-20 21:21:02 +0100679}
680