Speed dial on Asterisk

It’s fairly simple to setup a programmable speeddial with asterisk. All with a option to playback what speed dials you have setup.

You’ll need to setup the dialplan to handle the extensions for the speeddial. For me, I choose a *29 to setup the speed dials, then *3X, *4X, and *5X as the actual speed dials. *30, *40, *50 are reserved for playback (see later). I used each range to hold different meanings. *3X was for family, *4X was for friends, and *5X was for restaurants. These instructions should give you enough to set it up and change it to what you’d like.

In your main dialplan (house for this example) in your extensions.conf file:

[house]

;; Normal outgoing rules, whatever you have for your outgoing provider
exten => _ZXXXXX.,1,Dial(SIP/${EXTEN}@PROVIDER)

;; Start of speed dial rules, go at the end of your main dialplan
exten => *29,1,Goto(speeddial,create,1)
exten => *30,1,Goto(speeddial,answer,Speed30)
exten => *40,1,Goto(speeddial,answer,Speed40)
exten => *50,1,Goto(speeddial,answer,Speed50)

;; This handles all the speed dials and will figure out what number to dial
;; and hand it back to your main dial plan. It'll also check to make sure
;; it's valid and if not, play a message indicating it's empty.
exten => _*[3-5][1-9],1,Answer()
exten => _*[3-5][1-9],n,Wait(1)
exten => _*[3-5][1-9],n,Set(NUMBER=${DB(speeddial/${EXTEN})})
exten => _*[3-5][1-9],n,GotoIf($["${NUMBER}" = ""]?BadNumber)
exten => _*[3-5][1-9],n,Playback(speed-dial)
exten => _*[3-5][1-9],n,Playback(call)
exten => _*[3-5][1-9],n,Playback(numbers/${NUMBER})
;; Hand it back to your main dial plan, ie "house"
exten => _*[3-5][1-9],n,Dial(local/${NUMBER}@house)
exten => _*[3-5][1-9],n,Hangup()
exten => _*[3-5][1-9],n(BadNumber),Playback(speed-dial-empty)
exten => _*[3-5][1-9],n,Hangup()

[speeddial]

;; Setup a new speed dial. Note: It won't let you enter any of the
;; playback speed dials, or outside the range
exten => create,1,Answer()
exten => create,n(Start),Read(NEW|custom/speeddial/speed-intro,2)
exten => create,n,Set(STEST=${DB_EXISTS(speeddial/*${NEW})})
exten => create,n,GotoIf($["${STEST}" = "1"]?Overwrite)
;; Put the *30, *40, *50 extentions here so you can't use them, also
;; adjust the range (ie: 31-->59)
exten => create,n,GotoIf($["${MATH(${NEW}<=30,int)}" = "TRUE"]?Start)
exten => create,n,GotoIf($["${NEW}" = "40"]?Start)
exten => create,n,GotoIf($["${NEW}" = "50"]?Start)
exten => create,n,GotoIf($["${MATH(${NEW}>=60,int)}" = "TRUE"]?Start)

;; Prompt for the new 10 digit outgoing number
exten => create,n(Number),Read(NEWEXT|custom/speeddial/enternumber|10)
exten => create,n,Playback(custom/speeddial/you-entered)
exten => create,n,SayDigits(${NEWEXT}
exten => create,n,Read(CHECK,custom/speeddial/correct-press1-otherwise-press-2,1)
exten => create,n,GotoIf($[${CHECK} = 2] ?Number)
exten => create,n,GotoIf($[${CHECK} = 1] ?Record)

;; Record a message indicating who this is (ie, Mother, Father, Friend's name etc...)
exten => create,n(Record),Playback(custom/speeddial/recordmesg)
exten => create,n,Record(numbers/${NEWEXT}:sln)
exten => create,n,Playback(numbers/${newext})
exten => create,n,Playback(custom/speeddial/thankbye)
exten => create,n,Set(DB(speeddial/*${NEW})=${NEWEXT})
exten => create,n,Hangup()

;; This just handles if you want to overwrite an existing speeddial
exten => create,n(Overwrite),Read(OVER,custom/speeddial/speed-overwrite,1)
exten => create,n,GotoIf($[${OVER} = 1] ?Number)
exten => create,n,GotoIf($[${OVER} = 2] ?PlayNumber)
exten => create,n,GotoIf($[${OVER} = 3] ?Start)
exten => create,n,Hangup()

exten => create,n(PlayNumber),Set(NUMBER=${DB(speeddial/*${NEW})})
exten => create,n,Playback(numbers/${NUMBER})
exten => create,n,Goto(Start)

;; If you dial *30, *40, *50 it'll start playing back all the speed dial recordings
;; starting that next higher one.
;; *30 starts playback at speed dial *31
;; *40 starts playback at speed dial *41
;; *50 starts playback at speed dial *51
exten => answer,1,Answer()
exten => answer,n(Speed30),Set(SDIAL=31)
exten => answer,n,Goto(StartPlay)
exten => answer,n(Speed40),Set(SDIAL=41)
exten => answer,n,Goto(StartPlay)
exten => answer,n(Speed50),Set(SDIAL=51)
exten => answer,n,Goto(StartPlay)

;; You can dial any speed dial number while it's going through the playback.
exten => answer,n(StartPlay),Set(TIMEOUT(digit)=2)
exten => answer,n,Set(TIMEOUT(response)=60)
exten => answer,n,Wait(1)
exten => answer,n(Playnumber),Set(STEST=${DB_EXISTS(speeddial/*${SDIAL})})
exten => answer,n,GotoIf($["${STEST}" = "0"]?Add1)
exten => answer,n,Set(NUMBER=${DB(speeddial/*${SDIAL})})
exten => answer,n,Background(press-star)
exten => answer,n,SayDigits(${SDIAL})
exten => answer,n,Background(for)
exten => answer,n,Background(numbers/${NUMBER})
exten => answer,n(Add1),Set(SDIAL=${MATH(${SDIAL}+1,int)})

exten => answer,n,GotoIf($["${MATH(${SDIAL}>=59,int)}" = "TRUE"]?LastDial)

exten => answer,n,Goto(Playnumber)

;; Last number played, wait up to 60 seconds for them to press an * speed dial
exten => answer,n(LastDial),NoOp( No More )
exten => answer,n,WaitExten(60)
exten => answer,n,Playback(goodbye)
exten => answer,n,Hangup()

;; Handle the dialing of the speed dial, just pass it to the main dial plan (house)

exten => _*[3-5][1-9],1,Dial(local/${EXTEN}@house)

Here’s the zip file with the custom/speeddial sounds.  You’ll want to unzip this in your sounds/custom folder.

Enjoy!

No Comments »

on November 3rd 2010 in Asterisk

Gizmo and Asterisk 1.6

After upgrading to Ubuntu 9.10 which includes Asterisk 1.6 my Google Voice connection through Gizmo5 stopped working. Sound familiar?

The issue is that Asterisk 1.6 requires insecure=invite in the sip.conf definition for Gizmo.

Here’s my working config:
[gizmo]
type=peer
context=your-context-here
disallow=all
allow=ulaw
allow=gsm
dtmfmode=rfc2833
host=proxy01.sipphone.com
insecure=invite    <---Change this setting
secret=password-here
username=gizmo-number-here
canreinvite=no

Source: http://vaug.ca/pipermail/vaug/2009-March/000053.html

No Comments »

on December 18th 2009 in Asterisk

Asterisk voicemail sent to cell phone

Anyone whom uses asterisk knows that Asterisk can send voicemail notifications to your cell phone. Normally the Asterisk voicemail.conf file would look like this:

201 => 1234,Eric,my@email.com,CELLNUMBER@vtext.com,|tz=eastern|volgain=3.0

This would send a short text message to your cell phone indicating you have a new voicemail. It would also send the voicemail itself as an attachment to your email address. This example goes to a Verizon wireless cell phone. Once you get the notification you still need to check the voicemail. This could be as simple as dialing in from your cell phone to check on the voicemail remotely. Wouldn’t it be nice if you could just get the message directly to your cell phone? You can! The audio message that is attached is just a wave file that seems to be playable on most phones as a multimedia attachment. For Verizon you just need to send it to a different email address:

201 => 1234,Eric,CELLNUMBER@vzwpix.com,,|tz=eastern|volgain=4.0

This changes the email address to be the email address for Verizon’s MMS gateway. What shows up on the phone is PIX message with an audio component. You can then play the voicemail directly from your phone. I also had to adjust the volgain in order to raise the volume. Here’s the list for other cell carriers. I know it works for Verizon. In theory it should work many other carries and phones. Anyone who has luck with this, please post and let me know.

No Comments »

on July 13th 2009 in Asterisk

Sharing to friends in Google Reader

Google reader is a nice way to have all your RSS feeds in one place.   They even have a way to share an interesting article you want with other people, even friends.  I found this good, but wanted a better way to share to specific friends that would not be hard to manage.  I’ll show you a neat way to share articles with different people so they have their own customized view.

You first have to tag an article to start.  So just tag any article and call it something familiar that you’ll remember.  For this example I’m going to call it “eric” (I like just creating tags the name of my friends so it’s easy to remember).  Now you have a new tag called “eric“.  You want to make that tag public.  You’ll need to go into your Settings page, then Folders and Tags.  On that page you’ll see all your tags, find the “eric” tag and click on the icon to the left of the word private.  This will change that tag to public.  On the same line now to the right of it, you’ll see a view public page link.  You can click on that.  This is the page that you’d give to your friend.  You can either give them the public HTML page, or the RSS feed for it.  Now all that you need to do is just tag any articles with your “eric” tag, and your friend will see them.

Something great too, is the Notes area of Google Reader.  If you access your Notes, then can then drag the link they give you to share anything on the web.   When you do that, just click on your Note in Reader link, add a note if you’d like, then click on the Add tags to give it the “eric” tag of your friend.  You can un-check the “Add to shared items” even.

If you have multiple friends you can seperate the tags with a comma to share an article to multiple people.

I have also just used the Note feature to bookmark websites to go back to later.  It gives me the opportunity to search for something I’ve been to with the search feature in Google Reader.

This does make your page is public, so anyone can view it that has this special public page, just keep that in mind.

I’ve found this a lot easier to share out different articles to friends this way, and the Notes feature allows me to share any web page I find.

No Comments »

on January 26th 2009 in Internet

Show date in menu bar

Lately I’ve been using Dashboard in OSX a lot to figure out today’s date since Apple won’t let you (easily) add it to the menu bar. I found this amazing article to help fix the problem. It’s a nice hack to fix something Apple left out.

http://paulstamatiou.com/2006/06/11/how-to-display-date-in-os-x-menu-bar

No Comments »

on January 26th 2009 in Apple

Connecting your PDA to a Windows VM using Vmware 6.5

These are the steps to use if you are using Vmware Workstation 6.5, with a Windows XP guest, and your PDA won’t sync.

First: You need to find the VID and PID of the device you are trying to connect

To do this, all you need to do is attempt to sync your device.  When that fails, cd into the directory that has the files for the guest you are trying to sync to.  Look at the vmware.log file, there will be a line like this

vmx| USB: Found device [name:Palm\ Handheld vid:0830 pid:0061 path:5/1 speed:full family:vendor autoclean:1]

Note the VID = 0830 and the PID = 0061.

Next: Edit the vmx file for the windows XP guest and add the following line to it

usb.quirks.device0 = “0×0830:0×0061 skip-setconfig, skip-reset”

The 0×0830 and the 0×0061 will be replaced with the VID:PID that was in the vmware.log file.  the 0x MUST come before the numbers so that vmware knows it is a HEX value.  The values in the logfile are HEX numbers.  Also, the number after “device” in the device name “usb.quirks.device0″ can be any number from 0-N but there can not be any gaps in numbering.

Finally: Save the file and then shut down your VM if it was already running, then start it back up, and try to sync your device.

No Comments »

on January 13th 2009 in Vmware

Invisible buddy bookmarklet

Have any buddies on you AIM list that set their status to invisible? If you use iChat in OSX 10.4 you can’t get them to show up in your list. (iChat in 10.5 lets you view “offline buddies” so this isn’t a problem.) Drag the bookmarklet below to your bookmark bar.

AIM

(This won’t work if you’re using an RSS reader. Go to the posting to do it.)

Now click the bookmarklet and enter the screenname to open a chat window.

No Comments »

on January 8th 2009 in Internet

Virtualbox and the Linux Tickless Timer

There is currently an issue with Virtualbox and linux guests that have their kernel compiled with tickless timer support (CONFIG_NO_HZ) enabled.  What happens is that when the linux guest is idle, the CPU on the host gets pegged at 100%, or close to it.  SUN is currently investigating this issue, so they recommend that if you are having an issue, then either re-compile your linux kernel to disable the tickless timer support, or add the following to the boot parameters in your grub.conf file, and reboot.

nohz=off

If the problem isn’t fixed by that option, the other thing to try is to see if running the following command resolves the problem:

modprobe vboxdrv force_async_tsc=1

If that works, you can put that in the init script for the vbox driver.  To do that, edit /etc/init.d/vboxdrv with your favorite editor.

edit the following line:

if ! modprobe $MODNAME > /dev/null 2>&1; then

so that it says this:

if ! modprobe $MODNAME force_async_tsc=1 > /dev/null 2>&1; then

This second item may not need to be done, but it has helped people in the past, if the first option doesn’t work.  Hopefully SUN will have a workaround for this in the near future.

No Comments »

on November 21st 2008 in Linux, Virtualbox

Solaris multi-homed hosts on separate subnets

Solaris like most UNIX type hosts can have multiple network cards on their system. It gets tricky when have 2 interfaces on different subnets since you can only have 1 default router.

Consider this example:

A Solaris server has 2 network interfaces, bge0 and bge2. bge0 has an IP of 192.168.1.1, the router on that network is 192.168.1.254. bge2 has an IP of 192.168.100.1, the router on that network is 192.168.100.254. The default route on the system in the /etc/defaultrouter is 192.168.1.254.

When a packet comes in for 192.168.100.1, Solaris will process it and send the answer out to the default router. It knows nothing about the default router on the 2nd network. If you place the 2nd router in /etc/defaultrouter, then Solaris just round-robins the IPs. So a request comes in bge2 and goes out bge0 to the default router, from bge2′s IP. If the router is configured with anti-spoofing rules, then the router will ignore that packet. Thus, the answer never reaches the client.

In comes IPFilter. This is the Solaris firewall that’s built in. After exploring many different options to try to get it to route properly for that interface by checking the ‘route’ command I found this simple rule that allows it to work:

pass out quick on bge0 to bge2:192.168.100.254 from 192.168.100.1 to any

This rule says that any traffic going out bge0 from the IP 192.168.100.1 (bge2′s IP) should be changed to go out bge1 interface and be sent to 192.168.100.254 (the default router on bge2).

Now…introduce the Solaris multipathing. This allows you to use 2 interfaces, a primary and a backup interface. To do the probe-based failure detection, you’ll need to use 3 IPs, the primary IP and 2 test IPs (one for each interface).

Consider this:

Solaris server has 4 networks, bge0 has a primary IP of 192.168.1.1, bge1 is the 2nd backup network, so the test IPs would be 192.168.1.2 (bge0) and 192.168.1.3 (bge1). It look like this with an ifconfig:

bge0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2 inet 192.168.1.1 netmask ffffff00 broadcast 192.168.1.255 groupname backup bge0:1: flags=9040843<UP,BROADCAST,RUNNING,MULTICAST,DEPRECATED,IPv4,NOFAILOVER> mtu 1500 index 2 inet 192.168.1.2 netmask ffffff00 broadcast 192.168.1.255 bge1: flags=69040843<UP,BROADCAST,RUNNING,MULTICAST,DEPRECATED,IPv4,NOFAILOVER,STANDBY,INACTIVE> mtu 1500 index 3 inet 192.168.1.3 netmask ffffff00 broadcast 192.168.1.255 groupname backup

The server has a second network. bge2 has a primary IP of 192.168.100.1, bge3 is the 2nd backup network, so the test IPs would be 192.168.100.2 (bge2) and 192.168.100.3 (bge3). It look like this with an ifconfig:

bge2: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2 inet 192.168.100.1 netmask ffffff00 broadcast 192.168.100.255 groupname backup bge2:1: flags=9040843<UP,BROADCAST,RUNNING,MULTICAST,DEPRECATED,IPv4,NOFAILOVER> mtu 1500 index 2 inet 192.168.100.2 netmask ffffff00 broadcast 192.168.100.255 bge3: flags=69040843<UP,BROADCAST,RUNNING,MULTICAST,DEPRECATED,IPv4,NOFAILOVER,STANDBY,INACTIVE> mtu 1500 index 3 inet 192.168.100.3 netmask ffffff00 broadcast 192.168.100.255 groupname backup

The routing table looks like this:

# netstat -rn Routing Table: IPv4 Destination Gateway Flags Ref Use Interface -------------------- -------------------- ----- ----- ---------- --------- default 192.168.1.254 UG 1 59593 192.168.1.0 192.168.1.1 U 1 9 bge0 192.168.1.0 192.168.1.3 U 1 0 bge0:1 192.168.1.0 192.168.1.3 U 1 3 bge1 192.168.100.0 192.168.100.1 U 1 35 bge2 192.168.100.0 192.168.100.3 U 1 0 bge2:1 192.168.100.0 192.168.100.3 U 1 30 bge3 224.0.0.0 192.168.1.1 U 1 0 bge0 127.0.0.1 127.0.0.1 UH 2 14556 lo0

If the interface bge0 fails, the IP 192.168.1.1 will fail over to the bge1 interface. If bge2 fails, the IP 192.168.100.1 will fail over to the bge3 interface.

There are rules in IPFilter that can be used, but it makes it a little trickier to ensure the failovers still work:

# Normal condition, bge0 and bge2 are primarys
pass out quick on bge0 to bge2:192.168.100.254 from 192.168.100.1 to any

# bge2 has failed
pass out quick on bge0 to bge3:192.168.100.254 from 192.168.100.1 to any

# bge0  has failed
pass out quick on bge1 to bge2:192.168.100.254 from 192.168.100.1 to any

# bge0 and bge2 has failed
pass out quick on bge1 to bge3:192.168.100.254 from 192.168.100.1 to any

These rules in IPFilter should pass the traffic the correct way in the even of any multipath failovers. You’ll need those 4 rules for each IP on the secondary network you want to route correctly. This means any Solaris containers as well. One small thing with containers is that if you have a container on just the second network, you’ll need to add these commands to a startup script in the global zone in order to have a default router for the zone to see:

        /sbin/route add default 192.168.100.254 -ifp bge2
        /sbin/route add default 192.168.100.254 -ifp bge3

Using the ‘route -p’ does not work to keep it persistent in this case, as it only remembers one of the ‘default 192.168.100.254′ routes (it ignores the -ifp part).

5 Comments »

on November 12th 2008 in solaris

ClusterSSH on OSX

If you aren’t familiar with ClusterSSH, here’s the official tag line from SourceForge:

“ClusterSSH controls a number of xterm windows via a single graphical console window to allow commands to be interactively run on multiple servers over an ssh connection.”

This is extremely handy if you’re editing files, running commands, or tailing logs on multiple servers. Once you get used to use using it you’ll feel the pain of losing it once Apple comes out with another update.

And if you’re a regular user of ClusterSSH and OSX you might have noticed that Leopard (10.5) changes how X operates. The old method was to set the DISPLAY variable to localhost:0 (done automatically), start X11 from the Utilities folder, then run the x command from the xterm window that gets started. The new method automatically sets the DISPLAY variable to something like /tmp/launch-JQhO33/:0 and removes the need to start X11 manually.

ClusterSSH doesn’t recognize /tmp/launch-JQhO33/:0 as a valid display and fails. Here are a couple workarounds.

For pre-10.5.4 the following works:

  • Save this file in /usr/local/bin/
  • Make sure you aren’t setting the DISPLAY variable in your profile
  • Change /usr/local/bin/cssh in the cs file to wherever you have ClusterSSH installed

Step-by-step here’s what’s going on:

xterm -e logout&

The cs wrapper starts an xterm window and executes the “logout” command. This causes X11 to start. DO NOT MANUALLY START X11.

export DISPLAY=localhost:0

The DISPLAY variable is set to localhost:0 for ClusterSSH.

/usr/local/bin/cssh $* &

Executes ClusterSSH with the arguments passed to cs and backgrounds it to free up the terminal (for convenience only).

osascript << END
tell application “X11″
activate
end tell
END

Finally it calls on AppleScript to bring X11 to the front (again, for convenience only).

I’ve found that using this method sometimes fails and requires a reboot before it will work again. Also keep an eye out for runaway xterm processes and kill them.

For 10.5.5 and later:

  • sudo vi /etc/sshd_config and change X11Forwarding to yes
  • Restart sshd (either by rebooting or the command “SystemStarter -v restart SSH”)
  • ssh -Y localhost
  • Use ClusterSSH as normal

This method forwards X over ssh and ssh sets the DISPLAY variable to a value ClusterSSH can handle. To verify this:

$ echo $DISPLAY
localhost:10.0

Note: This value may vary but should always start with “localhost.”

If you want to get really fancy, set up keys so ssh won’t prompt for a password.

I hope this helps. I spent way too much time fighting with it before I came across a solution. I admit it’s not the best, but it works.

Update:

I’ve come across a better solution. Since X11 is looking for a valid display, change line 1716 of cssh to the following:

$xdisplay = X11::Protocol->new(“unix:0″);

Also replace the cs wrapper file with the new one. You’ll see some errors, but it’ll work and is much cleaner than the previous solution.

Update 2:

Version 3.26 of ClusterSSH requires changing line 1994 of cssh to:

$xdisplay = X11::Protocol->new(“unix:0″);

2 Comments »

on October 28th 2008 in Apple