9
0
Fork 0

mgcp: Introduce multiple virtual trunks

A virtual trunk is identified by a virtual domain name.
This commit is contained in:
Holger Hans Peter Freyther 2011-09-14 19:14:54 +02:00
parent 96cc57af80
commit f574cec745
7 changed files with 236 additions and 283 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -28,6 +28,7 @@
enum ss7_vty_node {
MGCP_NODE = _LAST_OSMOVTY_NODE + 1,
TRUNK_NODE,
VTRUNK_NODE,
CELLMGR_NODE,
SS7_NODE,
LINKSETS_NODE,

View File

@ -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) {

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);