Hi Developers,
I’ve written some code that, while crude, gives a highly flexible intercom functionality. It allows every extension to select which extensions it is willing to accept intercom calls from, or which to deny intercom calls from – and since it’s based on caller ID, it even gives the option of giving intercom access so certain outside callers.
The paging functionality that’s currently in FreePBX is excellent, but the intercom functionality, I think many believe, is non-existent or half-baked, because the only way to get intercom is through the paging system, requiring people to define all extensions TWICE, a regular version and a paging version.
The only other option is to use *80, which again is clumsy workaround for something that is literally a mainstay on traditional PBX’s. The problem with the *80 workflow also is that it should never be the caller who gets to decide whether a call is on intercom, it should be the RECIPIENT. The *80 workflow has significant privacy and security problems – think if someone *80’s into the bosses office. Absolutely noone should have that kind of access. And it is also incompatible with BLF buttons, because they can’t prefix the *80, thereby denying you the possibility of push-button-intercom. But the alternative shouldn’t be to be forced to disable intercom altogether. I think that *80 is a misunderstanding and not a good approach.
This proposed solution is recipient-centric, where each extension has list of extensions to either ALLOW or DENY intercom calls from.
This code is sort of a hack, in that I’m modifying extensions.conf directly, and calling a php script from the webserver that makes the decision about whether to include the auto-answer headers for Grandstream and Polycom phones for a given call. If you were to include this in FreePBX, it should obviously be database-driven. I would then suggest to re-label the “Paging And Intercom” section to just “Paging”, and add an intercom extension list to each extension’s configuration page, where in addition to the list you have 4 radio-buttons, Deny All, Allow All, Deny List, Allow List. Intercom is a feature of the particular extension, not the system itself, and it therefore belongs on the extension config page.
Anyway, here is the code, and I strongly believe that this intercom behavior ought to be in FreePBX… of course not programmed the way I’ve done it below, but this is just a proof of concept. Try it out and tell me if you don’t just love it.
First of all, in extensions.conf, locate the [macro-dial] macro, locate Sequence number 10, and replace 10 and 11 with this block:
;
; Step 14 and 15 are from original code, only renumbered.
; This segment uses localhost/custom/intercom.php to determine whether to add SIP headers for intercom
;
exten => s,10,Set(DOINTERCOM=${CURL(http://localhost/custom/intercom.php?dest=${ARG3}&src=${CALLERID(num)} )})
exten => s,11,GotoIf($[ “${DOINTERCOM}” != “ALLOW” ] ? 14)
exten => s,12,SIPAddHeader(Call-Info: answer-after=0)
exten => s,13,SIPAddHeader(Alert-info: Ring Answer)
exten => s,14,Dial(${ds}) ; dialparties will set the priority to 10 if $ds is not null
exten => s,15,Set(DIALSTATUS=${IF($["${DIALSTATUS_CW}"!="" ]?${DIALSTATUS_CW}:${DIALSTATUS})})
;
; End of new segment
;
If you’re using a later version of FreePBX than the 2.? this is done with, the whole point is to just squeeze in some action at sequence #10, and then the original code gets executed at #14. You may want to keep the original code, and just insert #10-#13 before it, and renumber, just to stay compatible. Execution starts at #10.
Then there’s a PHP script, which on Elastix is installed in /var/www/html/custom/intercom.php (“custom” is a new directory in the web root).
Here is the script, intercom.php:
<?php // Selective Intercom, 2008 Per Holmes, Public Domain // // This PHP script assists code in extentions.conf in determining whether to send SIP headers // to phones for enabling intercom/auto-answer. This allows each extension to choose // which other extensions it is willing to accept intercom calls from (or which extensions to // deny intercom calls from). Intercom must also be physically enabled on the phone itself. // // If an extension is not listed in the array below, the default is NO INTERCOM. // If ALLOW is selected, ONLY the listed extentions will be allowed to intercom. // If DENY is selected, all extensions will be allowed to intercom, *except* the listed extensions. // To allow all, select DENY with no extension. To deny all, select ALLOW with no extensions. $extensions = array ( // Syntax is: (destination) => array(allow/deny, source1, source2, source3, source4, ...), 201 => array("DENY"), 202 => array("DENY"), 203 => array("DENY"), 204 => array("DENY", 240, 241), 207 => array("ALLOW"), 240 => array("ALLOW"), 950 => array("ALLOW", 210, 211), // Example: 950 allows intercom from 210, 211 951 => array("DENY", 220, 221), // Example: 951 denies intercom from 220, 221 952 => array("DENY"), // Example: 952 allows intercom from everyone by denying noone ); $dest = $_GET['dest']; $src = $_GET['src']; if ($extensions[$dest][0] != "") { $mode=$extensions[$dest][0]; $srccount=1; while ($extensions[$dest][$srccount] != "") { if ($extensions[$dest][$srccount] == $src) { echo $mode; exit; } $srccount++; } // Return opposite result as default if ($mode == "ALLOW") echo "DENY"; else echo "ALLOW"; exit; } if ($src < 1 || $src > 9999) echo "DENY"; // If callerID is >9999, then it's a phone number = outside call = always deny // This is placed last to allow the possibility of a specific phone number // having intercom access to certain extensions. To do that, simply enter the // callerID as an allowed extension. echo "DENY"; ?>Again, this solution is not the most elegant one – it probably should be an .agi file or something, and this should all be integrated. But it works.
Notice the piece of code at the end that says if ($src > 9999) then DENY. The point is that if the extension number is over 9999, then it’s not in fact an extension, but an outside call. It is placed last, because then you have the option of actually making an extension willing to auto-answer a call from a certain outside caller if you program it into the arrays, but only if. You could use that to call in to hear if a machine is still running or whatever. We for example do a lot of remote printing because we have multiple locations with VPNs back and forth. With our 3Com system, we would routinely call and hear if a printer was running. You don’t have to do this, but the option is free. It’s also set to check if $src < 1, because if the caller ID for some reason was a string, it might resolve as 0.
Anyway, I hope that you’ll give this approach serious consideration, because I believe it gives an intercom functionality that will allow everyone to get what they want, and not be forced to either (1) have intercom across the board, (2) have no intercom, (3) use *80 which has serious privacy issues, is tedious and doesn’t work with BLF, or (4) set up double extensions for everyone to page them. Extension-to-extension intercom is what everyone wants, and you can readily find hundreds of forum postings where people ask how to do it.
I think that this proposed solution is flexible enough, and simple enough, that it’s right for FreePBX. Not the code, good heavens no. The concept.
Best,
Per