Friday, July 26, 2013

FreePBX 2.10 or 2.11 & Asterisk dynamic phone locking application


(image courtesy of www.unlock.my)

Introduction

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 freepbx.org 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 freepbx.org 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)

Usage

  • 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

Installation

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:

    [from-internal-custom]
    include => app-create-pin
    ;;;;;;;;;;;;;;;; Emergency and exceptions;;;;;;;;;;;;;;;
    exten => 999,1,Goto(from-internal,${EXTEN},1)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    ;;;;;;;;;;;;;;;;;;;;HINTS;;;;;;;;;;;;;;;;;;;;;;;;;
    exten => 8001*159,hint,Custom:8001*159
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    exten => _.,1,Macro(predial-checks)
    [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
    http://goo.gl/x1U0gw  -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.
    image
  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 update_mix_monitor.pl 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)
    image
  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/update_mix_mixmonitor.pl ^{UNIQUEID} ^{MIXMONITOR_FILENAME}

    image
  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/update_mix_mixmonitor.pl
  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:

image

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 http://voxsc1.somafm.com:8502/
  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: http://somafm.com/

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

Saturday, May 11, 2013

Archive script for FreePBX recordings (Asternic recordings)

Hi guys, just setup cron for this script and it will at the time you specify do a move, copy or delete files based on n number of days. If run manually, it will be like this; say I want to archive any files or directories older than 14 days, I can run it like this;

# archivefiles 14

This will set actions on folders older than 14 days. Remember, for folders, it will not traverse within each files inside folders to determine its age, it will only check the subfolders within the specified folder. However, you can specify the depth but that’s not recommended to change to other than 1. Modify as you wish, its yours to test. If you want to check the output, do a copy first, don’t do a move, thus MOVE=0 must be set. The newer Asternic and Asterisk recordings do store files by directories and not mixed up inside

Just copy paste into into an appropriate location and either setup a cronjob, e.g. below, or run manually from CLI

Crontab daily..

@daily /usr/local/sbin/archivefiles 14

Copy paste the script below, make it executable by #chmod +x archivefiles

 

#!/bin/bash
# sanjayws@gmail.com
# usage #archivefiles 14 (meaning archivefiles will find files older than 14 days to do a move or copy)
#
# DEFINE THESE
SOURCEPATH=/var/spool/asterisk/monitor-mp3/
# With trailing / (slash )
SOURCEFILENAME=*
# filetypes to archive when archiving by main folder files .e.g *.mp3 for mp3 only files
DEST=/usr/usbhdg1/asterisk-recordings/
# With trailing / (slash )
MOVE=1
# NOTE:0 - copy, 1 - move, 2 - delete
#
# START THE SCRIPT
# CHECK IF OLDER THAN VARIABLE DEFINED
#
OLDERTHAN=$1
if [[ $OLDERTHAN = "" ]]; then
        echo "Define a period. Like 14 for older than 14 days"
    exit 1
else
        echo ""
fi

# CHECK IF VALUE ENTERED IS AN INTEGER
#
if [ $OLDERTHAN ]; then
    if [ ! $(echo "$OLDERTHAN" | grep -E "^[0-9]+$") ]; then
        echo $OLDERTHAN is not a valid integer.
        exit 1
    else
    if ! [ $OLDERTHAN -ge 0 ] || ! [ $OLDERTHAN -le 10000 ]; then
        echo $OLDERTHAN is an invalid value. Range is [1-10000]
        exit 1
    fi
    fi
fi

# CHECK IF SOURCE DIRECTORY EXIST
#
if [[ -d $SOURCEPATH ]]; then
        echo "OK - Source directory exits"
        cd $SOURCEPATH
else
        echo "Source Directory not found, check your settings... quitting"
        exit 1
fi

grabfiles=`ls -l  $SOURCEPATH | head -n 1 `
if [[ $grabfiles != "" ]]; then
        echo "OK - Source files exist"
else
        echo "Oops, no source files, check your settings...quitting"
        exit 1
fi
       
# CHECK IF DESTINATION EXISTS
#
if [[ $MOVE = "1"  ]];then
   
    #first way by files
    #find  $SOURCEPATH$SOURCEFILENAME -maxdepth 0 -mtime +$OLDERTHAN -exec mv -f {} $DEST \;
    #second way by directory
    for i in `find $SOURCEPATH -maxdepth 1 -type d -mtime +$OLDERTHAN -print`; do mv -f $i $DEST; done
   
