From 20e56c9d36b76efb153ce2d694e09e16547f525e Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Fri, 6 Nov 2009 22:32:17 +0000 Subject: Created standard location to add options to chan_dahdi for ISDN dialing. Dial(DAHDI/g1[/extension[/options]]) Current options: K() R Reverse charging indication (Collect calls) The earlier Dial(DAHDI/g1[/K][/extension] format was variable and did not allow for the easy addition of more options. The earlier 'C' prefix character for reverse charge indiation would conflict with the a-d DTMF digits if ISDN uses them. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@228691 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 16 +++++-- channels/chan_dahdi.c | 41 +++++++++------- channels/sig_pri.c | 127 ++++++++++++++++++++++---------------------------- 3 files changed, 92 insertions(+), 92 deletions(-) diff --git a/CHANGES b/CHANGES index f18e918d8..cba56f900 100644 --- a/CHANGES +++ b/CHANGES @@ -228,8 +228,6 @@ libpri channel driver (chan_dahdi) DAHDI changes dialing the redirected-to party. You still have to set the REDIRECTING(to-xxx,i) and the REDIRECTING(from-xxx,i) values. The call will update the redirecting-to presentation (COLR) when it becomes available. - * Added Reverse Charging Indication receipt & transmission (requires latest - LibPRI). * Added the ability to ignore calls that are not in a Multiple Subscriber Number (MSN) list for PTMP CPE interfaces. * Added dynamic range compression support for dahdi channels. It is @@ -243,9 +241,21 @@ libpri channel driver (chan_dahdi) DAHDI changes Will reroute/deflect an outgoing call when receive the message. Can use the DAHDISendCallreroutingFacility to send the message for the supported switches. + * Added standard location to add options to chan_dahdi dialing: + Dial(DAHDI/g1[/extension[/options]]) + Current options: + K() + R Reverse charging indication + * Added Reverse Charging Indication (Collect calls) send/receive option. + Send reverse charging in SETUP message with the chan_dahdi R dialing option. + Dial(DAHDI/g1/extension/R) + Access received reverse charge in SETUP message by: ${CHANNEL(reversecharge)} + (requires latest LibPRI) * Added ability to send/receive keypad digits in the SETUP message. - Send keypad digits in SETUP message: Dial(DAHDI/g1[/K][/extension]) + Send keypad digits in SETUP message with the chan_dahdi K() + dialing option. Dial(DAHDI/g1/[extension]/K()) Access any received keypad digits in SETUP message by: ${CHANNEL(keypad_digits)} + (requires latest LibPRI) Asterisk Manager Interface -------------------------- diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 32344f77e..e71f2ed91 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -12000,7 +12000,7 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons int unavailreason = 0; struct dahdi_pvt *p; struct ast_channel *tmp = NULL; - char *dest=NULL; + char *dest; int x; char *s; char opt=0; @@ -12009,12 +12009,18 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons struct dahdi_pvt *exitpvt; int channelmatched = 0; int groupmatched = 0; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(group); /* channel/group token */ + //AST_APP_ARG(ext); /* extension token */ + //AST_APP_ARG(opts); /* options token */ + AST_APP_ARG(other); /* Any remining unused arguments */ + ); /* * data is ---v - * Dial(DAHDI/pseudo[/extension]) - * Dial(DAHDI/[c|r|d][/extension]) - * Dial(DAHDI/(g|G|r|R)[c|r|d][/extension]) + * Dial(DAHDI/pseudo[/extension[/options]]) + * Dial(DAHDI/[c|r|d][/extension[/options]]) + * Dial(DAHDI/(g|G|r|R)[c|r|d][/extension[/options]]) * * g - channel group allocation search forward * G - channel group allocation search backward @@ -12032,12 +12038,15 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons ast_log(LOG_WARNING, "Channel requested with no data\n"); return NULL; } - if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { - /* Retrieve the group number */ - char *stringp; + AST_NONSTANDARD_APP_ARGS(args, dest, '/'); + if (!args.argc || ast_strlen_zero(args.group)) { + ast_log(LOG_WARNING, "No channel/group specified\n"); + return NULL; + } - stringp = dest + 1; - s = strsep(&stringp, "/"); + if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') { + /* Retrieve the group number */ + s = args.group + 1; if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) { ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); return NULL; @@ -12047,14 +12056,14 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons /* Lock the interface list */ ast_mutex_lock(&iflock); - if (toupper(dest[0]) == 'G') { - if (dest[0] == 'G') { + if (toupper(args.group[0]) == 'G') { + if (args.group[0] == 'G') { backwards = 1; p = ifend; } else p = iflist; } else { - if (dest[0] == 'R') { + if (args.group[0] == 'R') { backwards = 1; p = round_robin[x]?round_robin[x]->prev:ifend; if (!p) @@ -12067,16 +12076,12 @@ static struct ast_channel *dahdi_request(const char *type, format_t format, cons roundrobin = 1; } } else { - char *stringp; - - stringp = dest; - s = strsep(&stringp, "/"); + s = args.group; if (!strcasecmp(s, "pseudo")) { /* Special case for pseudo */ x = CHAN_PSEUDO; channelmatch = x; - } - else if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) { + } else if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) { ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); return NULL; } else { diff --git a/channels/sig_pri.c b/channels/sig_pri.c index ee4f9353d..99be5a49b 100644 --- a/channels/sig_pri.c +++ b/channels/sig_pri.c @@ -35,6 +35,7 @@ #include "asterisk/utils.h" #include "asterisk/options.h" #include "asterisk/pbx.h" +#include "asterisk/app.h" #include "asterisk/file.h" #include "asterisk/callerid.h" #include "asterisk/say.h" @@ -3267,38 +3268,22 @@ void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdes char *dial; char *number; char *subaddr; - - /* Get private copy of dial string. */ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(group); /* channel/group token */ + AST_APP_ARG(ext); /* extension token */ + //AST_APP_ARG(opts); /* options token */ + AST_APP_ARG(other); /* Any remining unused arguments */ + ); + + /* Get private copy of dial string and break it up. */ dial = ast_strdupa(rdest); + AST_NONSTANDARD_APP_ARGS(args, dial, '/'); - /* Skip channel selection section. */ - number = strchr(dial, '/'); - if (number) { - ++number; - } else { + number = args.ext; + if (!number) { number = ""; } -#if defined(HAVE_PRI_SETUP_KEYPAD) - /* - * v--- number points here - * /[K/]extension - */ - if (number[0] == 'K') { - /* Skip the keypad facility digits. */ - number = strchr(number + 1, '/'); - if (number) { - ++number; - } else { - number = ""; - } - } - /* - * v--- number points here - * /extension - */ -#endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ - /* Find and extract dialed_subaddress */ subaddr = strchr(number, ':'); if (subaddr) { @@ -3337,6 +3322,22 @@ void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdes } } +enum SIG_PRI_CALL_OPT_FLAGS { + OPT_KEYPAD = (1 << 0), + OPT_REVERSE_CHARGE = (1 << 1), /* Collect call */ +}; +enum SIG_PRI_CALL_OPT_ARGS { + OPT_ARG_KEYPAD = 0, + + /* note: this entry _MUST_ be the last one in the enum */ + OPT_ARG_ARRAY_SIZE, +}; + +AST_APP_OPTIONS(sig_pri_call_opts, BEGIN_OPTIONS + AST_APP_OPTION_ARG('K', OPT_KEYPAD, OPT_ARG_KEYPAD), + AST_APP_OPTION('R', OPT_REVERSE_CHARGE), +END_OPTIONS); + /*! \note Parsing must remain in sync with sig_pri_extract_called_num_subaddr(). */ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1) { @@ -3355,6 +3356,14 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, i #if defined(HAVE_PRI_SETUP_KEYPAD) const char *keypad; #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(group); /* channel/group token */ + AST_APP_ARG(ext); /* extension token */ + AST_APP_ARG(opts); /* options token */ + AST_APP_ARG(other); /* Any remining unused arguments */ + ); + struct ast_flags opts; + char *opt_args[OPT_ARG_ARRAY_SIZE]; ast_log(LOG_DEBUG, "CALLING CID_NAME: %s CID_NUM:: %s\n", ast->cid.cid_name, ast->cid.cid_num); @@ -3368,45 +3377,20 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, i return -1; } - ast_copy_string(dest, rdest, sizeof(dest)); - p->dialdest[0] = '\0'; p->outgoing = 1; - c = strchr(dest, '/'); - if (c) { - c++; - } else { - c = ""; + ast_copy_string(dest, rdest, sizeof(dest)); + AST_NONSTANDARD_APP_ARGS(args, dest, '/'); + if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) { + /* General invalid option syntax. */ + return -1; } -#if defined(HAVE_PRI_SETUP_KEYPAD) - /* - * v--- c points here - * /[K/]extension - */ - if (c[0] == 'K') { - /* Extract the keypad facility digits. */ - keypad = c + 1; - c = strchr(keypad, '/'); - if (c) { - /* Terminate the keypad facility digits. */ - *c++ = '\0'; - } else { - c = ""; - } - if (ast_strlen_zero(keypad)) { - /* What no keypad digits? */ - keypad = NULL; - } - } else { - keypad = NULL; + c = args.ext; + if (!c) { + c = ""; } - /* - * v--- c points here - * /extension - */ -#endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ /* setup dialed_subaddress if found */ ast_party_subaddress_init(&dialed_subaddress); @@ -3545,16 +3529,6 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, i case 'r': pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); break; -#if defined(HAVE_PRI_REVERSE_CHARGE) - case 'C': - pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); - break; -#endif -#if defined(HAVE_PRI_SETUP_KEYPAD) - case 'K': - /* Reserve this letter for keypad facility digits. */ - break; -#endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ default: if (isalpha(c[p->stripmsd])) { ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", @@ -3565,8 +3539,13 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, i c++; } #if defined(HAVE_PRI_SETUP_KEYPAD) - if (keypad) { + if (ast_test_flag(&opts, OPT_KEYPAD) + && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) { + /* We have a keypad facility digits option with digits. */ + keypad = opt_args[OPT_ARG_KEYPAD]; pri_sr_set_keypad_digits(sr, keypad); + } else { + keypad = NULL; } if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip)) #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ @@ -3584,6 +3563,12 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, i } #endif /* defined(HAVE_PRI_SUBADDR) */ +#if defined(HAVE_PRI_REVERSE_CHARGE) + if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) { + pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); + } +#endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ + ldp_strip = 0; prilocaldialplan = p->pri->localdialplan - 1; if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ -- cgit v1.2.3