Friday, July 26, 2013

FreePBX 2.10 or 2.11 & Asterisk dynamic phone locking application

(image courtesy of


We had a couple of clients requested this function of on the fly locking and unlocking functionalities independent of the phone manufacturer. This means also web phones, softphones and mobile softphones and what not. There are so many unmaintained hacks out there and most of the stuff in contributed modules are either not working or they cannot integrate properly or they’ve not been maintained for newer versions of FreePBX.

So I decided to write a small dialplan with the relevant recordings for you to use straight off. Please however read the following and as usual please send your feedbacks if something didn’t work or just to say hi :)

Notes and disclaimers

  1. This specific dialplan and instructions are designed for FreePBX 2.10 or higher and Asterisk version 1.8 or higher. You most probably can use them for older versions, but it is not covered in this guide though
  2. It is extremely important to define and test out the emergency numbers before rolling out. Malaysian emergency number is 999, change or add more as you wish, add as many exceptions by just copy pasting that 999 line and add the copied line below 999 and modify accordingly.
  3. Please ensure you test this, as this hooks the first priority of any given device (extension) in FreePBX, it may break custom context* module. So if this is broken, no devices/extensions can call out
  4. It uses AstDB to store the pin numbers, so drama there.
  5. It is tested with extensions mode or device and user mode
  6. It comes with the recordings which you can download from here
  7. I do not guarantee the functionality with heavily modified FreePBX setups
  8. This assumes all extensions uses the from-internal context. If you use custom context modules and name your context say “National-Calls” for instance, then whatever you see in the [from-internal-custom] needs to be also set in [National-Calls-Custom] as the custom context module includes custom dialplans too.
  9. You may use BLFs to indicate locking statuses, but the hints “declared” done inside from-internal[-custom] contexts or which context you’ve set as the hints context, i.e. subscribecontext value in sip.conf or sip_general_custom.conf or the SIP Settings in Settings. Leave it default(unset) if you’re not sure. You have to define for each extension you wan’t to use BLFs, in this example below, its extension 8001
  10. TTS sounds courtesy of AT&T Natural Voices® Text-to-Speech Demo
  11. Parts of the dialplan were taken off various web sources, but mainly it came from forums
  12. We always have a master pin to ensure you can help those who’ve not remembered their PINS (of course, the other way is to list astdb entries for that extension)


  • Dial *159 to set phone lock
  • Dial any number you wish to dial and enter the pin to unlock
  • Unlock masterkey is 2606 incase someone forgets


Steps to get this working on an unmodified core of FreePBX 2.10, 2.11. Be sure to read instructions and notes inside the dialplan too.

  1. Edit the file in /etc/asterisk/extensions_custom.conf. Paste the following diaplan there:

    include => app-create-pin
    ;;;;;;;;;;;;;;;; Emergency and exceptions;;;;;;;;;;;;;;;
    exten => 999,1,Goto(from-internal,${EXTEN},1)
    exten => 8001*159,hint,Custom:8001*159
    exten => _.,1,Macro(predial-checks)
    exten => s,1,NoOp(Phone locking module starting..)
    exten => s,n,Gotoif($[${DB_EXISTS(AMPUSER/${CALLERID(num)}/locked)}=0]?proceed)
    exten => s,n,Set(PINCOUNT=0)
    exten => s,n(readpin),Read(PIN,custom/lockunlock,,,1,5)
    exten => s,n,Set(MASTERUNLOCKER=2606)
    exten => s,n,GotoIf($[${PIN}=${MASTERUNLOCKER}]?unlocked)
    exten => s,n,Gotoif($[${PIN}=${DB(AMPUSER/${CALLERID(num)}/locked)}]?unlocked)
    exten => s,n,Set(PINCOUNT=$[${PINCOUNT}+1])
    exten => s,n,GotoIf($[${PINCOUNT}>2]?toomanyerros)
    exten => s,n,Playback(custom/wrongpintryagain)
    exten => s,n,Goto(readpin)
    exten => s,n(endit),Playback(an-error-has-occured)
    exten => s,n,Playback(terminating)
    exten => s,n,Hangup(16)
    exten => s,n(toomanyerros),Playback(custom/toomanyerrors)
    exten => s,n,Playback(terminating)
    exten => s,n,Hangup(16)
    exten => s,n(unlocked),NoOp(${DB_DELETE(AMPUSER/${CALLERID(num)}/locked)})
    exten => s,n,Set(DEVICE_STATE(Custom:${CALLERID(num)}*159)=NOT_INUSE)
    exten => s,n,Playback(custom/unlockedsuccess)
    exten => s,n,MacroExit()
    exten => s,n(proceed),NoOp(${DB_DELETE(AMPUSER/${CALLERID(num)}/locked)})
    exten => s,n,MacroExit()
  2. [app-create-pin]
    exten => *159,1,NoOp(In Set Lock)
    exten => *159,n,Read(PIN1,custom/enterpinnumber,,,,)
    exten => *159,n,Read(PIN2,custom/confirmpinnumber,,,,)
    exten => *159,n,Gotoif($[${PIN1}=${PIN2}]?setpin)
    exten => *159,n,Playback(custom/invalidverify)
    exten => *159,n,Hangup(16)
    exten => *159,n(setpin),Set(DB(AMPUSER/${CALLERID(num)}/locked)=${PIN1})
    exten => *159,n,Set(DEVICE_STATE(Custom:${CALLERID(num)}*159)=RINGING)
    exten => *159,n,Playback(custom/locksuccess)
    exten => *159,n,Playback(goodbye)
    exten => *159,n,Hangup(16)

  3. Note, if you already have something in [from-internal-custom], the ones I add above needs to be right on top. The code for locking is inside [app-create-pin] and the code for checking and unlocking is inside [macro-predial-checks].
  4. Download and store the recordings in the /custom folder
    # cd /var/lib/asterisk/sounds/custom
    # wget  -O phonelocker.tar.gz && tar -zxvf phonelocker.tar.gz
  5. Change ownership of these files to the asterisk daemon user/group you’re running with, in many cases and also in my case its “asterisk/asterisk”
    # chown asterisk:asterisk confirmpinnumber.wav
    # chown asterisk:asterisk enterpinnumber.wav
    # chown asterisk:asterisk invalidverify.wav
    # chown asterisk:asterisk locksuccess.wav
    # chown asterisk:asterisk lockunlock.wav
    # chown asterisk:asterisk toomanyerrors.wav
    # chown asterisk:asterisk unlockedsuccess.wav
    # chown asterisk:asterisk wrongpintryagain.wav
  6. Reload asterisk dialplans
    # asterisk -rx "dialplan reload”
  7. Test by dialing *159, lock ya phone!
  8. Dial anywhere and unlock it with the pin you set in item 6 just now.
  9. Be sure to test dialing your emergency numbers
  10. If you want to use BLFs, here’s a screenshot of blfs using a Yealink phone, the key item here is 8001*159 as the hint code for the phone, 8001.
  11. Hints are currently set to blink when locked or the DEVICE_STATE of “ringing”.

