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, ×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);