elif [[ $MOVE = "0" ]]; then

    #first way by files
    #find  $SOURCEPATH$SOURCEFILENAME -maxdepth 0 -mtime +$OLDERTHAN -exec cp -f {} $DEST \;
    #second way by directory
    for i in `find $SOURCEPATH -maxdepth 1 -type d -mtime +$OLDERTHAN -print`; do cp -f $i $DEST; done
   
elif [[ $MOVE = "2" ]]; then

    #first way by files
    #find  $SOURCEPATH$SOURCEFILENAME -maxdepth 0 -mtime +$OLDERTHAN -exec rm {} $DEST \;
    #second way by directory
    for i in `find $SOURCEPATH -maxdepth 1 -type d -mtime +$OLDERTHAN -print`; do rm -r $i $DEST; done
fi   


exit 0

Saturday, April 27, 2013

Modifying transfer contexts in FreePBX 2.10 higher or lower, and applying restrictions

(Image copyright PizzaHut Malaysia, QSR Brands)

Few days back, we dealt with a challenge to lock down phones in a callcenter of PizzaHut Malaysia. That was easy, we fired up a specialized context which I developed that uses Device User Mode based restriction. (If you wanna know more, about that, write me!). Now, we had a daunting task of getting the same kind of restrictions applied to user who perform transfers. By default, transfers are applied using the context “from-internal-xfer”. This is previously definable in FreePBX Advance settings, somehow it is now not available through the GUI. We had to make the same kind of restriction to those doing transfers too, so what we had to do, using Adminer (GUI database manager), look for a value in DB asterisk, table freepbx_settings called “from-internal-xfer”, for freepbx 2.10, look in asterisk DB, table, Globals, we changed that to “from-internal-xfer-phm”. Now, we forked the context out into our own little coding like here. Do note, after making changes in the DB, you need to make a change in the FreePBX gui, somewhere, and hit on the “Apply Config” button to materialize these changes.

To verify, run # asterisk –rx “dialplan show globals” and it should show you “TRANSFER_CONTEXT=from-internal-xfer-phm” or whatever you’ve called it.

Now that we are able to control transfers using our own context, we had to do it right and properly not to break other transfer functions with those whom are not bound by these restrictions.

In this example below, I have agents in Device Usermode, logged in as a 6XXX extension. What we are required to do is to not allow transfers using phone (button transfer) or even Asterisk code *2. Now, with the phone we had to modify the Asterisk SIP Setting and add a value like below, in the other SIP Setting;

allowtransfers=no

That fixed the phone transfers, no one can use transfers using SIP invites anymore directly. Cool.! Now, we force users to use *2 instead and when that code is pressed, the calls are being thrown to context [from-internal-xfer-phm]

In this context below, if any calls originating from 6XXX, retrieved from variable “PICKUPMARK” and is doing a transfer, looking at variable “TRANSFERNAME” which basically is populated when # transfers happen; we perform a soft hangup when those conditions are met, like below, otherwise, all others, we send back to the normal from-internal context, and basically allowing them to transfer it to wherever they like. , using this, you are free to write further more complex conditions as you please.

[from-internal-xfer-phm]
exten => _[4-6]XXX,1,ExecIf($["${PICKUPMARK:0:1}" = "6" & "${TRANSFERERNAME}" != "" ]?SoftHangup(Local/${EXTEN}))
exten => _X.,1,Goto(from-internal,${EXTEN},1)

 

Notes on the context above:

1) We catch calls in transfers made that start with digits 4 to 6, to digit “6” i.e. the call center agents. (We don’t want callcenter agents to call each other or in this case, transfer calls to each other)

2) It must be a transfer, i.e. must have the value TRANSFERNAME populated with something (With the two conditions above met, we do as below…, softhangup)

3) We softhangup the destination, i.e. EXTEN, causing the call to come back to the transferee

 

Have a good weekend folks!

Thursday, April 25, 2013

Asterisk –Debian based Asterisk 11, Freepbx 2.11 on VMware / Virtualbox (Asterisk VM/Asterisk Ready Virtual Machine)

Show some love,  do like our FB page www.fb.com/Astiostech |

[UPDATED: 03 FEB 2015]

Here’s a VMDK image to run a full featured Asterisk PaBX with FreePBX as the management UI using our default and secure install practices. No registrations, no username/password, no signing up for newsletter.