Good luck and happy securing your phones!

Sunday, July 14, 2013

FreePBX 2.11 and Asternic mp3/database conversion/update post recording script

Hello all, got a confirmation from Nicolas on Asternic and FreePBX 2.11 and as suspected, its no longer needed to apply the post recording patch called anymore. FreePBX 2.11 has already a place to add a post-recording script (which is what the patch from Nicolas/Asternic does anyway in the older versions). All existing patches won’t work on FreePBX 2.11, just so you know. Now, it is done more elegantly :) and you won’t have to keep patching when there’s a new release of  FreePBX Core/Framework or updates.

Here’s how:

  1. Read Asternic’s INSTALL file, when it comes to patching, do this instead if you’re using FreePBX 2.11 only, all other lower versions please use Asternic’s guide
  2. Log on to FreePBX
  3. Click on Settings | Advance Settings
  4. Turn on Display ReadOnly Settings & Override Readonly Settings like below (be sure to check the tiny checkbox after changing each field)
  5. Click Apply_Conf
  6. Refresh the page by hitting F5 or similar on your browser
  7. Now, under Developer and Customization, locate “Post Call Recording Script”
  8. In the empty field there, paste this exactly like this below;

    /usr/local/parselog/ ^{UNIQUEID} ^{MIXMONITOR_FILENAME}

  9. Again, be sure to hit that tiny check and then apply_conf again, and you’re done.
  10. Also, you might want to turn on the setting that enables it to convert to MP3, it is in the file /usr/local/parselog/
  11. Also also, be sure to set the correct Database Username/Password there and the location of the folders in which the records will be converted or moved exist and has the same rights as Asterisk daemon user
  12. I’ve had numerous times had to create arbitrary files in the “dest” directory first then do #chown -R asterisk:asterisk /var/spool/asterisk/asternic (where asterisk is the user/group which the asterisk daemon runs as)
  13. Follow the rest of the INSTALL guide
  14. NOTE: This is applicable for incoming calls, the outgoing call method is still the same, done via dialplan, and if you want a how-to for that too, here’s how
  15. Be sure to set your queues to record in WAV!, Enjoy Asternic!

Busy Lamp Field (BLF) and the Custom Context module

Hi guys, you may have this “issue” where BLFs do not work after using other than from-internal contexts? Well the fix is pretty simple, just head on to Advance SIP settings, and add a line right at the bottom like this:


Add: subscribecontext = from-internal

Now you can use your Custom Context modules and still have good fun with BLFs.

Add streaming music to FreePBX 2.10 or 2.11/Asterisk

Hi guys, here’s a simple guide many have been asking how to add streaming music to your FreePBX box’s MOH

  1. Login to FreePBX
  2. Click on Settings, click on Music on Hold
  3. Click on Add Streaming Category
  4. In the application section, add this: /usr/bin/mpg123 -q -s --mono -r 8000 -f 8192 -b 0
  5. Submit Changes, Apply configuration
  6. Now, make sure mpg123 has the appropriate permissions. In Debian OSes, it is located in /usrbin/mpg123, so do this below
  7. #chown asterisk:asterisk /usr/bin/mpg123
  8. And done!, you’ve got internet streaming straight off Asterisk.

Here’s some sources:

Basically anything that’s HTTP based streaming can work here!