aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-09-14 19:14:54 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-09-14 22:29:14 +0200
commitf574cec74543e6632a332d1b6995a8c827ca22f1 (patch)
tree242a8752bc6c1a9465b9cf6732c006cfc76bff88
parent96cc57af80d91054b4d23e6de83015bf93fefb18 (diff)
mgcp: Introduce multiple virtual trunks
A virtual trunk is identified by a virtual domain name.
-rw-r--r--include/mgcp/mgcp.h3
-rw-r--r--include/mgcp/mgcp_internal.h2
-rw-r--r--include/ss7_vty.h1
-rw-r--r--src/mgcp/mgcp_protocol.c68
-rw-r--r--src/mgcp/mgcp_vty.c196
-rw-r--r--src/mgcp_ss7.c9
-rw-r--r--src/mgcp_ss7_vty.c240
7 files changed, 236 insertions, 283 deletions
diff --git a/include/mgcp/mgcp.h b/include/mgcp/mgcp.h
index d5574ed..50b11cc 100644
--- a/include/mgcp/mgcp.h
+++ b/include/mgcp/mgcp.h
@@ -122,6 +122,7 @@ struct mgcp_trunk_config {
struct mgcp_endpoint *endpoints;
/* Special MGW handling */
+ char *virtual_domain;
int target_trunk_start;
int vad_enabled;
@@ -165,7 +166,7 @@ struct mgcp_config {
void *data;
/* trunk handling */
- struct mgcp_trunk_config trunk;
+ struct llist_head vtrunks;
struct llist_head trunks;
/* only used for start with a static configuration */
diff --git a/include/mgcp/mgcp_internal.h b/include/mgcp/mgcp_internal.h
index d499166..f0faf52 100644
--- a/include/mgcp/mgcp_internal.h
+++ b/include/mgcp/mgcp_internal.h
@@ -154,7 +154,9 @@ static inline int endp_back_channel(int endpoint)
}
struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int index);
+struct mgcp_trunk_config *mgcp_vtrunk_alloc(struct mgcp_config *cfg, const char *);
struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index);
+struct mgcp_trunk_config *mgcp_trunk_domain(struct mgcp_config *cfg, const char *);
void mgcp_trunk_free(struct mgcp_trunk_config *cfg);
diff --git a/include/ss7_vty.h b/include/ss7_vty.h
index a0368bd..da599e5 100644
--- a/include/ss7_vty.h
+++ b/include/ss7_vty.h
@@ -28,6 +28,7 @@
enum ss7_vty_node {
MGCP_NODE = _LAST_OSMOVTY_NODE + 1,
TRUNK_NODE,
+ VTRUNK_NODE,
CELLMGR_NODE,
SS7_NODE,
LINKSETS_NODE,
diff --git a/src/mgcp/mgcp_protocol.c b/src/mgcp/mgcp_protocol.c
index d583cee..6dc6090 100644
--- a/src/mgcp/mgcp_protocol.c
+++ b/src/mgcp/mgcp_protocol.c
@@ -308,6 +308,27 @@ static struct mgcp_endpoint *find_e1_endpoint(struct mgcp_config *cfg,
return &tcfg->endpoints[endp];
}
+struct mgcp_endpoint *find_virtual_endpoint(struct mgcp_config *cfg,
+ const char *endptr, int gw)
+{
+ struct mgcp_trunk_config *tcfg;
+
+ if (gw <= 0)
+ return NULL;
+
+ llist_for_each_entry(tcfg, &cfg->vtrunks, entry) {
+ if (strcmp(&endptr[1], tcfg->virtual_domain) != 0)
+ continue;
+
+ if (gw >= tcfg->number_endpoints)
+ return NULL;
+
+ return &tcfg->endpoints[gw];
+ }
+
+ return NULL;
+}
+
static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *mgcp)
{
struct mgcp_endpoint *endp = NULL;
@@ -318,8 +339,7 @@ static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *
endp = find_e1_endpoint(cfg, mgcp);
} else {
gw = strtoul(mgcp, &endptr, 16);
- if (gw > 0 && gw < cfg->trunk.number_endpoints && strcmp(endptr, "@mgw") == 0)
- endp = &cfg->trunk.endpoints[gw];
+ endp = find_virtual_endpoint(cfg, endptr, gw);
}
if (!endp) {
@@ -908,11 +928,7 @@ struct mgcp_config *mgcp_config_alloc(void)
cfg->net_ports.base_port = RTP_PORT_NET_DEFAULT;
/* default trunk handling */
- cfg->trunk.cfg = cfg;
- cfg->trunk.trunk_nr = 0;
- cfg->trunk.trunk_type = MGCP_TRUNK_VIRTUAL;
- trunk_init(&cfg->trunk);
-
+ INIT_LLIST_HEAD(&cfg->vtrunks);
INIT_LLIST_HEAD(&cfg->trunks);
return cfg;
@@ -937,6 +953,32 @@ struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr)
return trunk;
}
+struct mgcp_trunk_config *mgcp_vtrunk_alloc(struct mgcp_config *cfg,
+ const char *domain)
+{
+ struct mgcp_trunk_config *trunk;
+
+ trunk = talloc_zero(cfg, struct mgcp_trunk_config);
+ if (!trunk) {
+ LOGP(DMGCP, LOGL_ERROR, "Failed to allocate.\n");
+ return NULL;
+ }
+
+ trunk->virtual_domain = talloc_strdup(trunk, domain);
+ if (!trunk->virtual_domain) {
+ LOGP(DMGCP, LOGL_ERROR, "Failed to allocate.\n");
+ talloc_free(trunk);
+ return NULL;
+ }
+
+ trunk->cfg = cfg;
+ trunk->trunk_type = MGCP_TRUNK_VIRTUAL;
+ trunk->trunk_nr = 0;
+ trunk_init(trunk);
+ llist_add_tail(&trunk->entry, &cfg->vtrunks);
+ return trunk;
+}
+
void mgcp_trunk_free(struct mgcp_trunk_config *cfg)
{
llist_del(&cfg->entry);
@@ -954,6 +996,18 @@ struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index)
return NULL;
}
+struct mgcp_trunk_config *mgcp_trunk_domain(struct mgcp_config *cfg,
+ const char *domain)
+{
+ struct mgcp_trunk_config *trunk;
+
+ llist_for_each_entry(trunk, &cfg->vtrunks, entry)
+ if (strcmp(trunk->virtual_domain, domain) == 0)
+ return trunk;
+
+ return NULL;
+}
+
static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end)
{
if (end->local_alloc == PORT_ALLOC_DYNAMIC) {
diff --git a/src/mgcp/mgcp_vty.c b/src/mgcp/mgcp_vty.c
index 15ea196..33bfe81 100644
--- a/src/mgcp/mgcp_vty.c
+++ b/src/mgcp/mgcp_vty.c
@@ -36,6 +36,7 @@
/* MGW changes */
extern void mgcp_write_extra(struct vty *vty, struct mgcp_config *cfg);
extern void mgcp_write_trunk_extra(struct vty *vty, struct mgcp_trunk_config *cfg);
+extern void mgcp_write_vtrunk_extra(struct vty *vty, struct mgcp_trunk_config *cfg);
static int allocate_endpoints(struct mgcp_trunk_config *tcfg);
@@ -43,6 +44,7 @@ enum node_type mgcp_go_parent(struct vty *vty)
{
switch (vty->node) {
case TRUNK_NODE:
+ case VTRUNK_NODE:
vty->node = MGCP_NODE;
break;
default:
@@ -88,14 +90,15 @@ static void bsc_replace_string(void *ctx, char **dst, const char *newstr)
struct mgcp_config *g_cfg = NULL;
-static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
+static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg,
+ const char *type, const char *name)
{
struct mgcp_trunk_config *trunk;
- if (nr == 0)
- trunk = &cfg->trunk;
+ if (strcmp(type, "virtual") == 0)
+ trunk = mgcp_trunk_domain(cfg, name);
else
- trunk = mgcp_trunk_num(cfg, nr);
+ trunk = mgcp_trunk_num(cfg, atoi(name));
return trunk;
}
@@ -109,6 +112,12 @@ struct cmd_node mgcp_node = {
1,
};
+struct cmd_node vtrunk_node = {
+ VTRUNK_NODE,
+ "%s(vtrunk)#",
+ 1,
+};
+
struct cmd_node trunk_node = {
TRUNK_NODE,
"%s(trunk)#",
@@ -138,14 +147,6 @@ static int config_write_mgcp(struct vty *vty)
g_cfg->net_ports.range_start, g_cfg->net_ports.range_end, VTY_NEWLINE);
vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
- if (g_cfg->trunk.audio_payload != -1)
- vty_out(vty, " sdp audio payload number %d%s",
- g_cfg->trunk.audio_payload, VTY_NEWLINE);
- if (g_cfg->trunk.audio_name)
- vty_out(vty, " sdp audio payload name %s%s",
- g_cfg->trunk.audio_name, VTY_NEWLINE);
- vty_out(vty, " loop %u%s", !!g_cfg->trunk.audio_loop, VTY_NEWLINE);
- vty_out(vty, " number endpoints %u%s", g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
if (g_cfg->call_agent_addr)
vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
if (g_cfg->transcoder_ip)
@@ -159,7 +160,6 @@ static int config_write_mgcp(struct vty *vty)
vty_out(vty, " transcoder-remote-base %u%s", g_cfg->transcoder_remote_base, VTY_NEWLINE);
mgcp_write_extra(vty, g_cfg);
-
return CMD_SUCCESS;
}
@@ -197,7 +197,8 @@ DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp",
{
struct mgcp_trunk_config *trunk;
- dump_trunk(vty, &g_cfg->trunk);
+ llist_for_each_entry(trunk, &g_cfg->vtrunks, entry)
+ dump_trunk(vty, trunk);
llist_for_each_entry(trunk, &g_cfg->trunks, entry)
dump_trunk(vty, trunk);
@@ -372,47 +373,21 @@ ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
"Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.")
-DEFUN(cfg_mgcp_sdp_payload_number,
- cfg_mgcp_sdp_payload_number_cmd,
- "sdp audio payload number <1-255>",
- "Set the audio codec to use")
-{
- unsigned int payload = atoi(argv[0]);
- g_cfg->trunk.audio_payload = payload;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_sdp_payload_name,
- cfg_mgcp_sdp_payload_name_cmd,
- "sdp audio payload name NAME",
- "Set the audio name to use")
-{
- bsc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_loop,
- cfg_mgcp_loop_cmd,
- "loop (0|1)",
- "Loop the audio")
-{
- g_cfg->trunk.audio_loop = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_number_endp,
- cfg_mgcp_number_endp_cmd,
+DEFUN(cfg_vtrunk_number_endp,
+ cfg_vtrunk_number_endp_cmd,
"number endpoints <0-65534>",
"The number of endpoints to allocate. This is not dynamic.")
{
- if (g_cfg->trunk.endpoints) {
+ struct mgcp_trunk_config *trunk = vty->index;
+
+ if (trunk->endpoints) {
vty_out(vty, "Can not change size.%s", VTY_NEWLINE);
return CMD_WARNING;
}
/* + 1 as we start counting at one */
- g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
- if (allocate_endpoints(&g_cfg->trunk) != 0) {
+ trunk->number_endpoints = atoi(argv[0]) + 1;
+ if (allocate_endpoints(trunk) != 0) {
vty_out(vty, "Can not allocate endpoints.%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -464,6 +439,27 @@ DEFUN(cfg_mgcp_transcoder_remote_base,
return CMD_SUCCESS;
}
+DEFUN(cfg_mgcp_vtrunk, cfg_mgcp_vtrunk_cmd,
+ "vtrunk NAME",
+ "Configure a Virtual Trunk\n" "Domain Name\n")
+{
+ struct mgcp_trunk_config *trunk;
+
+ trunk = mgcp_trunk_domain(g_cfg, argv[0]);
+ if (!trunk)
+ trunk = mgcp_vtrunk_alloc(g_cfg, argv[0]);
+
+ if (!trunk) {
+ vty_out(vty, "%%Unable to allocate trunk %s.%s",
+ argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->node = VTRUNK_NODE;
+ vty->index = trunk;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
"trunk <1-64>",
"Configure a SS7 trunk\n" "Trunk Nr\n")
@@ -493,19 +489,39 @@ DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
return CMD_SUCCESS;
}
+static void config_write_trunk_common(struct vty *vty,
+ struct mgcp_trunk_config *tcfg)
+{
+ vty_out(vty, " sdp audio payload number %d%s",
+ tcfg->audio_payload, VTY_NEWLINE);
+ vty_out(vty, " sdp audio payload name %s%s",
+ tcfg->audio_name, VTY_NEWLINE);
+ vty_out(vty, " loop %d%s",
+ tcfg->audio_loop, VTY_NEWLINE);
+}
+
static int config_write_trunk(struct vty *vty)
{
struct mgcp_trunk_config *trunk;
llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
- vty_out(vty, " sdp audio payload number %d%s",
- trunk->audio_payload, VTY_NEWLINE);
- vty_out(vty, " sdp audio payload name %s%s",
- trunk->audio_name, VTY_NEWLINE);
- vty_out(vty, " loop %d%s",
- trunk->audio_loop, VTY_NEWLINE);
+ config_write_trunk_common(vty, trunk);
+ mgcp_write_trunk_extra(vty, trunk);
+ }
+
+ return CMD_SUCCESS;
+}
+static int config_write_vtrunk(struct vty *vty)
+{
+ struct mgcp_trunk_config *trunk;
+
+ llist_for_each_entry(trunk, &g_cfg->vtrunks, entry) {
+ vty_out(vty, " vtrunk %s%s", trunk->virtual_domain, VTY_NEWLINE);
+ vty_out(vty, " number endpoints %d%s",
+ trunk->number_endpoints - 1, VTY_NEWLINE);
+ config_write_trunk_common(vty, trunk);
mgcp_write_trunk_extra(vty, trunk);
}
@@ -546,16 +562,21 @@ DEFUN(cfg_trunk_loop,
return CMD_SUCCESS;
}
+#define TRUNK_TYPE_STR "Virtual trunk\nE1 trunk\n"
+#define TRUNK_IDENT_STR "Trunk identifier depending on the type\n"
+
DEFUN(loop_endp,
loop_endp_cmd,
- "loop-endpoint <0-64> NAME (0|1)",
- "Loop a given endpoint\n" "Trunk number\n"
+ "loop-endpoint (virtual|e1) IDENT NAME (0|1)",
+ "Loop a given endpoint\n"
+ TRUNK_TYPE_STR
+ TRUNK_IDENT_STR
"The name in hex of the endpoint\n" "Disable the loop\n" "Enable the loop\n")
{
struct mgcp_trunk_config *trunk;
struct mgcp_endpoint *endp;
- trunk = find_trunk(g_cfg, atoi(argv[0]));
+ trunk = find_trunk(g_cfg, argv[0], argv[1]);
if (!trunk) {
vty_out(vty, "%%Trunk %d not found in the config.%s",
atoi(argv[0]), VTY_NEWLINE);
@@ -568,7 +589,7 @@ DEFUN(loop_endp,
return CMD_WARNING;
}
- int endp_no = strtoul(argv[1], NULL, 16);
+ int endp_no = strtoul(argv[2], NULL, 16);
if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
vty_out(vty, "Loopback number %s/%d is invalid.%s",
argv[1], endp_no, VTY_NEWLINE);
@@ -577,7 +598,7 @@ DEFUN(loop_endp,
endp = &trunk->endpoints[endp_no];
- int loop = atoi(argv[2]);
+ int loop = atoi(argv[3]);
if (loop)
endp->conn_mode = MGCP_CONN_LOOPBACK;
@@ -590,8 +611,10 @@ DEFUN(loop_endp,
DEFUN(tap_call,
tap_call_cmd,
- "tap-call <0-64> ENDPOINT (bts-in|bts-out|net-in|net-out) A.B.C.D <0-65534>",
- "Forward data on endpoint to a different system\n" "Trunk number\n"
+ "tap-call (virtual|e1) IDENT ENDPOINT (bts-in|bts-out|net-in|net-out) A.B.C.D <0-65534>",
+ "Forward data on endpoint to a different system\n"
+ TRUNK_TYPE_STR
+ TRUNK_IDENT_STR
"The endpoint in hex\n"
"Forward the data coming from the bts\n"
"Forward the data coming from the bts leaving to the network\n"
@@ -604,10 +627,10 @@ DEFUN(tap_call,
struct mgcp_endpoint *endp;
int port = 0;
- trunk = find_trunk(g_cfg, atoi(argv[0]));
+ trunk = find_trunk(g_cfg, argv[0], argv[1]);
if (!trunk) {
vty_out(vty, "%%Trunk %d not found in the config.%s",
- atoi(argv[0]), VTY_NEWLINE);
+ atoi(argv[1]), VTY_NEWLINE);
return CMD_WARNING;
}
@@ -617,7 +640,7 @@ DEFUN(tap_call,
return CMD_WARNING;
}
- int endp_no = strtoul(argv[1], NULL, 16);
+ int endp_no = strtoul(argv[2], NULL, 16);
if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
vty_out(vty, "Endpoint number %s/%d is invalid.%s",
argv[1], endp_no, VTY_NEWLINE);
@@ -626,13 +649,13 @@ DEFUN(tap_call,
endp = &trunk->endpoints[endp_no];
- if (strcmp(argv[2], "bts-in") == 0) {
+ if (strcmp(argv[3], "bts-in") == 0) {
port = MGCP_TAP_BTS_IN;
- } else if (strcmp(argv[2], "bts-out") == 0) {
+ } else if (strcmp(argv[3], "bts-out") == 0) {
port = MGCP_TAP_BTS_OUT;
- } else if (strcmp(argv[2], "net-in") == 0) {
+ } else if (strcmp(argv[3], "net-in") == 0) {
port = MGCP_TAP_NET_IN;
- } else if (strcmp(argv[2], "net-out") == 0) {
+ } else if (strcmp(argv[3], "net-out") == 0) {
port = MGCP_TAP_NET_OUT;
} else {
vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
@@ -641,24 +664,26 @@ DEFUN(tap_call,
tap = &endp->taps[port];
memset(&tap->forward, 0, sizeof(tap->forward));
- inet_aton(argv[3], &tap->forward.sin_addr);
- tap->forward.sin_port = htons(atoi(argv[4]));
+ inet_aton(argv[4], &tap->forward.sin_addr);
+ tap->forward.sin_port = htons(atoi(argv[5]));
tap->enabled = 1;
return CMD_SUCCESS;
}
DEFUN(free_endp, free_endp_cmd,
- "free-endpoint <0-64> NUMBER",
- "Free the given endpoint\n" "Trunk number\n"
+ "free-endpoint (virtual|e1) IDENT NUMBER",
+ "Free the given endpoint\n"
+ TRUNK_TYPE_STR
+ TRUNK_IDENT_STR
"Endpoint number in hex.\n")
{
struct mgcp_trunk_config *trunk;
struct mgcp_endpoint *endp;
- trunk = find_trunk(g_cfg, atoi(argv[0]));
+ trunk = find_trunk(g_cfg, argv[0], argv[1]);
if (!trunk) {
vty_out(vty, "%%Trunk %d not found in the config.%s",
- atoi(argv[0]), VTY_NEWLINE);
+ atoi(argv[1]), VTY_NEWLINE);
return CMD_WARNING;
}
@@ -668,7 +693,7 @@ DEFUN(free_endp, free_endp_cmd,
return CMD_WARNING;
}
- int endp_no = strtoul(argv[1], NULL, 16);
+ int endp_no = strtoul(argv[2], NULL, 16);
if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
vty_out(vty, "Endpoint number %s/%d is invalid.%s",
argv[1], endp_no, VTY_NEWLINE);
@@ -711,10 +736,16 @@ int mgcp_vty_init(void)
install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd);
install_element(MGCP_NODE, &cfg_mgcp_no_transcoder_cmd);
install_element(MGCP_NODE, &cfg_mgcp_transcoder_remote_base_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
+
+ install_element(MGCP_NODE, &cfg_mgcp_vtrunk_cmd);
+ install_node(&vtrunk_node, config_write_vtrunk);
+ install_default(VTRUNK_NODE);
+ install_element(VTRUNK_NODE, &ournode_exit_cmd);
+ install_element(VTRUNK_NODE, &ournode_end_cmd);
+ install_element(VTRUNK_NODE, &cfg_vtrunk_number_endp_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_payload_number_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_payload_name_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_loop_cmd);
install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
install_node(&trunk_node, config_write_trunk);
@@ -821,9 +852,12 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
g_cfg->last_bts_port = rtp_calculate_port(0, g_cfg->bts_ports.base_port);
g_cfg->last_net_port = rtp_calculate_port(0, g_cfg->net_ports.base_port);
- if (configure_endpoints(&g_cfg->trunk) != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to initialize the virtual trunk.\n");
- return -1;
+ llist_for_each_entry(trunk, &g_cfg->vtrunks, entry) {
+ if (configure_endpoints(trunk) != 0) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Failed to initialize virtual trunk %s.\n", trunk->virtual_domain);
+ return -1;
+ }
}
llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
diff --git a/src/mgcp_ss7.c b/src/mgcp_ss7.c
index 4e2b803..745f312 100644
--- a/src/mgcp_ss7.c
+++ b/src/mgcp_ss7.c
@@ -700,7 +700,7 @@ static int configure_trunk(struct mgcp_trunk_config *tcfg, int *dsp_resource)
static struct mgcp_ss7 *mgcp_ss7_init(struct mgcp_config *cfg)
{
struct mgcp_trunk_config *trunk;
- int dsp_resource, i;
+ int dsp_resource;
struct mgcp_ss7 *conf = talloc_zero(NULL, struct mgcp_ss7);
if (!conf)
@@ -731,8 +731,8 @@ static struct mgcp_ss7 *mgcp_ss7_init(struct mgcp_config *cfg)
/* Now do the init of the trunks */
dsp_resource = 0;
- for (i = 1; i < cfg->trunk.number_endpoints; ++i) {
- if (configure_trunk(&cfg->trunk, &dsp_resource) != 0) {
+ llist_for_each_entry(trunk, &cfg->vtrunks, entry) {
+ if (configure_trunk(trunk, &dsp_resource) != 0) {
talloc_free(conf);
return NULL;
}
@@ -780,8 +780,9 @@ void mgcp_ss7_reset(struct mgcp_ss7 *mgcp)
LOGP(DMGCP, LOGL_INFO, "Resetting all endpoints.\n");
/* free UniPorte and MGCP data */
- free_trunk(&mgcp->cfg->trunk);
+ llist_for_each_entry(trunk, &mgcp->cfg->vtrunks, entry)
+ free_trunk(trunk);
llist_for_each_entry(trunk, &mgcp->cfg->trunks, entry)
free_trunk(trunk);
}
diff --git a/src/mgcp_ss7_vty.c b/src/mgcp_ss7_vty.c
index e9c79dc..7020405 100644
--- a/src/mgcp_ss7_vty.c
+++ b/src/mgcp_ss7_vty.c
@@ -46,160 +46,27 @@ DEFUN(cfg_mgcp_configure, cfg_mgcp_configure_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_mgcp_vad, cfg_mgcp_vad_cmd,
- "vad (enabled|disabled)",
- "Enable the Voice Activity Detection\n"
- "Enable\n" "Disable\n")
-{
- if (argv[0][0] == 'e')
- g_cfg->trunk.vad_enabled = 1;
- else
- g_cfg->trunk.vad_enabled = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_realloc, cfg_mgcp_realloc_cmd,
- "force-realloc (0|1)",
- "Force the reallocation of an endpoint\n"
- "Disable\n" "Enable\n")
-{
- g_cfg->trunk.force_realloc = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_inp_dig_gain, cfg_mgcp_inp_dig_gain_cmd,
- "input-digital-gain <0-62>",
- "Static Digital Input Gain\n"
- "Gain value")
-{
- g_cfg->trunk.digital_inp_gain = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_out_dig_gain, cfg_mgcp_out_dig_gain_cmd,
- "outut-digital-gain <0-62>",
- "Static Digital Output Gain\n"
- "Gain value")
-{
- g_cfg->trunk.digital_out_gain = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_upstr_agc, cfg_mgcp_upstr_agc_cmd,
- "upstream-automatic-gain (0|1)",
- "Enable automatic gain control on upstream\n"
- "Disable\n" "Enabled\n")
-{
- g_cfg->trunk.upstr_agc_enbl = argv[0][0] == '1';
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgc_upstr_adp, cfg_mgcp_upstr_adp_cmd,
- "upstream-adaptiton-rate <1-128>",
- "Set the adaption rate in (dB/sec) * 10\n"
- "Range\n")
-{
- g_cfg->trunk.upstr_adp_rate = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_upstr_max_gain, cfg_mgcp_upstr_max_gain_cmd,
- "upstream-max-applied-gain <0-49>",
- "Maximum applied gain from -31db to 18db\n"
- "Gain level\n")
-{
- g_cfg->trunk.upstr_max_gain = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_upstr_target, cfg_mgcp_upstr_target_cmd,
- "upstream-target-level <6-37>",
- "Set the desired level in db\n"
- "Desired lievel\n")
-{
- g_cfg->trunk.upstr_target_lvl = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_dwnstr_agc, cfg_mgcp_dwnstr_agc_cmd,
- "downstream-automatic-gain (0|1)",
- "Enable automatic gain control on downstream\n"
- "Disable\n" "Enabled\n")
-{
- g_cfg->trunk.dwnstr_agc_enbl = argv[0][0] == '1';
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgc_dwnstr_adp, cfg_mgcp_dwnstr_adp_cmd,
- "downstream-adaptation-rate <1-128>",
- "Set the adaption rate in (dB/sec) * 10\n"
- "Range\n")
-{
- g_cfg->trunk.dwnstr_adp_rate = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_dwnstr_max_gain, cfg_mgcp_dwnstr_max_gain_cmd,
- "downstream-max-applied-gain <0-49>",
- "Maximum applied gain from -31db to 18db\n"
- "Gain level\n")
-{
- g_cfg->trunk.dwnstr_max_gain = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_dwnstr_target, cfg_mgcp_dwnstr_target_cmd,
- "downstream-target-level <6-37>",
- "Set the desired level in db\n"
- "Desired lievel\n")
-{
- g_cfg->trunk.dwnstr_target_lvl = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(cfg_mgcp_endp_offset, cfg_mgcp_endp_offset_cmd,
- "endpoint-offset <-60-60>",
- "Offset to the CIC map\n" "Value to set\n")
-{
- vty_out(vty, "%%endpoint-offset is not used anymore.%s", VTY_NEWLINE);
- return CMD_WARNING;
-}
-
-DEFUN(cfg_mgcp_target_trunk, cfg_mgcp_target_trunk_cmd,
+DEFUN(cfg_vtrunk_target_trunk, cfg_vtrunk_target_trunk_cmd,
"target-trunk-start <1-24>",
"Map the virtual trunk to start here\n" "Trunk Nr\n")
{
- g_cfg->trunk.target_trunk_start = atoi(argv[0]);
+ struct mgcp_trunk_config *trunk = vty->index;
+ trunk->target_trunk_start = atoi(argv[0]);
return CMD_SUCCESS;
}
#define ENDP_BLOCK_STR "Block the Endpoint/Timeslot for Audio\n"
-DEFUN(cfg_mgcp_timeslot_block, cfg_mgcp_timeslot_block_cmd,
- "block-endpoint <1-65534>",
- ENDP_BLOCK_STR "Endpoint number\n")
-{
- int nr = atoi(argv[0]);
-
- if (g_cfg->trunk.number_endpoints <= nr) {
- vty_out(vty, "%%Endpoint %d too big. Current size: %d%s",
- nr, g_cfg->trunk.number_endpoints, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- g_cfg->trunk.endpoints[nr].blocked = 1;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_block_defaults, cfg_mgcp_block_defaults_cmd,
+DEFUN(cfg_vtrunk_block_defaults, cfg_vtrunk_block_defaults_cmd,
"block-defaults",
"Block the default endpoints 0x0 and 0x1F\n")
{
int i;
+ struct mgcp_trunk_config *trunk = vty->index;
- for (i = 1; i < g_cfg->trunk.number_endpoints; ++i) {
+ for (i = 1; i < trunk->number_endpoints; ++i) {
int multiplex, timeslot;
- struct mgcp_endpoint *endp = &g_cfg->trunk.endpoints[i];
+ struct mgcp_endpoint *endp = &trunk->endpoints[i];
mgcp_endpoint_to_timeslot(ENDPOINT_NUMBER(endp), &multiplex, &timeslot);
if (timeslot == 0x0 || timeslot == 0x1F)
@@ -357,10 +224,23 @@ DEFUN(cfg_trunk_timeslot_block, cfg_trunk_timeslot_block_cmd,
ENDP_BLOCK_STR "Endpoint number\n")
{
struct mgcp_trunk_config *trunk = vty->index;
+ int no = atoi(argv[0]);
+
+ if (no <= 0 || no >= trunk->number_endpoints) {
+ vty_out(vty, "%%Endpoint does not fit: %d.%s", no, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
trunk->endpoints[atoi(argv[0])].blocked = 1;
return CMD_SUCCESS;
}
+void mgcp_write_extra(struct vty *vty, struct mgcp_config *cfg)
+{
+ vty_out(vty, " configure-trunks %d%s",
+ cfg->configure_trunks, VTY_NEWLINE);
+}
+
static void write_blocked_endpoints(struct vty *vty,
struct mgcp_trunk_config *tcfg)
{
@@ -374,40 +254,7 @@ static void write_blocked_endpoints(struct vty *vty,
}
}
-void mgcp_write_extra(struct vty *vty, struct mgcp_config *cfg)
-{
- vty_out(vty, " configure-trunks %d%s",
- cfg->configure_trunks, VTY_NEWLINE);
- vty_out(vty, " force-realloc %d%s",
- cfg->trunk.force_realloc, VTY_NEWLINE);
- vty_out(vty, " vad %s%s",
- cfg->trunk.vad_enabled ? "enabled" : "disabled", VTY_NEWLINE);
- vty_out(vty, " input-digital-gain %d%s",
- cfg->trunk.digital_inp_gain, VTY_NEWLINE);
- vty_out(vty, " output-digital-gain %d%s",
- cfg->trunk.digital_out_gain, VTY_NEWLINE);
- vty_out(vty, " upstream-automatic-gain %d%s",
- cfg->trunk.upstr_agc_enbl, VTY_NEWLINE);
- vty_out(vty, " upstream-adaptation-rate %d%s",
- cfg->trunk.upstr_adp_rate, VTY_NEWLINE);
- vty_out(vty, " upstream-max-applied-gain %d%s",
- cfg->trunk.upstr_max_gain, VTY_NEWLINE);
- vty_out(vty, " upstream-target-level %d%s",
- cfg->trunk.upstr_target_lvl, VTY_NEWLINE);
- vty_out(vty, " downstream-automatic-gain %d%s",
- cfg->trunk.dwnstr_agc_enbl, VTY_NEWLINE);
- vty_out(vty, " downstream-adaptation-rate %d%s",
- cfg->trunk.dwnstr_adp_rate, VTY_NEWLINE);
- vty_out(vty, " downstream-max-applied-gain %d%s",
- cfg->trunk.dwnstr_max_gain, VTY_NEWLINE);
- vty_out(vty, " downstream-target-level %d%s",
- cfg->trunk.dwnstr_target_lvl, VTY_NEWLINE);
- vty_out(vty, " target-trunk-start %d%s",
- cfg->trunk.target_trunk_start, VTY_NEWLINE);
- write_blocked_endpoints(vty, &cfg->trunk);
-}
-
-void mgcp_write_trunk_extra(struct vty *vty, struct mgcp_trunk_config *trunk)
+void write_trunk_extra(struct vty *vty, struct mgcp_trunk_config *trunk)
{
vty_out(vty, " force-realloc %d%s",
trunk->force_realloc, VTY_NEWLINE);
@@ -436,6 +283,18 @@ void mgcp_write_trunk_extra(struct vty *vty, struct mgcp_trunk_config *trunk)
write_blocked_endpoints(vty, trunk);
}
+void mgcp_write_trunk_extra(struct vty *vty, struct mgcp_trunk_config *trunk)
+{
+ write_trunk_extra(vty, trunk);
+}
+
+void mgcp_write_vtrunk_extra(struct vty *vty, struct mgcp_trunk_config *trunk)
+{
+ vty_out(vty, " target-trunk-start %d%s",
+ trunk->target_trunk_start, VTY_NEWLINE);
+ write_trunk_extra(vty, trunk);
+}
+
void mgcp_mgw_vty_init(void)
{
@@ -445,22 +304,23 @@ void mgcp_mgw_vty_init(void)
mgcp_vty_init();
install_element(MGCP_NODE, &cfg_mgcp_configure_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_vad_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_realloc_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_inp_dig_gain_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_out_dig_gain_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_upstr_agc_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_upstr_adp_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_upstr_max_gain_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_upstr_target_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_dwnstr_agc_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_dwnstr_adp_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_dwnstr_max_gain_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_dwnstr_target_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_endp_offset_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_target_trunk_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_timeslot_block_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_block_defaults_cmd);
+
+ install_element(VTRUNK_NODE, &cfg_vtrunk_target_trunk_cmd);
+ install_element(VTRUNK_NODE, &cfg_vtrunk_block_defaults_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_vad_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_realloc_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_inp_dig_gain_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_out_dig_gain_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_upstr_agc_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_upstr_adp_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_upstr_max_gain_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_upstr_target_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_dwnstr_agc_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_dwnstr_adp_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_dwnstr_max_gain_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_dwnstr_target_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_endp_offset_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_timeslot_block_cmd);
install_element(TRUNK_NODE, &cfg_trunk_vad_cmd);
install_element(TRUNK_NODE, &cfg_trunk_realloc_cmd);