Get it from Sourceforge: https://sourceforge.net/projects/debianasterisk/[Select SWSterisk11 folder, then download the zip file therein]

 

After extracting, You either need VirtualBox or VMPlayer/VMWare or any Virtualization products that supports VMDK files or if you’re using Hypervisor, convert the image to VHD using MVMC from here.  This is to give you a feel of Asterisk with FreePBX without worrying about installation etc., its plug and play, literally. Just start up to your VirtualBox/VMplayer nd get it up and running in seconds. Go in to FreePBX and start creating extensions and enable other features. This image is free from any lockdowns or customizations that you cannot reverse or disable or enable as you wish. It is completely FREE from any personal restrictions. This image does not trace usage, or “dials home” or anything strange like that. Totally clean, totally lean and totally fast. It is functional and you can hook it up to a real production environment and you almost have a full fledge PBX, just add a Digium VoIP Gateway or another IP based PSTN.

IMPORTANT

  • While it is enterprise ready, it should rather be used for “playing” or “testing”….
  • DISCLAIMER: By using this VIRTUAL MACHINE IMAGE, i disclaim any sorts of liability whatsoever. What you do with this image is purely your choice/actions.
  • This is not "another disto", nothing proprietary, i don't claim any copyrights, just make it look and feel like its mine for fun, but of course any of those customizations can be reversed. All other trademarks are properties of their respective owners. All rights reserved.
