]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-3655 please test and apply to wiki for documentation in the xml dialplan section
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 1 Nov 2011 22:46:26 +0000 (17:46 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Tue, 1 Nov 2011 22:46:26 +0000 (17:46 -0500)
src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c

index 5f042fbf26cc6c473a09705b536c78b090a305f5..57be1e3c52386c305830ebde411e0392d0469f8f 100644 (file)
@@ -81,12 +81,12 @@ static switch_status_t exec_app(switch_core_session_t *session, const char *app,
 
 static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, switch_caller_extension_t **extension)
 {
-       switch_xml_t xcond, xaction, xexpression;
+       switch_xml_t xcond, xaction, xexpression, xregex;
        switch_channel_t *channel = switch_core_session_get_channel(session);
        char *exten_name = (char *) switch_xml_attr(xexten, "name");
-       int proceed = 0;
+       int proceed = 0, save_proceed = 0;
        char *expression_expanded = NULL, *field_expanded = NULL;
-       switch_regex_t *re = NULL;
+       switch_regex_t *re = NULL, *save_re = NULL;
 
        if (!exten_name) {
                exten_name = "_anon_";
@@ -95,7 +95,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
        for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
                char *field = NULL;
                char *do_break_a = NULL;
-               char *expression = NULL;
+               char *expression = NULL, *save_expression = NULL, *save_field_data = NULL;
+               char *regex_rule = NULL;
                const char *field_data = NULL;
                int ovector[30];
                switch_bool_t anti_action = SWITCH_TRUE;
@@ -114,17 +115,6 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 
                field = (char *) switch_xml_attr(xcond, "field");
 
-               if ((xexpression = switch_xml_child(xcond, "expression"))) {
-                       expression = switch_str_nil(xexpression->txt);
-               } else {
-                       expression = (char *) switch_xml_attr_soft(xcond, "expression");
-               }
-
-               if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) {
-                       expression_expanded = NULL;
-               } else {
-                       expression = expression_expanded;
-               }
 
                if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) {
                        if (!strcasecmp(do_break_a, "on-true")) {
@@ -147,41 +137,169 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                        anti_action = SWITCH_FALSE;
                } else if (time_match == 0) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-                                                         "Dialplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
+                                                         "Dialplan: %s Date/TimeMatch (FAIL) [%s] break=%s\n",
                                                          switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false");
                }
+               
+               
+               if ((regex_rule = (char *) switch_xml_attr(xcond, "regex"))) {
+                       int all = !strcasecmp(regex_rule, "all");
+                       int pass = 0;
+                       int fail = 0;
+
+                       for (xregex = switch_xml_child(xcond, "regex"); xregex; xregex = xregex->next) {
+                               time_match = switch_xml_std_datetime_check(xregex);
 
-               if (field) {
-                       if (strchr(field, '$')) {
-                               if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) {
-                                       field_expanded = NULL;
-                                       field_data = field;
+                               if (time_match == 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
+                                                                         "Dialplan: %s Date/Time Match (PASS) [%s]\n",
+                                                                         switch_channel_get_name(channel), exten_name);
+                                       anti_action = SWITCH_FALSE;
+                               } else if (time_match == 0) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
+                                                                         "Dialplan: %s Date/TimeMatch (FAIL) [%s]\n",
+                                                                         switch_channel_get_name(channel), exten_name);
+                               }
+
+
+                               if ((xexpression = switch_xml_child(xregex, "expression"))) {
+                                       expression = switch_str_nil(xexpression->txt);
+                               } else {
+                                       expression = (char *) switch_xml_attr_soft(xregex, "expression");
+                               }
+                               
+                               if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) {
+                                       expression_expanded = NULL;
                                } else {
-                                       field_data = field_expanded;
+                                       expression = expression_expanded;
                                }
+                               
+                               
+                               field = (char *) switch_xml_attr(xregex, "field");
+
+                               if (field) {
+                                       if (strchr(field, '$')) {
+                                               if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) {
+                                                       field_expanded = NULL;
+                                                       field_data = field;
+                                               } else {
+                                                       field_data = field_expanded;
+                                               }
+                                       } else {
+                                               field_data = switch_caller_get_field_by_name(caller_profile, field);
+                                       }
+                                       if (!field_data) {
+                                               field_data = "";
+                                       }
+
+                                       if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
+                                                                                 "Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ match=%s\n",
+                                                                                 switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any");
+                                               pass++;
+                                               if (!all) break;
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
+                                                                                 "Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ match=%s\n",
+                                                                                 switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any");
+                                               fail++;
+                                               if (all) break;
+                                       }
+                               } else if (time_match == -1) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
+                                                                         "Dialplan: %s Absolute Condition [%s] match=%s\n", switch_channel_get_name(channel), exten_name, all ? "all" : "any");
+                                       pass++;
+                                       if (!all) break;
+                               }
+                               
+                               if (field && strchr(expression, '(')) {
+                                       
+                                       switch_safe_free(save_expression);
+                                       switch_safe_free(save_field_data);
+                                       switch_regex_safe_free(save_re);
+                                       
+                                       
+                                       save_expression = strdup(expression);
+                                       save_field_data = strdup(field_data);
+                                       save_re = re;
+                                       save_proceed = proceed;
+                                       
+                                       re = NULL;
+                               }
+
+                               switch_regex_safe_free(re);
+
+                               switch_safe_free(field_expanded);
+                               switch_safe_free(expression_expanded);
+                               
+                       }
+
+                       if ((all && !fail) || (!all && pass)) {
+                               anti_action = SWITCH_FALSE; 
+                       }
+
+                       switch_safe_free(field_expanded);
+                       switch_safe_free(expression_expanded);
+                       
+               } else {
+                       if ((xexpression = switch_xml_child(xcond, "expression"))) {
+                               expression = switch_str_nil(xexpression->txt);
                        } else {
-                               field_data = switch_caller_get_field_by_name(caller_profile, field);
+                               expression = (char *) switch_xml_attr_soft(xcond, "expression");
                        }
-                       if (!field_data) {
-                               field_data = "";
+
+                       if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) {
+                               expression_expanded = NULL;
+                       } else {
+                               expression = expression_expanded;
                        }
+                       
+                       if (field) {
+                               if (strchr(field, '$')) {
+                                       if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) {
+                                               field_expanded = NULL;
+                                               field_data = field;
+                                       } else {
+                                               field_data = field_expanded;
+                                       }
+                               } else {
+                                       field_data = switch_caller_get_field_by_name(caller_profile, field);
+                               }
+                               if (!field_data) {
+                                       field_data = "";
+                               }
 
-                       if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                               if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
+                                                                         "Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
+                                                                         switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
+                                       anti_action = SWITCH_FALSE;
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
+                                                                         "Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
+                                                                         switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
+                               }
+                       } else if (time_match == -1) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-                                                                 "Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
-                                                                 switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
+                                                                 "Dialplan: %s Absolute Condition [%s]\n", switch_channel_get_name(channel), exten_name);
                                anti_action = SWITCH_FALSE;
-                       } else {
-                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-                                                                 "Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
-                                                                 switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
                        }
-               } else if (time_match == -1) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG,
-                                                         "Dialplan: %s Absolute Condition [%s]\n", switch_channel_get_name(channel), exten_name);
-                       anti_action = SWITCH_FALSE;
+
                }
 
+               if (save_re) {
+                       re = save_re;
+                       save_re = NULL;
+                       
+                       expression = expression_expanded = save_expression;
+                       save_expression = NULL;
+                       field_data = field_expanded = save_field_data;
+                       field = (char *) field_data;
+                       save_field_data = NULL;
+                       proceed = save_proceed;
+               }
+
+
                if (anti_action) {
                        for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) {
                                const char *application = switch_xml_attr_soft(xaction, "application");