DND status indication - hints and BLF
-
I have followed these intructions, with no luck. I updated the callback.pm file as i think you intended:
package FOP2Callbacks; # Example module to customize and tweak FOP2 behaviour my %redirected; sub flashCommand { # This function is called when certain commands are sent from a flash client $command = shift; @parameters = @_; my $return = ""; my @allreturn = (); if($command eq "setastdb") { # DND Integration from FOP2 to FreePBX ASTDB DND # This is for debug # my $cont=0; # foreach my $param (@parameters) { # $cont++; # print "Parametro $cont = $param\n"; # } if($parameters[3] ne "") { $return = "Action: Command\r\n"; $return .= "Command: database put DND ".$parameters[2]." YES\r\n"; $return .= "\r\n"; push @allreturn, $return; # New command to set a device state variable $return = "Action: SetVar\r\n"; $return .= "Variable: DEVICE_STATE(Custom:DND".$parameters[2].")\r\n"; $return .= "Value: BUSY\r\n"; $return .= "\r\n"; push @allreturn, $return; } else { $return = "Action: Command\r\n"; $return .= "Command: database del DND ".$parameters[2]."\r\n"; $return .= "\r\n"; push @allreturn, $return; # New command to set a device state variable $return = "Action: SetVar\r\n"; $return .= "Variable: DEVICE_STATE(Custom:DND".$parameters[2].")\r\n"; $return .= "Value: NOT_INUSE\r\n"; $return .= "\r\n"; push @allreturn, $return; } return @allreturn; } elsif($command eq "pickupActive") { #my $cont=0; #foreach my $param (@parameters) { # $cont++; # print "comando $comando -- Parametro $cont = $param\n"; #} $redirected{$parameters[0]}=1; #print "seteo redirected de ".$parameters[1]."\n"; return @allreturn; } elsif($command eq "auth") { #print "llego un auth, no devuelvo nada\n"; #foreach my $param (@parameters) { # $cont++; # print "Parametro $cont = $param\n"; #} return @allreturn; } } sub amiCommand { # Received an event from Asterisk Manager Interfase $command = shift; if($command eq "LEAVE") { # Used with fop2-dummy context for writing a line # to queue_log so redirects OUT of a queue are not # counted as abandoned calls %event = @_; my $return = ""; my @allreturn = (); if( defined ( $redirected { $event{Channel} } )) { # Este abandono es en realidad una redireccion delete $redirected { $event{Channel} }; my $tiempo = time(); $tiempo = $tiempo + 30; my $uniid = $event{Uniqueid}; my $queue = $event{Queue}; $return = "Action: Originate\r\n"; $return .= "Channel: Local/dummy\@fop2-dummy/n\r\n"; $return .= "Application: QueueLog\r\n"; $return .= "Data: $queue,$uniid,NONE,NOTABANDON,0,0,0\r\n"; $return .= "Async: true\r\n"; $return .= "\r\n"; push @allreturn, $return; return @allreturn; } } elsif($command eq "HANGUP") { # Garbage Collect %event = @_; if( defined ( $redirected { $event{Channel} } )) { # Este abandono es en realidad una redireccion delete $redirected { $event{Channel} }; } } } 1;It compiled without error. I restarted fop2.
It has not changed the result.I cannot see, in the CLI, any reaction at all when I change the presence state in the FOP2.
When I set the DND presence via *76, I can see the CLI react (ie, it scrolls through various steps it is taking). This does not happen when I set DND via FOP2. FOP2 does recognise the DND setting if I set it using *76, OR using the FOP2 interface.I think the problem is related to the fact that, once the dnd status is toggled, the CLI still shows:
== Extension Changed 216[ext-local] new state Idle for Notify User 216
Should this not be showing as "Busy" ?
I have active watchers watching for the status, but they are all showing idle: (this is from core show hints)
216@ext-local : SIP/216 State:Idle Watchers 6
However, if I try to dial that extension from another phone, the system reports that the user is 'on the phone', so it is responding to the DND setting.
-
I also tried changing the device state codes set by your script to "InUse" and "Idle" (Rather than "BUSY" and "NOT_INUSE") to match the status names I see in the CLI, checked perl no errors, restart fop2 - however this had no appreciable effect.
I have BLF's set to watch the status of 216, and they accurately reflect when the phone is in use, but they stubbornly continue to show the extension as idle when DND is set.
-
Check the dialplan macros, and the variables that are set for Device State, and try to replicate those in FOP2Calbacks.pm. What I wrote was taken from that macro, but if you look at them, there are more custom states being set. Perhaps you must add them all, or the other one that is also listed. This is just an extract of the dialplan:
exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE}) exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE})What I wrote tries to replicate the variable set for Custom:DND, but perhpas the phone is subscribed to DEVDND as the 2nd appearance. But I am not sure if DEVDND expect the device name or the extension number. If it is the device, then you should use another parameter in FOP2Callbacks.pm, you will have to uncomment the debug print lines to know what index to use, probably 4 or 5, so you can add another block like:
# New command to set a device state variable $return = "Action: SetVar\r\n"; $return .= "Variable: DEVICE_STATE(Custom:DEVDND".$parameters[4].")\r\n"; $return .= "Value: BUSY\r\n"; $return .= "\r\n"; push @allreturn, $return;In any case, start FOP2 in debug mode level 3 and inspect the commands being sent via AMI and the asterisk responses:
service fop2 stop cd /usr/local/fop2 script capture.log ./fop2_server -X 3log into fop2 and set presence to something, wait a while, set back to available, and then stop the capture:
ctrl-C exit service fop2 startYou will have the capture.log file to review, and see if the device state variables are being set and what are the manager responses.
Best regards,
-
Hi Nicolas, thank you for your ongoing help with this.
I have made significant progress, but there is still an issue, if you can bear with me explaining where I have got to.Firstly, for the benefit of others out there, I have discovered that there is a default setting in FreePBX that needs to be changed before you can get custom hints to work.
Specifically, you need to go to the "Advanced Settings" page, and change "Enable Custom Device States" to "True"
Once I did this, I started seeing signs of progress (core show hints started showing lots of monitored hints)Then I revisited the instructions Nicolas gave earlier, and re-set my /usr/local/fop2/FOP2Callbacks.pm changes to match my earlier post (I had made some changes since then trying different things, none of which worked)
I then reloaded asterisk (core reload) and restarted fop2 (service fop2 restart)At this stage, BLF started to work for DND set via the FOP2 interface.
This is a huge step forward and I am already very grateful and happy to have it working this far.The next issue, though, is that the BLF continues to ignore changes made by dialling *76 on the phone.
It is important to note that FOP2 DOES pick up these changes, and updates its status accordingly - however the BLF lamp does not change unless the DND status is changed via the FOP2 interface.
(this tells me that Nicolas' changes to FOP2Callbacks.pm are working well - it is now the underlying settings that are not working. )Presently, the BLF lamp will get 'out-of-sync' if the DND status is set via the *76 - it will continue to show Red unavailable if it was set to DND via FOP2 then turned off via *76, even though FOP2 recognises the change back to avaialable.
I have read what Nicolas said about how the FOP2Callbacks.pm works, and it seems it is only called when the FOP2 user interface is used. So, either we need somehow to have FOP2Callbacks.pm called when *76 is used, or we need to have the system set the presence correctly when FOP2Callbacks.pm is not called.
I have had another look at app-dnd-toggle in extensions_additional.conf and compared it with app-dnd-toggle in extensions_override_fop2.conf
It seems that, with the fop2 override, the exten => *76,n,Set(STATE=BUSY or NOT_INUSE) lines are omitted:From extensions_additional.conf
app-dnd-toggle
..
exten => *76,1,Answer
exten => *76,n,Wait(1)
exten => *76,n,Macro(user-callerid,)
exten => *76,n,GotoIf($["${DB(DND/${AMPUSER})}" = ""]?activate:deactivate)
exten => *76,n(activate),Set(DB(DND/${AMPUSER})=YES)
exten => *76,n,Set(STATE=BUSY)
exten => *76,n,Gosub(app-dnd-toggle,sstate,1())
exten => *76,n(hook_on),Playback(do-not-disturb&activated)
exten => *76,n,Macro(hangupcall,)From extensions_override_fop2.conf
app-dnd-toggle
...
exten => *76,1,Answer
exten => *76,n,Wait(1)
exten => *76,n,Macro(user-callerid,)
exten => *76,n,GotoIf($["${DB(DND/${AMPUSER})}" = ""]?activate:deactivate)
exten => *76,n(activate),Set(DB(DND/${AMPUSER})=YES)
; added for fop2
exten => *76,n,Set(CHAN=${CUT(CHANNEL,-,1)})
exten => *76,n,Set(DB(fop2state/${CHAN})=Do not Disturb)
exten => *76,n,UserEvent(FOP2ASTDB,Family: fop2state,Channel: ${CHAN},Value: Do not Disturb)
; end fop2 addition
exten => *76,n(hook_on),Playback(do-not-disturb&activated)
exten => *76,n,Macro(hangupcall,)I suspect this may be the reason the state is not getting set correctly when set via *76 ?
I did try re-inserting these lines into extensions_override_fop2.conf but it did not work. I am thinking perhaps the State being set is the device state, rather than the extension state, and it seems the system is happily reading the extension state.Are you able to suggest what I can do to make the *76 change behave in the same way as when set via FOP2 ?
Thanks again
-
The fix is to have the correct macro in extensions_override_fop2.conf. Not sure if you updated FreePBX after creating the override contexts, and it also seems your macros are kind of short, or for an old FreePBX version? Try to generate the contexts again running
/usr/local/fop2/generate_override_contexts.pl -w
Then compare the two macros again, there should be equal except for the ; added for fop2 and ;end addition blocks.
Also, just for your viewing pleasure, this is a copy of the macro for FreePBX 2.8 , kind of old I know, but it is what I have around:
[app-dnd-toggle] include => app-dnd-toggle-custom exten => *76,1,Answer exten => *76,n,Wait(1) exten => *76,n,Macro(user-callerid,) exten => *76,n,GotoIf($["${DB(DND/${AMPUSER})}" = ""]?activate:deactivate) exten => *76,n(activate),Set(DB(DND/${AMPUSER})=YES) ; added for fop2 exten => *76,n,Set(CHAN=${CUT(CHANNEL,-,1)}) exten => *76,n,Set(DB(fop2state/${CHAN})=Do not Disturb) exten => *76,n,UserEvent(FOP2ASTDB,Family: fop2state,Channel: ${CHAN},Value: Do not Disturb) ; end fop2 addition exten => *76,n,Set(STATE=BUSY) exten => *76,n,Gosub(app-dnd-toggle,sstate,1) exten => *76,n(hook_on),Playback(do-not-disturb&activated) exten => *76,n,Macro(hangupcall,) exten => *76,n(deactivate),Noop(Deleting: DND/${AMPUSER} ${DB_DELETE(DND/${AMPUSER})}) ; added for fop2 exten => *76,n,Set(CHAN=${CUT(CHANNEL,-,1)}) exten => *76,n,dbDel(fop2state/${CHAN}) exten => *76,n,UserEvent(FOP2ASTDB,Family: fop2state,Channel: ${CHAN},Value: ) ; end fop2 addition exten => *76,n,Set(STATE=NOT_INUSE) exten => *76,n,Gosub(app-dnd-toggle,sstate,1) exten => *76,n(hook_off),Playback(do-not-disturb&de-activated) exten => *76,n,Macro(hangupcall,) exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE}) exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${AMPUSER}/device)}) exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return) exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)}) exten => sstate,n,Set(ITER=1) exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE}) exten => sstate,n,Set(ITER=$[${ITER} + 1]) exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin) exten => sstate,n(return),Return() -
That did it!
When I re-generated the override contexts, they included the "set state" lines which had previously been missing.
All is working now. It even works using *78 and *79 to directly activate and deactivate DND, rather than *76 (toggle).
Awesome, thank you!