Here’s some information about the VM image you just downloaded
  • It’s in ZIP compression, just get WinRAR or 7-ZIP to extract. After extracting, there should be one vmdk just mount the vmdk into VMWare/VMPlayer or Virtualbox and start the image
  • Username/password
  • OS
    - Username: root (the other non root user is swsterisk with same password as below)
    - Password: asteriskrocks (change this!)
  • FreePBX(admin), MySQL(root), AMI(admin): usernames and passwords;
    username: admin
    password: @steriskRocks1 (change this, here’s a good guide to start you off with http://www.freepbx.org/support/documentation/installation/first-steps-after-installation)
  • REMEMBER REMEMBER REMEMBER: CHANGE PASSWORDS!
  • The network adapter is set to auto on eth0.
  • Image needs at least 384M memory (or more if you have more)
  • All source files except kernel-headers are removed to save disk space for downloading, you need to download them manually
  • Be sure your image can access internet when starting otherwise NTP and EXIM will start slow, don’t blame me!

OS features/settings

  • Debian 6.0.7 64bit (Source AMD64 netinstall) – UPDATED, Bash Vulnerability Fixed with latest patch no33, SSLV3 disabled and Ghost Vulnerability fixed. All binaries are retrieved from Debian’s 6 LTS repos. So they are up to date.
  • The interface, extX, is set to use DHCP, so be sure to hook up DHCP or manually. In case you can’t bring the interface up, run #ifconfig –a . Then edit the file in /etc/network/interfaces and set all values to correspond to the interface shown when you run ifconfig –a (not loopback of course)
  • IPV6 disabled
  • MySQL backend (performance tuned)
  • Webmin installed but not started (# /etc/init.d/webmin start , then access using https://<ipaddress>:10000)  - UPDATED!
  • Apache as webserver with enforced HTTPS
  • MySQL administration with Adminer in https://<ipaddress>/dbmanager  - UPDATED!
  • DHCP and TFTP server downloaded, not installed
  • Firewalled with IPTables (be sure to see /bin/wallfire.sh) – UPDATED and fixed wallfire.sh script …can be stopped and started #wallfire stop #wallfire start
  • Time i.e NTP autosyncs with ntp.org daily, when starting and when stopping
  • Exim4 (mailserver) configured to relay, configure your email appropriately #dpkg-reconfigure exim4-config
  • fail2ban for Asterisk and SSH with enhancement to the log checking facility which includes asterisk security channel inside messages log (modify notification email here /etc/fail2ban/jail.conf) – UPDATED to 0.9.1!
  • Munin for monitoring in https://<ipaddress>/munin
  • Phpsysinfo for server information in https://<ipaddress>/phpsysinfo
  • Many CLI tools for troubleshooting like tcpdump, ntop, htop…
  • Astribank support [if ever u need it]
  • Removed VirtualBox OSE support to make it more cross platform compatible.
Asterisk features
FreePBX features
  • https://<ipaddress> to access FreePBX
  • FreePBX 2.11.0.38 (with only basic modules pre-installed) - UPDATED
  • Enhanced FreePBX security built in
  • SIP defaults to NAT yes (avoid all one way audio issue)
  • Security basic hardening in extensions
  • CEL support in FreePBX CDR
  • Enabled g729, speex and silk (enabled for IAX and SIP)
  • Most services are started with /etc/init.d/btelsvc

Additional reading

 

As usual do give me your feedback. ==> sanjay(the at symbol)astiostech.com

Thanks!
Sanjay Willie

Monday, March 4, 2013

Asterisk or FreePBX call alert script (e.g. for sudden spike in international calls) that runs independently or via Nagios (Nagios compatible)

Lets face it, some of us may have had our share of FreePBX/Asterisk compromises and abusers almost always use the facility to make international calls to exotic numbers. The bill at the end of the month is already too late and there’s significant monetary damage. While its good to know in realtime of what’s going on, its of course best to prevent anything to compromise your server. see this guide here to get you started.

Here’s a small script we wrote that works for me to check as often as cronjob/Nagios allows it to, based on the parameters you set and report back via email if the script is triggered.

This script here does the following;

  • It checks the CDR for n minutes of past records also set by flags
  • Uses filters based on the dst column on your CDR to match that you specify during execution (the parameters), this can be prefixes or whole numbers, and run multiple instances. 
  • You can set the flag to check the prefix and the number of digits which is same or greater so that you won’t catch local calls, normally international calls have higher number of called digits, i.e. > 10
  • To automatically check or do it almost realtime, you can use cron on your server locally (It can also work with Nagios too, however, this guide does not cover configuring on Nagios, set NAGIOSMODE=YES). If you set Nagiosmode, it will not independently send out email and instead your Nagios server will decide what to do according to what you’ve set it to.
  • Be sure to change SYSADMINEMAIL, FROMUSER,SERVER,PORT,DATABASE,TABLE,USER,PASS in the script relevant to your setup

Getting started:

  1. Copy paste this script below in /usr/bin/checkintl.sh (or any location of your choice)
  2. Modify the parameters as described below
  3. Make it executable (chmod +x /usr/bin/checkintl.sh)
  4. Put this script in a cronjob if you wish to automate checking (crontab –e), e.g. like this     */15 * * * * /usr/bin/checkintl.sh -w 5 -c 10 -i 30 -p 00:6,900:6"
    • Above cronjob does the checks for every 15 minutes 30 records in CDR and warns on 5 critical alerts on 10 for pattern 00, with length greater than or equals 6 numbers and for pattern 900 with length greater than or equals 6 numbers
  5. Test manually. You surely can run this manually and try to invoke the trigger by making n number of calls and you should get an email alert based on the email address you specified
  6. This script requires a MySQL CDR for Asterisk (therefore making it perfect for use with FreePBX, out of the box)
  7. IMPORTANT: THIS SCRIPT CHECKS AFTER ASTERISK WRITES TO CDR AND ALSO WHILE IN CALL COMBINED, SO CHECK BOTH PLACES

Set these below before running the script

  • The emailtoSYSADMINEMAIL, emailFROMUSER,SERVERip,serverPORT,cdrDATABASE,cdrTABLE,dbUSER,dbPASS
  • If using Nagios, just set the flag NAGIOSMODE=YES
  • Everything copied from below must be in a single line, no line breaks

Here’s the script, copy paste this as per item 1. getting started guide.

###PASTE START###

#!/bin/bash
RELEASE="Version 2"
AUTHOR="sanjay@astiostech.com"
PROGNAME="checkintl.sh"
#
# PRE-REQ
# – BASH 4.1.X or higher
# – FREEPBX and MYSQL of course
# - ASTERISK WITH CDR SUPPORT
# - ACCESS TO ASTERISKCDR DB
# – CLI tools like mail, awk, tr, curl,grep,mysql bin

# - ABLE TO SEND EMAIL OUT USING #mail with exim etc..
#
# ChangeLog
# - FIRST RELEASE
# - 1.1 Minor changes encapsulating output for compatibility
# - 2.0 Updated checking algorithm
#
# Place a cronjob, e.g. check every 5 minutes
# */15 * * * * /<locationofscript>/checkintl.sh
#
# NOTHING TO CHANGE HERE
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
USERDATEFORMAT=`date +%d-%m-%Y_%H:%M:%S`
#
########MODIFY HERE
########
NAGIOSMODE=NO
SYSADMINEMAIL=youradmin@yourdomain.com #add more separated by commas
FROMUSER=youruser@yourdomain.com
EMAILSUBJECT="CALL ALERTER – By Astiostech"
server="localhost"
port="3306"
database="asteriskcdrdb"
table="cdr"
user="<mysqluser>"
pass="<mysqlpass>"
########END MODIFY########
#
#
##FUNCTIONS
function sendoutmail()
{
( echo [$USERDATEFORMAT] - $2 ) | mail -aFrom:$FROMUSER -s "$EMAILSUBJECT" $SYSADMINEMAIL
return
}
#
print_release() {
    echo "$RELEASE $AUTHOR"
}
#
print_usage() {
    clear
    echo ""
    echo "$PROGNAME $RELEASE - Checks international calls"
    echo ""
    echo "Usage: checkintl.sh [flags]"
    echo ""
    echo "e.g  : ./checkintl.sh -w 5 -c 10 -i 30 -p 00:6,900:6"
    echo "Where it warns at 5 intl calls, and makes a critcal alert 10 calls at every 30 minutes "
    echo "of past CDR record for prefixes 00 and 900 combined total of equals to or higher than 6 digits"
    echo ""
    echo "Flags:"
    echo "  -w <number> : Warning value for number of international calls."
    echo "  -c <number> : Critical value for number of international calls"
    echo "  -i <number> : How many minutes of CDR data to poll to evaluate"
    echo "  -p <prefix:length,prefix:length,prefix:length> : Comma separated prefixes with IDD, e.g. 900:5,800:5,00:5. Length value is equals or higher. Default is 5 or higher chars"
    echo "  -h  Show this page"
    echo ""
    echo "Usage: $PROGNAME --help"
    echo ""
}
print_help() {
    print_usage
        echo ""
        echo "This plugin will check international calls made on Asterisk CDR"
        echo ""
    exit 0
}

# Parse parameters
while [ $# -gt 0 ]; do
    case "$1" in
        -h | --help)
            print_help
            exit $STATE_OK
            ;;
        -v | --version)
                print_release
                exit $STATE_OK
                ;;
        -w | --warning)
                shift
                WARNING_THRESHOLD=$1
                ;;
        -c | --critical)
               shift
                CRITICAL_THRESHOLD=$1
                ;;
        -i | --interval)
               shift
               INTERVAL=$1
                ;;
        -p | --prefix)
               shift
               PREFIXES=$1
                ;;
        *)  echo "Unknown argument: $1"
            print_usage
            exit $STATE_UNKNOWN
            ;;
        esac
