[Freeswitch-users] Stacked conditions are not acting like logical AND
Herman Griffin
herman.griffin at gmail.com
Wed Jan 18 12:45:38 MSK 2012
Hello Michael,
That response was prefect. I get it know! Thanks for taking the time to respond.
Herman
On Mon, Jan 16, 2012 at 4:29 PM, Michael Collins <msc at freeswitch.org> wrote:
> Hi Herman,
>
> These are common questions when dealing with the dialplan. I highly
> recommend that you acquire the FreeSWITCH "bridge book" (see link near top
> of wiki.freeswitch.org) and read chapters 5 and 8. (Full disclosure: I wrote
> chapter 5 and Darren Schreiber wrote chapter 8.) Both of these chapters
> cover the break attribute in detail. I think you might be confusing the
> purpose of the break attribute.
>
> Consider this dp fragment:
> <extension name="test">
> <condition field="foo" expression="bar"/>
> <condition field="foo2" expression="bar2">
> <!-- actions here get added to task list only if both conditions are
> true -->
> <!-- anti-actions here get added to task list only if foo is true and
> foo2 is false -->
> </condition>
> </extension>
>
> When the dialplan parser gets to this extension, the first thing it does is
> test the "foo" field. If the test fails then the parser does not even look
> at the rest of this extension. Why not? Because all conditions have an
> implied break="on-false". The following two conditions are identical in
> function:
> <condition field="foo" expression="bar"/>
> <condition field="foo" expression="bar" break="on-false/>
>
> So, if you want a set of actions to be included only if more than one
> condition is met then "stacking" will work, however you cannot do
> break="never". Why not? Because break="never" tells the dialplan parser,
> "Hey, even if this condition fails, go ahead and evaluate the next condition
> in this extension." If you have break="on-false" (or no 'break' attribute at
> all) then that tells the dialplan parser, "Hey, if this condition fails then
> 'break out' of this extension and continue parsing the dialplan."
>
> Using what we've just discussed, let's look at the example you cited in your
> second post.
> Dialplan extension "emergency_set_variables":
>
>
> <condition field="${caller_id_name}" expression="^Emerg_" break="never">
> <action application="set" data="emergency_call=true" inline="true"/>
> </condition>
>
> <condition wday="2-6" time-of-day="22:00-23:59" break="never">
> <action application="set" data="open=true" inline="true"/>
> </condition>
>
> <condition wday="1,7" time-of-day="05:00-23:59" break="never">
> <action application="set" data="open=true" inline="true"/>
> </condition>
>
> The dialplan parser logged this:
>
>
> Dialplan: sofia/external/Unknown at 72.37.252.18 Regex (FAIL)
> [emergency_set_variables] ${caller_id_name}(Unknown) =~ /^Emerg_/
> break=never
> Dialplan: sofia/external/Unknown at 72.37.252.18 Date/TimeMatch (FAIL)
> [emergency_set_variables] break=never
> Dialplan: sofia/external/Unknown at 72.37.252.18 Date/Time Match (PASS)
> [emergency_set_variables] break=never
> Dialplan: sofia/external/Unknown at 72.37.252.18 Action set(open=true) INLINE
> EXECUTE sofia/external/Unknown at 72.37.252.18 set(open=true)
>
> Note: I added the color so that you could see which dialplan lines
> correspond to the log output.
>
> The first condition (purple) fails. ({$caller_id_name} has the value
> "Unknown" which fails the regex test against /^Emerg_/) However, since you
> have break="never", the parser continues on to the next condition inside
> this extension. Had you done break="on-false" (or no break attribute) then
> the parser would have moved on to the next extension in the dialplan.
>
> The second condition (orange) also fails. Again, you have break="never", so
> even though it fails, the parser moves on to the next condition.
>
> The third condition (green) passes, so the parser adds the <action> to the
> task list. (Since you have inline="true" the action gets executed
> immediately during dialplan parsing instead later on during the "execution
> phase".)
>
> In other words, the log output is exactly what I would expect it to be.
>
> As to your other question about anti-actions in a stack: this also is a
> common question. It looks like you are trying to do something like this:
>
> IF (cond1 AND cond2 AND cond3) THEN
> do actions
> ELSE
> do other actions
> ENDIF
>
> You cannot do this particular construct just with conditions and
> anti-actions. Instead you'll need the brand spanking new "regex" syntax
> mentioned here:
> http://wiki.freeswitch.org/wiki/Dialplan_XML#Multiple_Conditions_.28Logical_OR.2C_XOR.29
>
> So, to do what you wanted to do in the second example (in your second post)
> you could try this:
>
> <condition regex="all">
> <regex field="${sip_gateway}" expression="^${default_provider}$"/>
> <regex field="${emergency_call}" expression="^true$"/>
> <regex field="${db(select/emergency/autoanswer)}" expression="^1$"/>
> <!-- the following actions get executed if all regexes PASS -->
>
> <action application="set" data="call_timeout=60"/>
> <action application="set"
> data="effective_caller_id_name=${regex(${caller_id_name}|^Emerg(_.*)$|Auto%1)}"/>
> <action application="set" data="autoanswered=true"/>
> <action application="answer" data=""/>
> <action application="set"
> data="group_confirm_file=/usr/local/freeswitch/sounds/en/us/callie/emergency/press_to_accept.wav"/>
> <action application="set" data="group_confirm_key=1"/>
> <action application="bridge"
> data="user/1000@${domain_name},sofia/gateway/1006_7217/${mobile_number}"/>
> <!-- the following anti-actions are executed if any of the regexes FAIL
> -->
>
> <anti-action application="set"
> data="effective_caller_id_name=${regex(${caller_id_name}|^Emerg(_.*)$|NotAuto%1)}"/>
> <anti-action application="set" data="call_timeout=30"/>
> <anti-action application="set" data="autoanswered=false"/>
> <anti-action application="set"
> data="group_confirm_file=/usr/local/freeswitch/sounds/en/us/callie/emergency/press_to_accept.wav"/>
> <anti-action application="set" data="group_confirm_key=1"/>
> <anti-action application="bridge"
> data="user/1000@${domain_name},sofia/gateway/1006_7217/${mobile_number}"/>
> </condition>
>
>
> The <condition regex="all"> tells the parser, "Hey, execute the <action>'s
> only if all regexes PASS, otherwise execute any <anti-action>'s". That
> should give you what you need.
>
> Hope this helps!
>
> -Michael
>
>
>
>
> On Sat, Jan 14, 2012 at 7:39 PM, Herman Griffin <herman.griffin at gmail.com>
> wrote:
>>
>> Hello everyone,
>>
>> In irc SwK said that freeswitch AND operator is lazy. To me this means
>> that if a condition is set to break=true and it evaluates to FAIL,
>> then the that break=never will invert the meaning of FAIL; Change it
>> to a PASS . But why doesn't break=false behave in this same manner
>> when there is only a single condition?
>>
>> Take this call trace and dialplan for example. I use a single
>> condition with break=false. However, unlike the stacked conditions,
>> the action is not executed when the single condition evaluates to
>> FAIL. Why doesn't break=never cause the action to be executed in a non
>> stacked condition?
>>
>> Call trace:
>>
>> Dialplan: sofia/external/Unknown at 72.37.252.18 Regex (FAIL)
>> [emergency_set_variables] ${caller_id_name}(Unknown) =~ /^Emerg_/
>> break=never
>> Dialplan: sofia/external/Unknown at 72.37.252.18 Date/TimeMatch (FAIL)
>> [emergency_set_variables] break=never
>> Dialplan: sofia/external/Unknown at 72.37.252.18 Date/Time Match (PASS)
>> [emergency_set_variables] break=never
>> Dialplan: sofia/external/Unknown at 72.37.252.18 Action set(open=true) INLINE
>> EXECUTE sofia/external/Unknown at 72.37.252.18 set(open=true)
>>
>> Dialplan:
>>
>> <condition field="${caller_id_name}" expression="^Emerg_" break="never">
>> <action application="set" data="emergency_call=true" inline="true"/>
>> </condition>
>>
>> <condition wday="2-6" time-of-day="22:00-23:59" break="never">
>> <action application="set" data="open=true" inline="true"/>
>> </condition>
>>
>> <condition wday="1,7" time-of-day="05:00-23:59" break="never">
>> <action application="set" data="open=true" inline="true"/>
>> </condition>
>>
>> -------------------------------------------------
>>
>> I also getting confusing behavior with anti-action and stacked
>> condition. I expect the anti-action to be executed if any of the
>> stacked conditions evaluates to FAIL. However, in the case below, the
>> extension simply breaks if any of the condition evaluates to FAIL.
>>
>> Call trace:
>>
>> Dialplan: sofia/external/Unknown at 72.37.252.18 parsing
>> [public->emergency_bridge] continue=true
>> Dialplan: sofia/external/Unknown at 72.37.252.18 Regex (PASS)
>> [emergency_bridge] ${sip_gateway}(1006_7217) =~ /^1006_7217$/
>> break=on-false
>> Dialplan: sofia/external/Unknown at 72.37.252.18 Regex (FAIL)
>> [emergency_bridge] ${emergency_call}() =~ /^true$/ break=on-false
>> Dialplan: sofia/external/Unknown at 72.37.252.18 parsing
>> [public->public_did] continue=false <-- [[MOVES ON TO ANOTHER
>> EXTENSION WITH EXECUTING THE anti-action]]
>>
>> Dialplan:
>>
>> <condition field="${sip_gateway}" expression="^${default_provider}$"/>
>> <condition field="${emergency_call}" expression="^true$"/>
>> <condition field="${db(select/emergency/autoanswer)}" expression="^1$">
>> <action application="set" data="call_timeout=60"/>
>> <action application="set"
>>
>> data="effective_caller_id_name=${regex(${caller_id_name}|^Emerg(_.*)$|Auto%1)}"/>
>> <action application="set" data="autoanswered=true"/>
>> <action application="answer" data=""/>
>> <action application="set"
>>
>> data="group_confirm_file=/usr/local/freeswitch/sounds/en/us/callie/emergency/press_to_accept.wav"/>
>> <action application="set" data="group_confirm_key=1"/>
>> <action application="bridge"
>> data="user/1000@${domain_name},sofia/gateway/1006_7217/${mobile_number}"/>
>>
>> <anti-action application="set"
>>
>> data="effective_caller_id_name=${regex(${caller_id_name}|^Emerg(_.*)$|NotAuto%1)}"/>
>> <anti-action application="set" data="call_timeout=30"/>
>> <anti-action application="set" data="autoanswered=false"/>
>> <anti-action application="set"
>>
>> data="group_confirm_file=/usr/local/freeswitch/sounds/en/us/callie/emergency/press_to_accept.wav"/>
>> <anti-action application="set" data="group_confirm_key=1"/>
>> <anti-action application="bridge"
>> data="user/1000@${domain_name},sofia/gateway/1006_7217/${mobile_number}"/>
>> </condition>
>> </extension>
>>
>>
>> SwK suggested that I use a script language, which is probably what
>> I'll end up doing. However, I'm very interested in understanding why
>> the scenarios above. Are these bugs or are they just counter intuitive
>> rules that we must simply memorize?
>>
>> Thanks for your input.
>> Herman Griffin
>>
>>
>>
>> On Sat, Jan 14, 2012 at 11:42 AM, Jeff Lenk <jeff at jefflenk.com> wrote:
>> > By putting the break=never you are defeating the "and" processing.
>> > Remove
>> > that.
>> >
>> > Move the second group into its own extension.
>> >
>> > --
>> > View this message in context:
>> > http://freeswitch-users.2379917.n2.nabble.com/Stacked-conditions-are-not-acting-like-logical-AND-tp7188082p7188271.html
>> > Sent from the freeswitch-users mailing list archive at Nabble.com.
>
>
>
>
> _________________________________________________________________________
> Professional FreeSWITCH Consulting Services:
> consulting at freeswitch.org
> http://www.freeswitchsolutions.com
>
>
>
>
> Official FreeSWITCH Sites
> http://www.freeswitch.org
> http://wiki.freeswitch.org
> http://www.cluecon.com
>
> FreeSWITCH-users mailing list
> FreeSWITCH-users at lists.freeswitch.org
> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
> http://www.freeswitch.org
>
Join us at ClueCon 2011 Aug 9-11, 2011
More information about the FreeSWITCH-users
mailing list