# # patch "res/res_features.c" # from [c159a66b43c3c3039f8c4b5f48cb40f2c811fb40] # to [faabc5bb3d32b6ed28eb11d794c182f73b6934ee] # ================================================================================ --- res/res_features.c c159a66b43c3c3039f8c4b5f48cb40f2c811fb40 +++ res/res_features.c faabc5bb3d32b6ed28eb11d794c182f73b6934ee @@ -1026,10 +1026,15 @@ return res; } -static void set_config_flags(struct ast_bridge_config *config) +static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config) { int x; - + char *dynamic_features = NULL; + char *tmp = NULL; + char *tok = NULL; + char *begin = NULL; + struct ast_call_feature *feature; + ast_clear_flag(config, AST_FLAGS_ALL); for (x = 0; x < FEATURES_COUNT; x++) { if (ast_test_flag(&(config->features_caller), builtin_features[x].feature_mask)) { @@ -1041,6 +1046,44 @@ ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1); } } + + if (chan && peer && !(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) { + + dynamic_features = pbx_builtin_getvar_helper(chan,"DYNAMIC_FEATURES"); + + if (dynamic_features) { + tmp = strdup(dynamic_features); + begin = tmp; + + if (!tmp) { + ast_log(LOG_ERROR, "Not enough memory to perform a strdup, some dynamic features may not work correctly"); + return; + } + + /* while we have a feature and neither bridge flag is set */ + while (NULL != (tok = strsep(&tmp, "#"))) { + + AST_LIST_LOCK(&feature_list); + AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) { + if (!strcasecmp(tok, feature->sname)) + break; /* break from list traverse, not outer loop */ + } + AST_LIST_UNLOCK(&feature_list); + + if (feature) { + if (ast_test_flag(feature, AST_FEATURE_FLAG_CALLER)) { + if (ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) + ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0); + } + if (ast_test_flag(feature, AST_FEATURE_FLAG_CALLEE)) { + if (ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) + ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1); + } + } + } + free(begin); + } + } } @@ -1257,7 +1300,7 @@ allowdisconnect_out = ast_test_flag(&(config->features_caller), AST_FEATURE_DISCONNECT); allowredirect_in = ast_test_flag(&(config->features_callee), AST_FEATURE_REDIRECT); allowredirect_out = ast_test_flag(&(config->features_caller), AST_FEATURE_REDIRECT); - set_config_flags(config); + set_config_flags(chan, peer, config); config->firstpass = 1; /* Answer if need be */ @@ -2038,8 +2081,17 @@ if (!strcasecmp(party,"caller")) ast_set_flag(feature,AST_FEATURE_FLAG_CALLER); - else + else if (!strcasecmp(party, "callee")) ast_set_flag(feature,AST_FEATURE_FLAG_CALLEE); +#if 0 + else if (!strcasecmp(party, "both")) + ast_set_flag(feature,AST_FEATURE_FLAG_CALLEE | AST_FEATURE_FLAG_CALLER); +#endif + else { + ast_log(LOG_NOTICE, "Invalid party specification for feature '%s', must be caller, or callee\n", var->name); + var = var->next; + continue; + } ast_register_feature(feature);