shift
done
#
if  [[ "$WARNING_THRESHOLD" == "" ]]; then
    echo "Warning value not set, quitting.."
    exit $STATE_OK
fi
if  [[ "$CRITICAL_THRESHOLD" == "" ]]; then
    echo "Critical value not set, quitting.."
    exit $STATE_OK
fi
if  [[ "$INTERVAL" == "" ]]; then
    echo "Interval value not set, quitting.."
    exit $STATE_OK
fi
if  [[ "$PREFIXES" == "" ]]; then
    echo "You must define at least one prefix, quitting.."
    exit $STATE_OK
fi
#
# SET VARIABLES
warning_value="$WARNING_THRESHOLD"
critical_value="$CRITICAL_THRESHOLD"
interval="$INTERVAL"
PREFIX="$PREFIXES"
MYSQLBIN=`which mysql`
MYAST=`which asterisk`
#
# CONSTANTS
todate=`/bin/date`
unixtime=`/bin/date --date="$todate" +%s`
filename=mycdrlogforintl.$unixtime.txt
#
# DB CONNECTION CHECKER
checkdb=`$MYSQLBIN -b -n -N -s -h $server -P $port -u $user -p$pass -D $database -e "show databases;" | grep -c $database`
# START CHECKING CALLS
IFS=$OLDIFS
IFS=,
if  [[ $checkdb -lt 1 ]]; then
    echo "Error connecting to MySQL CDR DB"
    if [[ "$NAGIOSMODE" == "NO" ]]; then
        sendoutmail -f "Error connecting to MySQL CDR DB"
    fi
    exit $STATE_UNKNOWN