-
Good to know. Can you post your final/working FOP2Callbacks.pm changes to the forum?
-
This is the working content of FOP2Callbacks.pm
Here is the full file:
package FOP2Callbacks; # Example module to customize and tweak FOP2 behaviour my %redirected; sub flashCommand { # This function is called when certain commands are sent from a flash client $command = shift; @parameters = @_; my $return = ""; my @allreturn = (); if($command eq "setastdb") { # DND Integration from FOP2 to FreePBX ASTDB DND # This is for debug # my $cont=0; # foreach my $param (@parameters) { # $cont++; # print "Parametro $cont = $param\n"; # } if($parameters[3] ne "") { $return = "Action: Command\r\n"; $return .= "Command: database put DND ".$parameters[2]." YES\r\n"; $return .= "\r\n"; push @allreturn, $return; # New command to set a device state variable $return = "Action: SetVar\r\n"; $return .= "Variable: DEVICE_STATE(Custom:DND".$parameters[2].")\r\n"; $return .= "Value: BUSY\r\n"; $return .= "\r\n"; push @allreturn, $return; } else { $return = "Action: Command\r\n"; $return .= "Command: database del DND ".$parameters[2]."\r\n"; $return .= "\r\n"; push @allreturn, $return; # New command to set a device state variable $return = "Action: SetVar\r\n"; $return .= "Variable: DEVICE_STATE(Custom:DND".$parameters[2].")\r\n"; $return .= "Value: NOT_INUSE\r\n"; $return .= "\r\n"; push @allreturn, $return; } return @allreturn; } elsif($command eq "pickupActive") { #my $cont=0; #foreach my $param (@parameters) { # $cont++; # print "comando $comando -- Parametro $cont = $param\n"; #} $redirected{$parameters[0]}=1; #print "seteo redirected de ".$parameters[1]."\n"; return @allreturn; } elsif($command eq "auth") { #print "llego un auth, no devuelvo nada\n"; #foreach my $param (@parameters) { # $cont++; # print "Parametro $cont = $param\n"; #} return @allreturn; } } sub amiCommand { # Received an event from Asterisk Manager Interfase $command = shift; if($command eq "LEAVE") { # Used with fop2-dummy context for writing a line # to queue_log so redirects OUT of a queue are not # counted as abandoned calls %event = @_; my $return = ""; my @allreturn = (); if( defined ( $redirected { $event{Channel} } )) { # Este abandono es en realidad una redireccion delete $redirected { $event{Channel} }; my $tiempo = time(); $tiempo = $tiempo + 30; my $uniid = $event{Uniqueid}; my $queue = $event{Queue}; $return = "Action: Originate\r\n"; $return .= "Channel: Local/dummy\@fop2-dummy/n\r\n"; $return .= "Application: QueueLog\r\n"; $return .= "Data: $queue,$uniid,NONE,NOTABANDON,0,0,0\r\n"; $return .= "Async: true\r\n"; $return .= "\r\n"; push @allreturn, $return; return @allreturn; } } elsif($command eq "HANGUP") { # Garbage Collect %event = @_; if( defined ( $redirected { $event{Channel} } )) { # Este abandono es en realidad una redireccion delete $redirected { $event{Channel} }; } } } 1;The only changes are the insertion of these two sections:
# New command to set a device state variable $return = "Action: SetVar\r\n"; $return .= "Variable: DEVICE_STATE(Custom:DND".$parameters[2].")\r\n"; $return .= "Value: BUSY\r\n"; $return .= "\r\n"; push @allreturn, $return;and:
# New command to set a device state variable $return = "Action: SetVar\r\n"; $return .= "Variable: DEVICE_STATE(Custom:DND".$parameters[2].")\r\n"; $return .= "Value: NOT_INUSE\r\n"; $return .= "\r\n"; push @allreturn, $return; -
This is the full content of the now working extensions_override_fop2.conf:
[app-dnd-off] include => app-dnd-off-custom exten => *79,1,Answer exten => *79,n,Wait(1) exten => *79,n,Macro(user-callerid,) ; added for fop2 exten => *79,n,Set(CHAN=${CUT(CHANNEL,-,1)}) exten => *79,n,dbDel(fop2state/${CHAN}) exten => *79,n,UserEvent(FOP2ASTDB,Family: fop2state,Channel: ${CHAN},Value: ) ; end fop2 addition exten => *79,n,Noop(Deleting: DND/${AMPUSER} ${DB_DELETE(DND/${AMPUSER})}) exten => *79,n,Set(STATE=NOT_INUSE) exten => *79,n,Gosub(app-dnd-off,sstate,1()) exten => *79,n(hook_1),Playback(do-not-disturb&de-activated) exten => *79,n,Macro(hangupcall,) exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE}) exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${AMPUSER}/device)}) exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return) exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)}) exten => sstate,n,Set(ITER=1) exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE}) exten => sstate,n,Set(ITER=$[${ITER} + 1]) exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin) exten => sstate,n(return),Return() [app-dnd-on] include => app-dnd-on-custom exten => *78,1,Answer exten => *78,n,Wait(1) exten => *78,n,Macro(user-callerid,) ; added for fop2 exten => *78,n,Set(DB(DND/${AMPUSER})=YES) exten => *78,n,Set(CHAN=${CUT(CHANNEL,-,1)}) exten => *78,n,Set(DB(fop2state/${CHAN})=Do not Disturb) exten => *78,n,UserEvent(FOP2ASTDB,Family: fop2state,Channel: ${CHAN},Value: Do not Disturb) ; end fop2 addition exten => *78,n,Set(DB(DND/${AMPUSER})=YES) exten => *78,n,Set(STATE=BUSY) exten => *78,n,Gosub(app-dnd-on,sstate,1()) exten => *78,n(hook_1),Playback(do-not-disturb&activated) exten => *78,n,Macro(hangupcall,) exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE}) exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${AMPUSER}/device)}) exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return) exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)}) exten => sstate,n,Set(ITER=1) exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE}) exten => sstate,n,Set(ITER=$[${ITER} + 1]) exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin) exten => sstate,n(return),Return() [app-dnd-toggle] include => app-dnd-toggle-custom exten => *76,1,Answer exten => *76,n,Wait(1) exten => *76,n,Macro(user-callerid,) exten => *76,n,GotoIf($["${DB(DND/${AMPUSER})}" = ""]?activate:deactivate) exten => *76,n(activate),Set(DB(DND/${AMPUSER})=YES) ; added for fop2 exten => *76,n,Set(CHAN=${CUT(CHANNEL,-,1)}) exten => *76,n,Set(DB(fop2state/${CHAN})=Do not Disturb) exten => *76,n,UserEvent(FOP2ASTDB,Family: fop2state,Channel: ${CHAN},Value: Do not Disturb) ; end fop2 addition exten => *76,n,Set(STATE=BUSY) exten => *76,n,Gosub(app-dnd-toggle,sstate,1()) exten => *76,n(hook_on),Playback(do-not-disturb&activated) exten => *76,n,Macro(hangupcall,) exten => *76,n(deactivate),Noop(Deleting: DND/${AMPUSER} ${DB_DELETE(DND/${AMPUSER})}) ; added for fop2 exten => *76,n,Set(CHAN=${CUT(CHANNEL,-,1)}) exten => *76,n,dbDel(fop2state/${CHAN}) exten => *76,n,UserEvent(FOP2ASTDB,Family: fop2state,Channel: ${CHAN},Value: ) ; end fop2 addition exten => *76,n,Set(STATE=NOT_INUSE) exten => *76,n,Gosub(app-dnd-toggle,sstate,1()) exten => *76,n(hook_off),Playback(do-not-disturb&de-activated) exten => *76,n,Macro(hangupcall,) exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE}) exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${AMPUSER}/device)}) exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return) exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)}) exten => sstate,n,Set(ITER=1) exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE}) exten => sstate,n,Set(ITER=$[${ITER} + 1]) exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin) exten => sstate,n(return),Return() [app-cf-off] include => app-cf-off-custom exten => *73,1,Answer exten => *73,n,Wait(1) exten => *73,n,Macro(user-callerid,) exten => *73,n,Set(fromext=${AMPUSER}) exten => *73,n,Noop(Deleting: CF/${fromext} ${DB_DELETE(CF/${fromext})}) ; added for fop2 exten => *73,n,Set(CHAN=${DB(DEVICE/${fromext}/dial)}) exten => *73,n,UserEvent(FOP2CUST,Family: astdbcust,Channel: ${CHAN},Value: ) ; end fop2 addition exten => *73,n,Set(STATE=NOT_INUSE) exten => *73,n,Gosub(app-cf-off,sstate,1()) exten => *73,n(hook_1),Playback(call-fwd-unconditional&de-activated) exten => *73,n,Macro(hangupcall,) exten => _*73.,1,Answer exten => _*73.,n,Wait(1) exten => _*73.,n,Set(fromext=${EXTEN:3}) exten => _*73.,n,Noop(Deleting: CF/${fromext} ${DB_DELETE(CF/${fromext})}) ; added for fop2 exten => _*73.,n,Set(CHAN=${DB(DEVICE/${fromext}/dial)}) exten => _*73.,n,UserEvent(FOP2CUST,Family: astdbcust,Channel: ${CHAN},Value: ) ; end fop2 addition exten => _*73.,n,Set(STATE=NOT_INUSE) exten => _*73.,n,Gosub(app-cf-off,sstate,1()) exten => _*73.,n(hook_2),Playback(call-fwd-unconditional&for&extension) exten => _*73.,n,SayDigits(${fromext}) exten => _*73.,n,Playback(cancelled) exten => _*73.,n,Macro(hangupcall,) exten => sstate,1,Set(DEVICE_STATE(Custom:CF${fromext})=${STATE}) exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${fromext}/device)}) exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return) exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)}) exten => sstate,n,Set(ITER=1) exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVCF${CUT(DEVICES,&,${ITER})})=${STATE}) exten => sstate,n,Set(ITER=$[${ITER} + 1]) exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin) exten => sstate,n(return),Return() [app-cf-on] include => app-cf-on-custom exten => *72,1,Answer exten => *72,n,Wait(1) exten => *72,n,Macro(user-callerid,) exten => *72,n,Read(fromext,call-fwd-unconditional&please-enter-your&extension&then-press-pound,,,,) exten => *72,n,Set(fromext=${IF($["foo${fromext}"="foo"]?${AMPUSER}:${fromext})}) exten => *72,n,Wait(1) exten => *72,n(startread),Read(toext,ent-target-attendant&then-press-pound,,,,) exten => *72,n,GotoIf($["foo${toext}"="foo"]?startread) exten => *72,n,Wait(1) exten => *72,n,Set(DB(CF/${fromext})=${toext}) ; added for fop2 exten => *72,n,Set(CHAN=${DB(DEVICE/${fromext}/dial)}) exten => *72,n,UserEvent(FOP2CUST,Family: astdbcust,Channel: ${CHAN},Value: ${toext} ) ; end fop2 addition exten => *72,n,Set(STATE=BUSY) exten => *72,n,Gosub(app-cf-on,sstate,1()) exten => *72,n(hook_1),Playback(call-fwd-unconditional&for&extension) exten => *72,n,SayDigits(${fromext}) exten => *72,n,Playback(is-set-to) exten => *72,n,SayDigits(${toext}) exten => *72,n,Macro(hangupcall,) exten => _*72.,1,Answer exten => _*72.,n,Wait(1) exten => _*72.,n,Macro(user-callerid,) exten => _*72.,n,Set(fromext=${AMPUSER}) exten => _*72.,n,Set(toext=${EXTEN:3}) exten => _*72.,n,Set(DB(CF/${fromext})=${toext}) ; added for fop2 exten => _*72.,n,Set(CHAN=${DB(DEVICE/${fromext}/dial)}) exten => _*72.,n,UserEvent(FOP2CUST,Family: astdbcust,Channel: ${CHAN},Value: ${toext} ) ; end fop2 addition exten => _*72.,n,Set(STATE=BUSY) exten => _*72.,n,Gosub(app-cf-on,sstate,1()) exten => _*72.,n(hook_2),Playback(call-fwd-unconditional&for&extension) exten => _*72.,n,SayDigits(${fromext}) exten => _*72.,n,Playback(is-set-to) exten => _*72.,n,SayDigits(${toext}) exten => _*72.,n,Macro(hangupcall,) exten => sstate,1,Set(DEVICE_STATE(Custom:CF${fromext})=${STATE}) exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${fromext}/device)}) exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return) exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)}) exten => sstate,n,Set(ITER=1) exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVCF${CUT(DEVICES,&,${ITER})})=${STATE}) exten => sstate,n,Set(ITER=$[${ITER} + 1]) exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin) exten => sstate,n(return),Return() ;[fop2-park] ; Old fop2-park for asterisk 1.2 or some older 1.4 ;exten => _X.,1,Set(ARRAY(RETURN_EXTENSION,RETURN_CONTEXT)=${CUT(EXTEN,:,1)},${CUT(EXTEN,:,2)}) ;exten => _X.,n,ParkAndAnnounce(PARKED,,Console/dsp,${RETURN_CONTEXT},${RETURN_EXTENSION},1) ;exten => _X.,n,Goto(${RETURN_CONTEXT},${RETURN_EXTENSION},1) ;exten => _X.,n,Hangup [fop2-park] exten => _X.,1,Set(ARRAY(RETURN_EXTENSION,RETURN_CONTEXT,PARKBUTTON)=${CUT(EXTEN,:,1)},${CUT(EXTEN,:,2)},${CUT(EXTEN,:,3)}) exten => _X.,2,GotoIf($["${PARKBUTTON}" = "PARK/default"?5) exten => _X.,3,GotoIf($["${PARKBUTTON}" = ""?5) exten => _X.,4,Set(PARKINGLOT=${PARKBUTTON:5}) exten => _X.,5,Park(,${RETURN_CONTEXT},${RETURN_EXTENSION},1,s) [fop2-dummy] exten => dummy,1,Answer exten => dummy,2,Wait(1) exten => dummy,3,Hangup -
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login