diff options
-rw-r--r-- | CHANGES | 33 | ||||
-rw-r--r-- | configs/dundi.conf.sample | 21 | ||||
-rw-r--r-- | pbx/pbx_dundi.c | 38 |
3 files changed, 71 insertions, 21 deletions
@@ -6,10 +6,8 @@ Miscellaneous ------------- * Added the bindaddr option to gtalk.conf. - * Added the ability to specify arguments to the Dial application when using - the DUNDi switch in the dialplan. * Added the ability to customize which sound files are used for some of the - prompts within the Voicemail application by changing them in voicemail.conf + prompts within the Voicemail application by changing them in voicemail.conf * Argument support for Gosub application * Ability to set process limits without restarting Asterisk * SS7 support in chan_zap (via libss7 library) @@ -85,7 +83,7 @@ Dialplan functions ------------------ * Added the DEVSTATE() dialplan function which allows retrieving any device state in the dialplan, as well as creating custom device states that are - controllable from the dialplan. + controllable from the dialplan. * Extend CALLERID() function with "pres" and "ton" parameters to fetch string representation of calling number presentation indicator and numeric representation of type of calling number value. @@ -100,18 +98,27 @@ SIP changes ----------- * The default SIP useragent= identifier now includes the Asterisk version * A new option, match_auth_username in sip.conf changes the matching of incoming requests. - If set, and the incoming request carries authentication info, - the username to match in the users list is taken from the Digest header - rather than from the From: field. This feature is considered experimental. + If set, and the incoming request carries authentication info, + the username to match in the users list is taken from the Digest header + rather than from the From: field. This feature is considered experimental. * The "musiconhold" and "musicclass" settings in sip.conf are now removed, - since they where replaced by "mohsuggest" and "mohinterpret" in version 1.4 + since they where replaced by "mohsuggest" and "mohinterpret" in version 1.4 * The "localmask" setting was removed in version 1.2 and the reminder about it - being removed is now also removed. + being removed is now also removed. * A new option "busy-level" for setting a level of calls where asterisk reports - a device as busy, to separate it from call-limit + a device as busy, to separate it from call-limit * A new realtime family called "sipregs" is now supported to store SIP registration - data. If this family is defined, "sippeers" will be used for configuration and - "sipregs" for registrations. If it's not defined, "sippeers" will be used for - registration data, as before. + data. If this family is defined, "sippeers" will be used for configuration and + "sipregs" for registrations. If it's not defined, "sippeers" will be used for + registration data, as before. * The SIPPEER function have new options for port address, call and pickup groups * Added support for T.140 realtime text in SIP/RTP + +DUNDi changes +------------- + * Added the ability to specify arguments to the Dial application when using + the DUNDi switch in the dialplan. + * Added the ability to set weights for responses dynamically. This can be + done using a global variable or a dialplan function. Using the SHELL() + function would allow you to have an external script set the weight for + each response. diff --git a/configs/dundi.conf.sample b/configs/dundi.conf.sample index a1e999726..4b7f15617 100644 --- a/configs/dundi.conf.sample +++ b/configs/dundi.conf.sample @@ -125,8 +125,27 @@ autokill=yes ;digexten => default,0,IAX2,guest@lappy/${NUMBER} ;asdf => - ; +; Weights for mappings can be set a few different ways: +; +; 1) It can be set as a static number. +;testmap1 => context1,222,IAX2,guest@peer1/${NUMBER} +; +; 2) It can be an Asterisk global variable. +;testmap2 => context2,${DUNDITESTVAR},IAX2,guest@peer2${NUMBER} +; +; 3) It can be retrieved using a dialplan function. This can be extremely +; useful if you want to let an external script decide what the weight +; in a response shouuld be. +;testmap3 => context3,${SHELL(echo 123)},IAX2,guest@peer3/${NUMBER} +; +; Note than when using a global variable or dialplan function to set the +; weight for a mapping, that response caching should be disabled if you +; plan for these values to change frequently at all. If the results are +; cached, then any change in value will not take effect until the cache +; has expired. +; + ; ; The remaining sections represent the peers ; that we fundamentally trust. The section name diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c index 62c2c558b..21a06a079 100644 --- a/pbx/pbx_dundi.c +++ b/pbx/pbx_dundi.c @@ -79,6 +79,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define MAX_PACKET_SIZE 8192 +#define MAX_WEIGHT 59999 + #define DUNDI_MODEL_INBOUND (1 << 0) #define DUNDI_MODEL_OUTBOUND (1 << 1) #define DUNDI_MODEL_SYMMETRIC (DUNDI_MODEL_INBOUND | DUNDI_MODEL_OUTBOUND) @@ -211,7 +213,8 @@ struct dundi_request { struct dundi_mapping { char dcontext[AST_MAX_EXTENSION]; char lcontext[AST_MAX_EXTENSION]; - int weight; + int _weight; + char *weightstr; int options; int tech; int dead; @@ -511,6 +514,19 @@ struct dundi_query_state { char fluffy[0]; }; +static int get_mapping_weight(struct dundi_mapping *map) +{ + char buf[32] = ""; + + if (map->weightstr) { + pbx_substitute_variables_helper(NULL, map->weightstr, buf, sizeof(buf) - 1); + if (sscanf(buf, "%d", &map->_weight) != 1) + map->_weight = MAX_WEIGHT; + } + + return map->_weight; +} + static int dundi_lookup_local(struct dundi_result *dr, struct dundi_mapping *map, char *called_number, dundi_eid *us_eid, int anscnt, struct dundi_hint_metadata *hmd) { struct ast_flags flags = {0}; @@ -539,7 +555,7 @@ static int dundi_lookup_local(struct dundi_result *dr, struct dundi_mapping *map ast_set_flag(&flags, map->options & 0xffff); ast_copy_flags(dr + anscnt, &flags, AST_FLAGS_ALL); dr[anscnt].techint = map->tech; - dr[anscnt].weight = map->weight; + dr[anscnt].weight = get_mapping_weight(map); dr[anscnt].expiration = dundi_cache_time; ast_copy_string(dr[anscnt].tech, tech2str(map->tech), sizeof(dr[anscnt].tech)); dr[anscnt].eid = *us_eid; @@ -2591,15 +2607,17 @@ static int dundi_show_requests(int fd, int argc, char *argv[]) static int dundi_show_mappings(int fd, int argc, char *argv[]) { #define FORMAT2 "%-12.12s %-7.7s %-12.12s %-10.10s %-5.5s %-25.25s\n" -#define FORMAT "%-12.12s %-7d %-12.12s %-10.10s %-5.5s %-25.25s\n" +#define FORMAT "%-12.12s %-7s %-12.12s %-10.10s %-5.5s %-25.25s\n" struct dundi_mapping *map; char fs[256]; + char weight[8]; if (argc != 3) return RESULT_SHOWUSAGE; AST_LIST_LOCK(&peers); ast_cli(fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination"); AST_LIST_TRAVERSE(&mappings, map, list) { - ast_cli(fd, FORMAT, map->dcontext, map->weight, + snprintf(weight, sizeof(weight), "%d", get_mapping_weight(map)); + ast_cli(fd, FORMAT, map->dcontext, weight, ast_strlen_zero(map->lcontext) ? "<none>" : map->lcontext, dundi_flags2str(fs, sizeof(fs), map->options), tech2str(map->tech), map->dest); } @@ -3871,6 +3889,8 @@ static void destroy_peer(struct dundi_peer *peer) static void destroy_map(struct dundi_mapping *map) { + if (map->weightstr) + free(map->weightstr); free(map); } @@ -3960,11 +3980,15 @@ static void build_mapping(char *name, char *value) } else if (x >= 4) { ast_copy_string(map->dcontext, name, sizeof(map->dcontext)); ast_copy_string(map->lcontext, fields[0], sizeof(map->lcontext)); - if ((sscanf(fields[1], "%d", &map->weight) == 1) && (map->weight >= 0) && (map->weight < 60000)) { + if ((sscanf(fields[1], "%d", &map->_weight) == 1) && (map->_weight >= 0) && (map->_weight <= MAX_WEIGHT)) { ast_copy_string(map->dest, fields[3], sizeof(map->dest)); - if ((map->tech = str2tech(fields[2]))) { + if ((map->tech = str2tech(fields[2]))) + map->dead = 0; + } else if (!strncmp(fields[1], "${", 2) && fields[1][strlen(fields[1]) - 1] == '}') { + map->weightstr = ast_strdup(fields[1]); + ast_copy_string(map->dest, fields[3], sizeof(map->dest)); + if ((map->tech = str2tech(fields[2]))) map->dead = 0; - } } else { ast_log(LOG_WARNING, "Invalid weight '%s' specified, deleting entry '%s/%s'\n", fields[1], map->dcontext, map->lcontext); } |