mgcp: Introduce multiple virtual trunks
A virtual trunk is identified by a virtual domain name.zecke/mgcp-merge
parent
96cc57af80
commit
f574cec745
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
enum ss7_vty_node {
|
||||
MGCP_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||
TRUNK_NODE,
|
||||
VTRUNK_NODE,
|
||||
CELLMGR_NODE,
|
||||
SS7_NODE,
|
||||
LINKSETS_NODE,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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, ×lot);
|
||||
|
||||
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);
|
||||
|
|
Reference in New Issue