diff options
author | crichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-05-08 15:07:37 +0000 |
---|---|---|
committer | crichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-05-08 15:07:37 +0000 |
commit | 4c974b0078f4509e584ea5e61e4887f9545b4190 (patch) | |
tree | 9040dfc7d5ab953b81222d3b208e5501fe473b31 /channels/chan_misdn.c | |
parent | b670645e9bc561f66e4039780047adfaa2fa19c9 (diff) |
added application misdn_check_l2l1 which tries to pull up the L1/L2 on all ports that have the layers down in a group. It waits then for a timeout. This helps for scenarios where multiple PMP BRIs are grouped together, or where a provider has a faulty PTP Implementation, that looses the L2 after a while.
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@63402 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r-- | channels/chan_misdn.c | 123 |
1 files changed, 116 insertions, 7 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index 3b5b4eae0..02e3a5c53 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -320,6 +320,7 @@ static int start_bc_tones(struct chan_list *cl); static int stop_bc_tones(struct chan_list *cl); static void release_chan(struct misdn_bchannel *bc); +static int misdn_check_l2l1(struct ast_channel *chan, void *data); static int misdn_set_opt_exec(struct ast_channel *chan, void *data); static int misdn_facility_exec(struct ast_channel *chan, void *data); @@ -2684,8 +2685,6 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat } } while (!newbc && robin_channel != rr->channel); - if (!newbc) - chan_misdn_log(-1, port, " Failed! No free channel in group %d!", group); } else { for (port=misdn_cfg_get_next_port(0); port > 0; port=misdn_cfg_get_next_port(port)) { @@ -2709,16 +2708,27 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat } } } - } else { + + /* Group dial failed ?*/ + if (!newbc) { + ast_log(LOG_WARNING, + "Could not Dial out on group '%s'.\n" + "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" + "\tOr there was no free channel on none of the ports\n\n" + , group); + return NULL; + } + } else { /* 'Normal' Port dial * Port dial */ if (channel) chan_misdn_log(1, port," --> preselected_channel: %d\n",channel); newbc = misdn_lib_get_free_bc(port, channel, 0, dec); + + if (!newbc) { + ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n",port,ext); + return NULL; + } } - if (!newbc) { - chan_misdn_log(-1, 0, "Could not create channel on port:%d with extensions:%s\n",port,ext); - return NULL; - } /* create ast_channel and link all the objects together */ cl->bc=newbc; @@ -4396,6 +4406,24 @@ int load_module(void) ); + ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", + "misdn_check_l2l1(<port>||g:<groupname>,timeout)" + "Checks if the L2 and L1 are up on either the given <port> or\n" + "on the ports in the group with <groupname>\n" + "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" + "for <timeout> seconds that this happens. Otherwise, nothing happens\n" + "\n" + "This application, ensures the L1/L2 state of the Ports in a group\n" + "it is intended to make the pmp_l1_check option redundant and to\n" + "fix a buggy switch config from your provider\n" + "\n" + "a sample dialplan would look like:\n\n" + "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" + "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" + "\n" + ); + + misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n"); @@ -4438,6 +4466,7 @@ int unload_module(void) /* ast_unregister_application("misdn_crypt"); */ ast_unregister_application("misdn_set_opt"); ast_unregister_application("misdn_facility"); + ast_unregister_application("misdn_check_l2l1"); ast_channel_unregister(&misdn_tech); @@ -4526,6 +4555,86 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data) } +static int misdn_check_l2l1(struct ast_channel *chan, void *data) +{ + if (strcasecmp(chan->tech->type,"mISDN")) { + ast_log(LOG_WARNING, "misdn_check_l2l1 makes only sense with chan_misdn channels!\n"); + return -1; + } + + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(grouppar); + AST_APP_ARG(timeout); + ); + + if (ast_strlen_zero((char *)data)) { + ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); + return -1; + } + + AST_STANDARD_APP_ARGS(args, data); + + if (args.argc != 2) { + ast_log(LOG_WARNING, "Wrong argument count\n"); + return 0; + } + + /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ + char group[BUFFERSIZE+1]; + char *port_str; + + int port=0; + int timeout=atoi(args.timeout); + int dowait=0; + + port_str=args.grouppar; + + int port_up; + if (port_str[0]=='g' && port_str[1]==':' ) { + /* We make a group call lets checkout which ports are in my group */ + port_str += 2; + strncpy(group, port_str, BUFFERSIZE); + group[BUFFERSIZE-1] = 0; + chan_misdn_log(2, 0, "Checking Ports in group: %s\n",group); + + for ( port = misdn_cfg_get_next_port(port); + port > 0; + port = misdn_cfg_get_next_port(port)) { + + chan_misdn_log(2,0,"trying port %d\n",port); + + char cfg_group[BUFFERSIZE+1]; + misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); + + if (!strcasecmp(cfg_group, group)) { + port_up = misdn_lib_port_up(port, 1); + + if (!port_up) { + chan_misdn_log(2, 0, " --> port '%d'\n", port); + misdn_lib_get_port_up(port); + dowait=1; + } + } + } + + } else { + port = atoi(port_str); + chan_misdn_log(2, 0, "Checking Port: %d\n",port); + port_up = misdn_lib_port_up(port, 1); + if (!port_up) { + misdn_lib_get_port_up(port); + dowait=1; + } + + } + + if (dowait) { + chan_misdn_log(2, 0, "Waiting for '%d' seconds\n",timeout); + sleep(timeout); + } + + return 0; +} static int misdn_set_opt_exec(struct ast_channel *chan, void *data) { |