else
    for i in $PREFIX; do
        i=`echo $i | awk -F':' '{print $1}'`
        length=`echo $i | awk -F':' '{print $2}'`
        if [[ $length == 0 ]]; then
            length=5
        fi
        rawdata=`$MYSQLBIN -b -n -N -s -h $server -P $port -u $user -p$pass -D $database -e "SELECT dst FROM $table WHERE cdr.calldate > now() - INTERVAL $interval MINUTE and CHAR_LENGTH(dst) >= '$length';" | grep -o '[0-9]*' | grep -e '\<'$i'.*\>' | tr -d ' '`
        subtotal=`echo $rawdata | awk 'NF > 0' | wc -l`
        echo $rawdata >> /tmp/$filename
        ((totalcalls+=$subtotal))
    done
    for n in $PREFIX; do
        n=`echo $n | awk -F':' '{print $1}'`
        length=`echo $n | awk -F':' '{print $2}'`
        if [[ $length == 0 ]]; then
            length=5
        fi
        rawdata2=`$MYAST -rx "core show channels concise" |grep Outgoing | grep -e '\<'$n'.*\>' `
        if [[ "$rawdata2" != "" ]]; then
            subtotal=`echo $rawdata2 | awk 'NF > 0' | wc -l`
            echo $rawdata2 >> /tmp/$filename       
            ((totalcalls+=$subtotal))
        fi   
    done
IFS=$OLDIFS
fi
csved=`cat /tmp/$filename | tr -d ' ' | awk 'NF > 0' | tr "\n" ","`
#
# Now we start reporting to Nagios/sendmail if required
#
if [[ "$totalcalls" == "0" ]]; then
    echo "OK:$totalcalls |intl_calls=$totalcalls;$warning_value;$critical_value"
    exit $STATE_OK
elif [[ "$totalcalls" -ge "$critical_value" ]]; then
    echo "CRITICAL:$totalcalls LISTING:[START] $csved[END]|intl_calls=$totalcalls;$warning_value;$critical_value"
    if [[ "$NAGIOSMODE" == "NO" ]]; then
        sendoutmail -f "CRITICAL:$totalcalls LISTING:[START]$csved[END] | Critical threshold set: $critical_value"
    fi
    exit $STATE_CRITICAL
elif [[ "$totalcalls" -ge "$warning_value" ]]; then
    echo "WARNING:$totalcalls LISTING:[START] $csved[END]|intl_calls=$totalcalls;$warning_value;$critical_value"
    if [[ "$NAGIOSMODE" == "NO" ]]; then
        sendoutmail -f "WARNING:$totalcalls LISTING:[START] $csved[END] | Warning threshold set: $warning_value"
    fi
    exit $STATE_WARNING
else
    echo "TOTAL:$totalcalls LISTING:[START] $csved[END]|intl_calls=$totalcalls;$warning_value;$critical_value"
    exit $STATE_OK
fi

###PASTE END###

Tuesday, February 12, 2013

Asterisk/FreePBX Setting up and enabling Speex codec.

Why Speex?

  1. It works like SILK but, see item 2.
  2. Its an old codec thus supported by lots of phones as opposed to SILK

Environments (of course, improvise and modify for your respective OSes, it can run too far away from these)

  • Debian 6 32bit (somehow I messed up my 64bit or it doesn’t work well with 64 bit)
  • Asterisk 11
  • FreePBX

