Use of Dynamic Features in Dialplan

Hello,

I would like to enable a dynamic feature in order to open the door when someone call from my SIP-Door Phone (That I haven’t bought yet).

After some research, I succeeded to do like hereunder, and it works !

File: /etc/asterisk/features_applicationmap_custom.conf :
OpenDoor => *66,peer,Macro,OpenDoorFeature

File: /etc/asterisk/extensions_custom.conf :
[macro-OpenDoorFeature]
exten => s,1,Set(result=${CURL(http://admin:[email protected]/preset.htm?RLY1=1)})
exten => s,n,MacroExit

File: /etc/asterisk/globals_custom.conf :
DYNAMIC_FEATURES = OpenDoor

The problem is that anyone calling me from outside is also able to open my door and that I is not so nice :-/
I would like that only my local phones (extension) are able to do this

I presume that somewhere in the dialplan, I should add the set(dynamic_features) like this :

[default]
exten => __XXX,1,Set(DYNAMIC_FEATURES=OpenDoor)

The problem is I really don’t know where to do it without touching the automatic generated files of FreePBX.

Would you have an idea ?

Oops, ever mind I reread but try using callee instead of peer

Hi,

I would not use a feature map at all, but rather a custom context to do that. If you want to protect your door being opened by anyone you should limit the ${EXTEN} to a pattern with a caller id and hangup the call if someone else is trying to use the code. I do not think that you are getting a result code from your adapter, so no need to use it.
This code should be dialled from the from-internal-custom context if you are using the Freepbx of course.

example:

[from-internal-custom]
exten => *66/_XXX,1,Answer
exten => same,n,CURL(http://admin:[email protected]/preset.htm?RLY1=1)
exten => same,n,Hangup

Thank you,

Daniel Friedman
Trixton LTD.

Mobile: +41.79.868.7050
Email: [email protected]

Thanks for the reply dicko. Unfortunately, with callee, if I call an external number, he will be able to open the door as callee I suppose. Actually, I tried and both caller and callee were able to open, what I don’t explain ?!?

Thanks Daniel,

I tried also this solution (without limitation to the $Exten). It works, but in this case, it works only when communication is not established. I mean, my doorphone calls an internal extension, I speak with the person and then I decide to open. I must first hang up and then unhook and type *66 ?

That is the manipulation I wanted to avoid…

Patrick,

your dilemma about callee and caller are clear. One important consideration is, don’t overwrite DYNAMIC_FEATURES, make sure you append to it since FreePBX uses it for on demand call recording so you don’t want to overwrite that. See documentation as to how to append.

I think the solution is a combination of callee and only setting the DYNAMIC_FEATURE if the call is from an internal extension. The way we would usually do something like that is to hook into macro-user-callerid and from within there, detect that it’s an internal extensions call or not. There are many other ways you could probably do this that can be investigated or other’s can pipe in.

An alternative would be similar to how we do on demand recording though that is a lot more ‘sophisticated.’ We call a script that connects into the manager and makes dynamic decisions, so it could determine who you are and if you have the authority to do this. This is probably a lot harder to do, vs. finding a way to only append your dynamic feature when the call is initiated from inside and only for the callee to press. I guess the other thing, thinking out loud, that you can do within dialplan, is to check the AMPUSER channel variable, and then confirm that there is an actual AMPUSER who is that person (this is somewhat effectively determining if the authoritative callerid is an internal user making the call) and only executing the door open feature if so, that in conjunction with callee only. I still like the hooking of macro-user-callerid better but that usually involves writing a minor module that can hook into the macro since redefining the macro leads to future issues when we do upgrades.

I hope that sets you off in the right direction. It was a bit ‘train of thought’ so if it’s a bit confusing, sorry :frowning:

Hello Patrick,

You can send the DTMF during the call, there is not a problem doing that. Try this and let me know if it is succeeding or not. If not, I will adapt the dialplan to wait for the code and then initiate a local call to the door phone.
I can add some authentication to check if the caller id is an AMPUSER by adding few lines to the dialplan.

Thank you,

Daniel Friedman
Trixton LTD.

Tel: +41.79.868.7050
Email: [email protected]

Daniel,

I think you may be a bit confused with what he’s trying to do. He needs to initiate a call while on an already answered call with the person at the other end of the door phone in most cases. That means he needs a dynamic feature code. The way to do that in Asterisk is how he’s proceeding, it requires Asterisk detect the feature code thus being vectored off to execute the appropriate dialplan.

Hi Philippe,

Yes, I understand what he is trying to do, and I understand that the channel is already has been answered. The Asterisk can detect any DTMF during a call and then I can store it in a variable and execute a local call origination.
In Patrick’s case, I do not think that a general feature code would be a prefect solution for him, as it is leading a way directly to the Asterisk other features codes, and god forbid if he is dialling with (tTr) parameters on his local calls.

Patrick, I suggest you try dialling the *66 during your call and share your logs here (core set verbose 4).

Thank you,

Daniel Friedman
Trixton LTD.

Hi Philippe,

Thanks a lot for your message and recommendations. I am really interested by the two way you propose; now it will take me some days to investigate this :smile:

Again thanks

Hi Daniel,

I desactived my feature and I tried with this code (without result) :

File: /etc/asterisk/extensions_custom.conf
[from-internal-custom]
exten => *66/_XX,1,NoOp()
same => n,Answer()
same => n,Set(result=${CURL(http://admin:[email protected]/preset.htm?RLY7=1)})
same => n,Hangup()

and I got this result. (sorry if i copied too much)

Hi,

Where is the output?

I cut a part in order to be able to post it, I hope the essential is there :smile:

-- Connected line update to SIP/11-00000264 prevented.
-- SIP/91-00000265 is ringing
-- SIP/91-00000265 is ringing
-- SIP/91-00000265 is ringing
-- SIP/91-00000265 is ringing
   > 0x765650d8 -- Probation passed - setting RTP source address to 192.168.1.17:4010
   > 0x765650d8 -- Probation passed - setting RTP source address to 192.168.1.17:4010
-- Connected line update to SIP/11-00000264 prevented.
-- SIP/91-00000265 answered SIP/11-00000264
   > 0x766d9eb8 -- Probation passed - setting RTP source address to 192.168.1.25:16400
   > 0x765650d8 -- Probation passed - setting RTP source address to 192.168.1.17:4010
-- Executing [[email protected]:1] Macro("SIP/11-00000264", "hangupcall,") in new stack
-- Executing [[email protected]:1] ExecIf("SIP/11-00000264", "0?Set(CDR(recordingfile)=.wav)") in new stack
-- Executing [[email protected]:2] GotoIf("SIP/11-00000264", "1?theend") in new stack
-- Goto (macro-hangupcall,s,4)
-- Executing [[email protected]:4] Hangup("SIP/11-00000264", "") in new stack

== Spawn extension (macro-hangupcall, s, 4) exited non-zero on ‘SIP/11-00000264’ in macro ‘hangupcall’
== Spawn extension (macro-dial-one, h, 1) exited non-zero on ‘SIP/11-00000264’
== Spawn extension (macro-dial-one, s, 44) exited non-zero on ‘SIP/11-00000264’ in macro ‘dial-one’
== Spawn extension (macro-exten-vm, s, 14) exited non-zero on ‘SIP/11-00000264’ in macro ‘exten-vm’
== Spawn extension (ext-local, 91, 2) exited non-zero on ‘SIP/11-00000264’
– Executing [[email protected]:1] Macro(“SIP/3Stars_9051-0000025e”, “hangupcall”) in new stack
– Executing [[email protected]:1] ExecIf(“SIP/3Stars_9051-0000025e”, “0?Set(CDR(recordingfile)=.wav)”) in new stack
– Executing [[email protected]:2] GotoIf(“SIP/3Stars_9051-0000025e”, “1?theend”) in new stack
– Goto (macro-hangupcall,s,4)
– Executing [[email protected]:4] Hangup(“SIP/3Stars_9051-0000025e”, “”) in new stack
== Spawn extension (macro-hangupcall, s, 4) exited non-zero on ‘SIP/3Stars_9051-0000025e’ in macro ‘hangupcall’
== Spawn extension (macro-dial, h, 1) exited non-zero on ‘SIP/3Stars_9051-0000025e’
== Spawn extension (macro-dial, s, 7) exited non-zero on ‘SIP/3Stars_9051-0000025e’ in macro ‘dial’
== Spawn extension (ext-group, 99, 11) exited non-zero on 'SIP/3Stars_9051-0000025e’
raspbx*CLI>

Daniel,

Is there a mechanism that I have not kept up with?

I just talked to one of the Asterisk developers and he wasn’t aware of anything else, though that doesn’t mean there isn’t one.

The purpose of dynamic feature codes is to give the ability to implement ‘in call’ feature codes similar to the stock ones like transfer, attended transfer, automon (which FreePBX stopped using in favor of our own dynamic feature code refered to above), etc. It’s also designed to provide a level of security by defining at call time if it’s accessible.

Can you elaborate or provide a link on the capability you’re referring that will allow you to store the DTMF dialed and execute it during the call. (I suspect he wants to stay on the call with the person to make sure the door gets unlocked so it probably has to happen during the call?) Since there are often many different ways to solve the same problem in Asterisk, maybe I’m missing something here?

Hi Patrick,

Can you turn on your DTMF flag in the console logger settings? I want to see the DTMF dialling in the log.
Do you know by chance if your door support DTMF commands directly?
Can you send me its manual?

Thank you,

Daniel Friedman
Trixton LTD.

Dear Daniel,

I haven’t bought my door phone yet, but it is not foreseen that he will control the door. For some reason, I prefer to keep this separate

Here is the log dtmf. first in one direction (internal callee) then in the other (internal caller)

[2015-10-29 14:58:34] DTMF[7466][C-00000167]: channel.c:4214 __ast_read: DTMF begin ‘’ received on SIP/91-0000027f
[2015-10-29 14:58:34] DTMF[7466][C-00000167]: channel.c:4225 __ast_read: DTMF begin passthrough '
’ on SIP/91-0000027f
[2015-10-29 14:58:34] DTMF[7466][C-00000167]: channel.c:4128 __ast_read: DTMF end ‘’ received on SIP/91-0000027f, duration 200 ms
[2015-10-29 14:58:34] DTMF[7466][C-00000167]: channel.c:4169 __ast_read: DTMF end accepted with begin '
’ on SIP/91-0000027f
[2015-10-29 14:58:34] DTMF[7466][C-00000167]: channel.c:4198 __ast_read: DTMF end passthrough ‘’ on SIP/91-0000027f
[2015-10-29 14:58:35] DTMF[7466][C-00000167]: channel.c:4214 __ast_read: DTMF begin ‘6’ received on SIP/91-0000027f
[2015-10-29 14:58:35] DTMF[7466][C-00000167]: channel.c:4225 __ast_read: DTMF begin passthrough ‘6’ on SIP/91-0000027f
[2015-10-29 14:58:35] DTMF[7466][C-00000167]: channel.c:4128 __ast_read: DTMF end ‘6’ received on SIP/91-0000027f, duration 200 ms
[2015-10-29 14:58:35] DTMF[7466][C-00000167]: channel.c:4169 __ast_read: DTMF end accepted with begin ‘6’ on SIP/91-0000027f
[2015-10-29 14:58:35] DTMF[7466][C-00000167]: channel.c:4198 __ast_read: DTMF end passthrough ‘6’ on SIP/91-0000027f
[2015-10-29 14:58:35] DTMF[10962][C-00000167]: channel.c:4214 __ast_read: DTMF begin ‘6’ received on SIP/91-0000027f
[2015-10-29 14:58:35] DTMF[10962][C-00000167]: channel.c:4218 __ast_read: DTMF begin ignored ‘6’ on SIP/91-0000027f
[2015-10-29 14:58:35] DTMF[10962][C-00000167]: channel.c:4128 __ast_read: DTMF end ‘6’ received on SIP/91-0000027f, duration 200 ms
[2015-10-29 14:58:35] DTMF[10962][C-00000167]: channel.c:4198 __ast_read: DTMF end passthrough ‘6’ on SIP/91-0000027f
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4214 __ast_read: DTMF begin '
’ received on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4225 __ast_read: DTMF begin passthrough ‘’ on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4128 __ast_read: DTMF end '
’ received on SIP/11-0000027e, duration 80 ms
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4169 __ast_read: DTMF end accepted with begin ‘’ on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4184 __ast_read: DTMF end '
’ detected to have actual duration 40 on the wire, emulation will be triggered on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4191 __ast_read: DTMF end ‘’ has duration 40 but want minimum 80, emulating on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4248 __ast_read: DTMF end emulation of '
’ queued on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4214 __ast_read: DTMF begin ‘6’ received on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4225 __ast_read: DTMF begin passthrough ‘6’ on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4128 __ast_read: DTMF end ‘6’ received on SIP/11-0000027e, duration 80 ms
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4169 __ast_read: DTMF end accepted with begin ‘6’ on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4184 __ast_read: DTMF end ‘6’ detected to have actual duration 40 on the wire, emulation will be triggered on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4191 __ast_read: DTMF end ‘6’ has duration 40 but want minimum 80, emulating on SIP/11-0000027e
[2015-10-29 14:58:46] DTMF[7466][C-00000167]: channel.c:4248 __ast_read: DTMF end emulation of ‘6’ queued on SIP/11-0000027e
[2015-10-29 14:58:47] DTMF[10962][C-00000167]: channel.c:4214 __ast_read: DTMF begin ‘6’ received on SIP/11-0000027e
[2015-10-29 14:58:47] DTMF[10962][C-00000167]: channel.c:4218 __ast_read: DTMF begin ignored ‘6’ on SIP/11-0000027e
[2015-10-29 14:58:47] DTMF[10962][C-00000167]: channel.c:4128 __ast_read: DTMF end ‘6’ received on SIP/11-0000027e, duration 90 ms
[2015-10-29 14:58:47] DTMF[10962][C-00000167]: channel.c:4198 __ast_read: DTMF end passthrough ‘6’ on SIP/11-0000027e

Hi Patrick,

Once the door phone will call you and you will answer the call, just make a blind transfer to *66 (or any other dial pattern that will be configured). On the worst case (the door will not open), The other person will call you again.
I am surprised that this door phone does not react on DTMF signals like the majority of the intercoms.

Thank you,

Daniel Friedman
Trixton LTD.

Patrick,

you were approaching the problem correctly for your intended purpose with the DYNAMIC feature and seem to have gotten side tracked as this other approach isn’t going to get what it sounds like you want. If your door phone can’t be programmed to respond to an inband DTMF code as Daniel points out, then I think you want to go back to your DYNAMIC feature code unless you’re happy with transferring and losing your call or something else very klunky like that. The DYNAMIC Feature code is definitely the ‘elegant’ and more natural user experience…

There are various options you can look into in order to decide your level of security. If it should only be availalbe when the call is initiated by the door phone, then you can set it to callee and then further scrutinize the channel within your macro to make sure it was the doorphone that made the call. You can add other measures of security such as the requirement, once in your macro, to plug in a combination such that once they press the feature code, they need to enter a combination for it to open. You can scrutinize the channel variables and try to reverse engineer if the channel interacting with your macro is an internal channel that is not the doorphone. You can do a combination where you try to easily detect who it is by some of these means, and if it’s ambigous you fall into a requirement to put in a combo. Unfortunately there are a lot of solutions once you’re in the dialplan to do all of this so much of it depends on how much you want to put into it, how secure you want it to be, how painless you want it to be for someone to open the door, etc.

Note that if you go the route of *66/_XXX you want to make sure that your door phone’s internal extension number isn’t a 3 digit extnension number or it’ll be able to dial that.

Also note that at some recent Asterisk version, they moved away from caller/callee to a new format in their applicationmap. I haven’t done anything with Dynamic Features with these changes and the wiki is farily brief so beware of the change and/or ask away and see if others can help you on these changes if/when they’re relevant to you. Here’s the wiki page I’m mentioning:

https://wiki.asterisk.org/wiki/display/AST/Custom+Dynamic+Features

Dear Daniel,

Indeed the blind transfer solution works. The door open and the communication is hanged up. It is just a bit heavy to do a ## followed by a *66 and i would preferer to keep the communication open. It can be an interesting fall-back solution if I can’t reach an other solution.

Thanks !
Patrick

1 Like

Hi Philippe,

I will continue to also try finding a solution with DYNAMIC Feature. Actually, I am already trying to play with [macro-user-callerid] of which you spoke in your first post. It seems however difficult to override the original freepbx macro and I also must find a way to check the origin of the call. Nice game for the next weeks :smile:

Thanks for your help
Patrick

EDIT : I could override the original macro with a copy of the original macro in extensions_override_freepbx.conf
And I added this command

ExecIf($["${AMPUSER}" = “91”]?Set(DYNAMIC_FEATURES=OpenDoor))

It works. I have too fine tune now the exact command and parameter caller/callee in order to get the result I want :smile: