Wednesday, April 28, 2010

A Handy Macro

I left off the last post with this:
exten => 1000,1,Dial(${MILES},${DELAYTIME})
exten => 1000,n,GoToIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
exten => 1000,n(unavail),VoiceMail(1000@default,u)
exten => 1000,n,Hangup()
exten => 1000,n(busy),VoiceMail(1000@default,b)
exten => 1000,n,Hangup()
As the book points out, this is fine for small implementations of *, but as a system scales this becomes massively inefficient. I followed the book example to turn this into a macro and condense everything down to one line outside the macro's definition.

Macros are created in a pseudo-context prefaced with "macro-" ; I used
[macro-voicemail]
It also differentiates from pure contexts because each step uses the "s" extension. * has some handy built-in variables, including one to call the original extension ${MACRO_EXTEN}. Thus, our macro becomes
[macro-voicemail]
exten => s,1,Dial(${MILES},${DELAYTIME})
exten => s,n,GoToIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
exten => s,n(unavail),VoiceMail(${MACRO_EXTEN}@default,u)
exten => s,n,Hangup()
exten => s,n(busy),VoiceMail(${MACRO_EXTEN}@default,b)
exten => s,n,Hangup()
This is why I had the mailbox extensions the same as the SIP extensions.

The last thing to do was strip the last unique variable in the macro and add it back in as an argument. Since this happened to be my name, we can just put that in as the "n"th argument using the ${ARG n} variable built into the Macro() application. The macro becomes:
[macro-voicemail]
exten => s,1,Dial(${ARG1},${DELAYTIME})
exten => s,n,GoToIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
exten => s,n(unavail),VoiceMail(${MACRO_EXTEN}@default,u)
exten => s,n,Hangup()
exten => s,n(busy),VoiceMail(${MACRO_EXTEN}@default,b)
exten => s,n,Hangup()
And now instead of the messy, 6-line statement in the [internal] context in the dialplan we started out with, we can just write
exten => 1000,1,Macro(voicemail,${MILES})
Here you can see where the ${ARG1} variable gets its value (the first argument after "voicemail" in the Macro application).

Voicemail Details

The original /etc/asterisk/voicemail.conf had a lot of commented options, so I renamed it voicemail.conf.sample and made a new one. There are three contexts: [general] holds various global options, [zonemessages] are for timezones, and [default] (which can be renamed whatever you want) holds the mailbox information.

Currently, this is what each section looks like (with brief explanation):
[general]

format=wav49|gsm|wav
serveremail=asterisk
attach=yes
skipms=3000
maxsilence=10
silencethreshold=128
maxlogins=3
emaildateformat=%A, %B %d, %Y at %r
sendvoicemail=yes
As I said, these are all global options and most are self-explanatory. You can find technical definitions of each option here, along with a bunch of others I didn't include.
[zonemessages]

eastern=America/New_York|'vm-received' Q 'digits/at' IMp
central=America/Chicago|'vm-received' Q 'digits/at' IMp
central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours'
military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'
european=Europe/Geneva|'vm-received' a d b 'digits/at' HM
These are just time zone settings. Full explanation of zonemessages is midway down the page here.
[default]

1000 => 9999,Miles K,email.removed.to.stop.spam@gmail.com
1001 => 9999,John M
....
Mailboxes are simple to set up. It's the extension followed by the passcode, Name (it knows that the last name is separated from the first name by a space!), and notification e-mail address. You can also add a pager e-mail address (pagers....hah!) and various overrides to the global options that are specified in [general].

The addition of voicemail necessitates changes to the dialplan (extensions.conf) which happened in a somewhat circular way as I followed the book's example. At first there was the no-brainer approach, taking this:
exten => 1000,1,Dial(${MILES},${DELAYTIME})
exten => 1000,n,Playback(vm-nobodyavail)
exten => 1000,n,Hangup()
into this:
exten => 1000,1,Dial(${MILES},${DELAYTIME})
exten => 1000,n,VoiceMail(1000@default,u)
exten => 1000,n,Playback(vm-nobodyavail)
exten => 1000,n,Hangup()
The VoiceMail() application takes two arguments: (mailboxNumber@mailboxContext, statusIdentifier). mailboxNumber and mailboxContext are what got entered into voicemail.conf. statusIdentifier can be either "u" (unavailable) or "b" (busy). The above is not very robust as it only has directions for an "unavailable" user and no instructions if the user is busy. The second incarnation is:
exten => 1000,1,Dial(${MILES},${DELAYTIME})
exten => 1000,n,GoToIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
exten => 1000,n(unavail),VoiceMail(1000@default,u)
exten => 1000,n,Hangup()
exten => 1000,n(busy),VoiceMail(1000@default,b)
exten => 1000,n,Hangup()
This makes use of the DIALSTATUS variable to tell * what message to play in the unavailable/busy scenarios, kind of like a decision tree.

Voicemail

Voicemail should now be set up for all users. I tested it out by calling myself in XLite and leaving a message; it recorded as well as I could expect from my crappy computer microphone and the built-in options seem to work fine.

Some features we have now:

-Internally searchable directory
  • Dial "8" to search by first name (everyone has a first name as entered)
  • Dial "9" to search by last name (Only John, Sarah, Jane, Katie M currently have last names)
-Individual mailboxes that can hold up to 100 messages (this is the default and can be changed upwards or downwards)

-Access to your mailbox by dialing extension "700" and then your Asterisk extension number. It doesn't have to be this way, I just thought it'd be easiest for now.

-Each mailbox is passcode protected- currently the default is 9999 (can be changed).

-Currently when your extension is dialed, Asterisk will ring for 30 seconds before transferring to voicemail.

-I haven't been able to try this out, but in theory if you are on the other line and you receive a call, Asterisk will ring for 30 seconds before automatically sending the caller an "I'm busy" dialogue before forwarding them to voicemail.

-In theory, Asterisk can be set up to send you e-mail alerts when you have a new voicemail. I entered my gmail address to test it out, but didn't get any e-mails. This is either because notification isn't instant (in which case I have no idea where I'd adjust the time period after which * checks for new voicemail) or something isn't configured right. I'll keep looking into it.

Technical details to follow after I run to the grocery store.

DELAYTIME variable

To make things easier, I defined a global variable in extensions.conf
DELAYTIME=35
...which is the amount of time in seconds that Asterisk will "ring" before giving the "Unavailable" message and hanging up (I'm still reading about voicemail).

Side note: Swiss French keyboards are incredibly annoying with any form of input involving {brackets}, as the { key appears as รจ while the } key appears as ¨ (the umlaut). Not to mention QWERTZ vs QWERTY...

Linksys ADC

[This is a summary of a couple of e-mails]

John found the Linksys SPA3102 Voice Gateway Router which appears to offer a hardware solution that would solve my inability to install DAHDI on our cloud server. There's even a configuration guide to make it work with Asterisk. If this device does what I think it does, it would eliminate the need to install the DAHDI drivers, as the output of the Linksys appears to be just like any other SIP client. That would be very nice!

Friday, April 23, 2010

Users Added to the Dialplan

I made the necessary adjustments to the dialplan so that the people assigned to a given extension can now dial another person's extension to "call" them- which really means that when a certain extension is dialed, Asterisk now has instructions on what to do upon detecting that extension.

DAHDI Installation Unsuccessful

...and now for today's letdown. I downloaded the latest version of DAHDI and the DAHDI tools from digium, but am running into the "linux sources" error I ran into back in March.
You do not appear to have the sources for the 2.6.32.1-rscloud kernel installed.
make: *** [modules] Error 1
I hesitate to jump to the conclusion (again) that this would be solved using a CentOS or non-cloud version of Linux, but I'm not really sure. What I do know is that extensive searching on "sources for 2.6.32.1-rscloud kernel" does not yield very helpful results other than "such-and-such won't work on a non-CentOS kernel."

Call Success!

John and I made a call to one another today which went very well. The nature of the SIP/SIP connection has Asterisk acting only as a facilitator to get two endpoints talking directly to one another.

SIP/SIP connections mean that call quality is determined by the speed and available bandwidth of the two connecting clients, not on the ability of the Asterisk server to process data quickly. Processor speed and other hardware requirements become an issue with PSTN lines connecting to pretty much everything else, as well as connecting the Asterisk PBX to the cellular network (both scenarios in which additional hardware is required).

Added More Users

Modified /etc/asterisk/sip.conf with 10 additional users as per the e-mail I sent to John. Also changed the existing passwords to something a bit harder to guess.

Friday, April 16, 2010

Zaptel -> Dahdi

I was browsing the Asterisk Support Forums today and came across a post that said Zaptel has been replaced by something called "Dahdi" for more recent versions of the Linux Kernel. I guess that explains why it wouldn't compile.

Friday, April 9, 2010

Silly Mistake Re: "Dial"

Removed the following lines from modules.conf (which, stupidly, were added by me a few days ago) to solve the "dial" problem below.
noload => app_queue.so
noload => app_dial.so
noload => features.so

Thursday, April 8, 2010

"Dial" Application Not Installed?????

I was trying to set up an extension so that SIP user 1000 could call user 1001 by dialing an extension using the Dial() command in extensions.conf. However, it appears that the Dial application wasn't installed?

(Using core show applications from the CLI)
ControlPlayback:
DateTime:
DBdel:
DBdeltree:
DeadAGI: Executes AGI on a hungup channel
Dictate:
Directory:
DISA:
DumpChan:
EAGI: Executes an EAGI compliant application
...definitely not there. Perhaps it was part of Zaptel, although it seems strange to me that Dial wouldn't be installed as a SIP-only configuration seems like it would be fairly common, and not dependent on FXS/FXO analog channels.

Right now I'm trying to find out how to install it.

Wednesday, April 7, 2010

Added Another Test User

I've added another test user to our setup with the following lines in the sip.conf :
[1001]
type=friend
nat=yes
username=1001
context=phones
host=dynamic
secret=4321
Perhaps you'd like to try to get XLite to connect on your end? The following settings should work, although the menus are probably slightly different in Windows.
Display Name: John (can be whatever you want)
User name: 1001
Password: 4321
Authorization user name: 1001
Domain: [IP of the server]
Once you get it to connect, dial "500" and see if you hear the "weasels" message.

Monday, April 5, 2010

Call Success

I tweaked the test dialplan so it plays back the file "tt-weasels" when the number "500" is dialed from XLite. The file played back successfully.

The dialplan:
[globals]

[general]

[default]
exten => s,1,Verbose(1,Unrouted call handler)
exten => s,n,Answer()
exten => s,n,Wait(1)
exten => s,n,Playback(tt-weasels)
exten => s,n,Hangup()

[incoming_calls]

[internal]
exten => 500,1,Verbose(1,Echo test application)
exten => 500,n,Playback(tt-weasels)
exten => 500,n,Hangup()

[phones]
include => internal

Some things to keep in mind:
-The book still uses the pipe | symbol as a delimiter. This has since been replaced with the comma, and the asterisk CLI will show a warning if you have a pipe in the dialplan.
-I turned off the various demo contexts from "make samples" by editing modules.conf with the following lines:
; Turns off the pbx_ael "demo"-created contexts in the dialplan
noload => pbx_ael.so
noload => app_queue.so
noload => app_dial.so
noload => features.so
(; precedes comments)
-If you make a change to the dialplan you have to reload it in the asterisk CLI with dialplan reload.

Got XLite to Connect!

After a bit of reading on the sip.conf page on voip-info I figured out what I had to change in order to get the program to connect to the asterisk server.



The book's default sip.conf file was insufficient to deal with the layer of NAT I'm sitting behind with my home router. Luckily asterisk now has an nat option you can put in the sip.conf file that fixes this. The test sip.conf file now looks like this:
[general]

[1000]
type=friend
nat=yes
username=1000
context=phones
host=dynamic
secret=1234
The settings in XLite in the SIP Accounts section:
Display Name: Miles (can be whatever you want)
User name: 1000 (can be whatever you want, but must match "username" in sip.conf)
Password: 1234 (matches "secret" in sip.conf)
Authorization user name: 1000 (not sure what this is, honestly)
Domain:
Everything else was left as default. I also had to forward the ports on my home router (5060-5070).

Thursday, April 1, 2010

Nothing Exciting Today

Right now I think the problem is some combination of NAT, the vsftpd/openssh conflict, and a healthy dose of not knowing exactly what's going on with certain things (mostly the config files and how a SIP connection actually behaves). I didn't do anything noteworthy today (besides walking around the uncomfortably crowded Cherry Blossom Festival).

The distro issue (Ubuntu vs. CentOS vs. whatever) is probably more of a convenience thing at the moment; I did a bunch of searching on various combinations of "asterisk ubuntu" but there's nothing particularly enlightening other than a fair number of websites saying the equivalent of "NAT makes things hard." Of course there's something to be said about starting fresh after a "trial run," although I'm not sure if I want to start the precedent of wiping everything when I hit a roadblock ;-)

I think I'm going to re-read the book and some various guides I came across today, voip-info.org/wiki/view/asterisk in particular looks like it could be helpful.