So the steps are simple as outlined here;

  1. # apt-get install speex speex libspeexdsp-dev libspeex-dev
  2. Go to your Asterisk source directory
  3. Do a #make clean && ./configure && make && make install
  4. NOTE: It should automatically notice Speex libraries are already installed and it will auto select, so don’t have to menu select whatnot.
  5. Once done make, restart Asterisk (#amportal kill && amportal start)
  6. Then you should be autoloading the codec, so # asterisk –rx “core show translation”     should show you speex

    speex 15000 15000 15000 15000 15000  9000 15000     -   23000 15000    15000 17250  17000   15000   23000  17000  17000  17000  17000  17000  17000   17000
    speex16 23500 23500 23500 23500 23500 17500 23500 23500       - 23500    23500 15000   9000   23500   23000  17500  17000  17000  17000  17000  17000   17000

  7. Otherwise, manually load #asterisk –rx “module load codec_speex.so”
  8. If you hit errors, lookout for the full log…
  9. Now, if speex is loaded properly, go to the IAX/SIP Setting pages in FreePBX and enable speex codec respectively
  10. That should now allow you to use speex in the extensions/devices you’ve configured

And you guessed, it, here’s the cliché, Enjoy Speex-ing…

More Asterisk related codec.conf configuration on Speex can be found here:

PS> What Codec we really want to consider in future and see it released to support Asterisk?.
OPUS. I believe this one codec will rule them all. Till then, we use bits like SILK and SPEEX and sometimes g729 to get our very cranky networks to play nice with VoIP audio.

Saturday, February 2, 2013

Setting up SILK Codec with Asterisk 10/11

Wikipedia on SILK: http://en.wikipedia.org/wiki/SILK
This guide takes you through the setup of SILK codec with Asterisk 11. It also can be used to setup Asterisk 10.
While it should work for other environments, this particular guide was written for
1) Debian
2) Working Asterisk 11 (try this article if you want a how-to)
Why use Skype’s SILK?
Here’s the quick how-to (Parts of this guide was taken from Asterisk Wiki here )
  1. Download the  benchmark tool based on your processor architecture. In my case I am using 64 bit so I downloaded the x86_64. Browse to http://downloads.digium.com/pub/telephony/codec_silk/benchsilk/ for options. Copy the URL and do the wget like below
    # cd /usr/src
    # wget
    http://downloads.digium.com/pub/telephony/codec_silk/benchsilk/x86-64/benchsilk-1.0.0-x86_64
    # chmod +x bench*
    # ./benchsilk-1.0.0-x86_64
  2. After this you will see the recommendation made from the benchmarking tool. Since I was running a VM for writing this, my winner was “generic”, so I headed to this http://downloads.digium.com/pub/telephony/codec_silk/ link, selected my Asterisk version, and selected the processor architecture, which was x86_64, then copied the generic codec url to do wget with
    # wget http://downloads.digium.com/pub/telephony/codec_silk/asterisk-11.0/x86-64/codec_silk-11.0_1.0.0-generic_64.tar.gz
    # tar –zxvf codec_silk*
    # cd codec_silk-11.0_1.0.0-generic_64     (or whatever version of yours directory name)
    # cp codec* /usr/lib/asterisk/modules/
  3. Now put up some configs for codecs.conf
    # nano /etc/asterisk/codecs.conf         (create the file if don’t exist). Paste below all variations this codec
    [silk8]
    type=silk
    samprate=8000
    fec=true
    packetloss_percentage=10
    maxbitrate=20000
    dtx=false

    [silk12]
    type=silk
    samprate=12000
    fec=true
    packetloss_percentage=10
    maxbitrate=25000
    dtx=false

    [silk16]
    type=silk
    samprate=16000
    fec=true
    packetloss_percentage=10
    maxbitrate=30000
    dtx=false

    [silk24]
    type=silk
    samprate=24000
    fec=true
    packetloss_percentage=10
    maxbitrate=40000
    dtx=false
  4. Save and exit
  5. Load the codec
    # asterisk -rx "module load codec_silk.so"
    You should see it return as “Loaded….”
  6. Now, check the translations and codecs
    # asterisk –rx “core show translation”
    # asterisk –rx “core show codecs”
  7. Sometimes, you might need to start and stop asterisk for it to show up in the codec translation table (and for it to work)
  8. On both command executions, you should see in those outputs the words SILK8, SILK12, SILK16, SILK24
  9. Be sure to “allow” this codec for each of your extensions, or sip general settings
    And for each extension, be sure to setup like this
    disallow=all
    allow=silk8 ;;;
    or whatever silk band you fancy, I use the narrowband as its important to use smallest bandwidth
  10. Connect using phones that support SILK, set those phones to only use SILK in its list of codecs based on the frequency you’ve “allowed”, in the case above, 8Khz. Typically, 8Khz band will only use 5-20kbps :)
  11. Checkout this document on the payload. The codecs.conf gives you the ability to tweak for poor network conditions too like on Wifi roamers….
Phones that support SILK in my tests:
  1. CSIPSimple for Android Mobile
  2. Basically anything using the PJSIP stack (which has become my favorite softphone….), e.g. http://microsip.org.ua/
Lots other phone vendors also do support SILK but it will probably come slower: Anyway, the PJSIP MicroSIP, I was making calls clean and flawlessly over Wifi
image