Welcome to The Tech 
Guide
Google
 
Web www.thetechguide.com
Geeks with attitude
Navigation
  • Home
  • How-To's
  • Tweaks
  • Hardware
  • Software
  • Games
  • Our Picks
  • Downloads
  • FAQ's
  • Forum
  • Chat
  • Tech Deals
  • Links
  • Email

  • Site News
    Our Black Friday section is now online! Click here to check it out.

    Active Discussions
    [an error occurred while processing this directive]


      

    Unlimited Incoming/Outgoing cellphone calls with Asterisk


    Part 3, examples of my setup.

    Note that your setup may be different than mine, this is just how I set things up. Also, while it works for me, there may be better ways to do what I've done (in fact, I know I have used some deprecated functions which still work now, but may be removed later). This should help to get you up and running, but please look into what these settings do and tailor it to your own needs.

    Ok, first I needed a number that I could call from my cellphone and would receive DTMF (remember, cellphone to cellphone did not pass DTMF). I also did not want to pay for another line, and needed a unique line used solely for calling in via cellphone. I used an IPKall number at www.ipkall.com. Normally you'd setup a FWD number first and have your IPKall number forwarded to it, but that would introduce an extra point of failure that I did not want. I setup my IPKall number to forward directly to my server. To do this you will need either a static ip, or a dynamic dns address. I have a dynamic ip, so I signed up for a dyndns account, and run a client on my server that checks the current ip and updates as necessary. Setting this up is beyond the scope of this howto, but suffice to say that you need a number setup that you can call from your cellphone and enter in some dtmf digits.

    This isn't necessary, but I have used variables in several places in my extensions.conf. This makes it very easy to make broad changes, such as changing my primary long-distance provider, or adding a new ata. Here's a list of variables that are used later in the examples:

    LD1=IAX2/username:[email protected]
    LD2=IAX2/username:[email protected]


    My primary (LD1) and secondary (LD2) long-distance providers. The first is voxee, and costs 1.1cents/minute. The second is voicepulse, which costs 2.9cents/minute. Voicepulse seems to be more reliable, but is more expensive. In my dialplan, it tries voxee first, then voicepulse, so unless both are down all calls will go through.

    HOURS=07:59-16:00|sun-sat|*|*?asleep|s|1

    Variable used with GotoIfTime, this matches during the hours of 7:59AM to 4:00PM, every day, and sends the caller to the [asleep] context, the s extension (s for start), and priority 1. Unless you're a night person like we are, you will probably want to change the hours to match during the night, instead of during the day.

    HOURSCELL=06:50-21:10|mon-fri|*|*?

    This matches between the hours of 6:50AM to 9:10PM, Monday through Friday. This is when the cellphone uses anytime minutes, all other times it's nights and weekends and long-distance calls are free. I did not set the context, extension, or priority here, but did so later on when this variable was used (you can set this anywhere you want, I'm just explaining why my extensions.conf looks the way it does). BTW, my nights and weekends is from 9PM to 7AM, but I don't trust the cellphone company's clock to be as accurate as mine, so I gave them an extra ten minutes (in this setup, nights and weekends starts at 9:10AM and ends at 6:50AM, if Cingular is more than ten minutes off there's something wrong).

    ALLPHONES=SIP/103&SIP/104&SIP/105&SIP/106

    The last variable, this is a list of my sip phones. You won't need to use this, but is included here for completeness. The samples given are pulled directly from my working setup. Ok, on to the good stuff! Notice that I will have all entries in extensions.conf in bold, and any comments are preceded by a semicolon (you may leave the comments in if you wish, asterisk will ignore them, but they aren't necessary). Also note that I have a lot of NoOp commands scattered throughout. I put them there so I could add additional commands later, and not have to reorder all my priorities (I began with one NoOp in between each actual command, you can tell where I have had to go back and add more commands in). BTW, NoOp stands for No Operation, it's just a placeholder.

    Here's the context for the incoming line. The extension is 777 in my case, but it could also be s, or the actual number, or any number of other things in your particular setup.

    [inbound]

    exten => 777,1,NoOp
    exten => 777,2,Wait(1)
    exten => 777,3,NoOp
    exten => 777,4,Answer
    exten => 777,5,NoOp
    exten => 777,6,SetCIDNum(${CALLERIDNUM})
    ;We get the callerid number of the calling party
    exten => 777,7,Wait(1)
    exten => 777,8,DigitTimeout,5
    exten => 777,9,NoOp
    exten => 777,10,Read(dncdigitsa,custom/please-enter,11,s)
    ;We are going to read the dtmf digits entered, store them in a variable called dncdigitsa,
    ;and will read up to 11 digits (any past 11, we ignore). We wait up to five seconds between
    ;digits. Once five seconds is up we assume the caller is done entering the number. Each
    ;time they press a button, this five second timeout is restarted. The prompt played is
    ;called "please-enter" and is in the "custom" sounds directory.
    exten => 777,11,Set(dncdigitsb=${dncdigitsa:-10})
    ;This takes the number entered, takes the last ten digits, and saves that in a variable
    ;called digitsb. It seems a bit silly, especially when you see the next line.
    exten => 777,12,Set(dncdigits=1${dncdigitsb})
    ;Here, we create a new variable called dncdigits, and set it to 1 plus the value of
    ;dndigitsb. So, why did we strip the 1 off the number, just to add it back? Well, we didn't
    ;actually strip off the 1, we just took the last ten digits. If you dial 1 + area code +
    ;number, then you have eleven digits. Take the last ten, and you have area code + number.
    ;Add a 1 in front, and you have 1 + area code + number. But what if you let other people
    ;use this system, people who aren't used to dialing a 1 in front of the area code? If they
    ;dial area code + number, and you take the last ten digits, you are left with area code +
    ;number. Add a 1 in front, and you have 1 + area code + number. It's just a hack to insure
    ;you end up with 1 + area code + number, whether the caller remembered to dial the 1 in
    ;front. I call this the "Aunt Sue" code.
    exten => 777,13,Playback(you-entered,s)
    exten => 777,14,Saydigits(${dncdigits:0:1})
    ;This says the digits, skipping 0 numbers, and reading 1
    exten => 777,15,Wait(0.5)
    ;This puts in a pause of half a second, makes the number easier to understand when read back
    exten => 777,16,Saydigits(${dncdigits:1:3})
    ;This says the digits, skipping 1 number, and reading the next 3 (in this case, the area
    ;code)
    exten => 777,17,NoOp
    exten => 777,18,Wait(0.5)
    exten => 777,19,NoOp
    exten => 777,20,Saydigits(${dncdigits:4:3})
    ;This says the digits, skipping 4 numbers, and reading the next 3 (the prefix)
    exten => 777,21,NoOp
    exten => 777,22,Wait(0.5)
    exten => 777,23,NoOp
    exten => 777,24,Saydigits(${dncdigits:7:4})
    ;This says the digits, skipping 7 numbers, and reading the next 4 (the last of the number)
    exten => 777,25,NoOp
    exten => 777,26,Wait(0.5)
    exten => 777,27,NoOp
    exten => 777,28,BackGround(custom/correct)
    ;Another custom prompt named "correct"; it asks the caller if this was correct press 1,
    ;otherwise press 2.
    exten => 777,29,NoOp
    exten => 777,30,DigitTimeout(1)
    ;We're only looking for one digit, so as soon as one digit (a 1 or 2 in our case) we're done
    exten => 777,31,NoOp
    exten => 777,32,ResponseTimeout,10
    ;Give them up to 10 seconds before giving up
    exten => 777,33,NoOp
    exten => 777,34,NoOp
    exten => 777,35,NoOp

    exten => 1,1,Goto(inbound-success,s,1)
    ;They pressed 1, so we go to extension 1. Extension 1 sends us to the [inbound-success]
    ;context, extension s, priority 1. Why do this? Because we need to do some further processing
    ;on the call after we hangup. If we stay in this context, then the call file we want to create
    ;will get created whenever the call is hungup, whether the user dialed 1, or got frustrated and
    ;hung up, etc. We only want to process the call file if the user pressed 1 and hung up.

    exten => 2,1,Goto(inbound,777,7)
    ;Well, something messed up and we didn't get the number they wanted to dial correctly
    ;(maybe fat fingers, maybe a bad connection and the some dtmf tones didn't make it
    ;through). We stay in the [inbound] context, and go back to the 777 extension, priority 7
    ;(just before we ask them to enter the number they wish to reach).

    exten => t,1,Playtones(congestion)
    exten => t,2,Wait(5)
    exten => t,3,Hangup
    ;"t" is the timeout extension, used if we prompt the user to enter some digits but they
    ;don't respond in a timely fashion. Here we play congestion tones for 5 seconds, then
    ;hangup.

    [inbound-success]

    exten => s,1,NoOp
    exten => s,2,Playback(custom/connected-soon,s)
    ;Another custom prompt, letting the caller know that they should hang up and their call
    ;will be connected soon
    exten => s,3,Wait(1)
    exten => s,4,Hangup
    ;Of course there will be those that don't hangup, so we hang up for them. Once the line has
    ;been hung up, we go to the "h" extension below.

    exten => h,1,NoOp
    exten => h,2,NoOp
    exten => h,3,System(echo channel: Local/1${CALLERIDNUM}@cell-out/n > /tmp/${CALLERIDNUM})
    ;The channel we want to call the user back on. A 1 is added to the callerid number, since
    ;IPKall (and most, but not all, other providers) present callerid as area code + number.
    exten => h,4,System(echo MaxRetries: 0 >> /tmp/${CALLERIDNUM})
    ;MaxRetries is set to 0. This means if it doesn't succeed on the first attempt, it won't
    ;try again. This way, the user will know it failed in less than a minute, and can just dial
    ;the number directly. Obviously something has failed, or asterisk is using the local cellphone
    ;for another call.
    exten => h,5,System(echo context: main >> /tmp/${CALLERIDNUM})
    ;The context we want to use to dial the number the user entered
    exten => h,6,NoOp
    exten => h,7,System(echo extension: ${dncdigits} >> /tmp/${CALLERIDNUM})
    ;Here we set the extension to be dialed to equal the number that the user entered
    exten => h,8,NoOp
    exten => h,9,System(echo priority: 2 >> /tmp/${CALLERIDNUM})
    ;We'll jump to priority 2, instead of priority 1. Not necessary, but in my setup priority 1
    ;sets the callerid number to be used for the outgoing long-distance calls (and for calls
    ;which are local, it's just a NoOp line). We skip this, so that asterisk will use the
    ;callerid number we assign below. This way we use only one extension for outgoing long-
    ;distance calls, and if we call from a regular line connected to asterisk callerid gets
    ;set to an appropriate number, and if we call from an outside cellular phone callerid
    ;gets set to that cellular number. Really not necessary, unless you let other people
    ;use their cellphone with your setup (which I do).
    exten => h,10,NoOp
    exten => h,11,System(echo Callerid: ${CALLERIDNUM} >> /tmp/${CALLERIDNUM})
    ;We set the callerid to be the callerid we received from the caller's phone
    exten => h,12,NoOp
    exten => h,13,System(echo sleep 5 > /tmp/${CALLERIDNUM}.2)
    ;Sleep for 5 seconds, give the other end a time to completely end the call before we call back
    exten => h,14,NoOp
    exten => h,15,System(echo cp /tmp/${CALLERIDNUM} /var/spool/asterisk/outgoing >> /tmp/${CALLERIDNUM}.2)
    exten => h,16,NoOp
    exten => h,17,System(chmod 775 /tmp/${CALLERIDNUM}.2)
    exten => h,18,NoOp
    exten => h,19,System(/tmp/${CALLERIDNUM}.2)
    exten => h,20,NoOp
    exten => h,21,Hangup()
    ;Why hangup an extension that's already hung up? I dunno, but that's what I had and it
    ;works *shrug*

    That's pretty much it right there. Just make sure you have the proper extensions in the [main] context to handle 1 + area code + number calls, and this part is done! Just for reference, here's the relevant part of my [main] context:

    [main]

    exten => _1NXXNXXXXXX,1,SetCallerID(9315551212)
    ;I set my callerid number here. When the call file is created, it skips this line and jumps
    ;right to priority 2 below
    exten => _1NXXNXXXXXX,2,NoOp
    exten => _1NXXNXXXXXX,3,NoOp
    exten => _1NXXNXXXXXX,4,SetVar(CALLFILENAME=${TIMESTAMP}-${CALLERIDNUM}-${EXTEN})
    ;This is where I setup the name of the file for the recorded call. Not necessary.
    exten => _1NXXNXXXXXX,5,NoOp
    exten => _1NXXNXXXXXX,6,GotoIfTime(${HOURSCELL}main|${EXTEN}|10)
    ;If the time is between 6:50AM and 9:10PM, we're sent to the [main] context, extension
    ;stays the same, and we goto priority 10. Basically, we're skipping priority 8 below and going
    ;straight to priority 10.
    exten => _1NXXNXXXXXX,7,NoOp
    exten => _1NXXNXXXXXX,8,Goto(cell-out,${EXTEN},1)
    ;Woohoo, we didn't jump to priority 10, so it must be nights and weekends! No need to pay
    ;for long-distance calls, we'll just make them through the local cellphone. Party time!
    exten => _1NXXNXXXXXX,9,NoOp
    exten => _1NXXNXXXXXX,10,Monitor(gsm,${CALLFILENAME},m)
    ;Crap, it must be between 6:50AM and 9:10PM on a Monday through Friday, so we were sent to
    ;priority 10. Here, we start recording the call (again, not necessary).
    exten => _1NXXNXXXXXX,11,NoOp
    exten => _1NXXNXXXXXX,12,Dial(${LD1}/${EXTEN})
    exten => _1NXXNXXXXXX,13,NoOp
    exten => _1NXXNXXXXXX,14,Dial(${LD2}/${EXTEN})
    exten => _1NXXNXXXXXX,15,NoOp
    exten => _1NXXNXXXXXX,16,Congestion
    exten => _1NXXNXXXXXX,113,NoOp
    exten => _1NXXNXXXXXX,114,Dial(${LD2}/${EXTEN})
    exten => _1NXXNXXXXXX,115,Congestion
    ;Just dialing one long-distance provider, and if that fails try the other.

    [cell-out]

    exten => _1NXXNXXXXXX,1,NoOp
    exten => _1NXXNXXXXXX,2,NoOp
    exten => _1NXXNXXXXXX,3,NoOp
    exten => _1NXXNXXXXXX,4,SetGroup(cellout)
    exten => _1NXXNXXXXXX,5,CheckGroup(1)
    exten => _1NXXNXXXXXX,6,Dial(BLT/Motorola/${EXTEN})
    exten => _1NXXNXXXXXX,7,NoOp
    exten => _1NXXNXXXXXX,8,Dial(${LD1}/${EXTEN})
    exten => _1NXXNXXXXXX,9,NoOp
    exten => _1NXXNXXXXXX,10,Dial(${LD2}/${EXTEN})
    exten => _1NXXNXXXXXX,11,NoOp
    exten => _1NXXNXXXXXX,12,Congestion
    exten => _1NXXNXXXXXX,106,NoOp
    exten => _1NXXNXXXXXX,107,NoOp
    exten => _1NXXNXXXXXX,108,Dial(${LD1}/${EXTEN})
    exten => _1NXXNXXXXXX,109,Congestion
    exten => _1NXXNXXXXXX,209,NoOp
    exten => _1NXXNXXXXXX,210,Dial(${LD2}/${EXTEN})
    exten => _1NXXNXXXXXX,211,Congestion

    This could be bad, if someone calls in and the cellphone is busy, it'll try to dial them using the long-distance line. We need some kind of fallback though, in case this is used from a local extension during nights and weekends. It's an easy fix, I just haven't done it yet.

    To be continued.


    Questions? Ask in the forum or email me.

    For the Privacy Policy, click here.
      
    Past Articles
  • Build your own Apple Clone
  • AllofMP3 Review
  • Tutorial to Basic Windows 2000 DOS
  • Extracting and joining MPG2 files from SVCD
  • Modifying your Windows XP Boot Logo
  • Unlocking WinXP's setupp.ini
  • Making a Full Screen Bios Logo
  • Making your WinMe CD bootable
  • Auto-insert your Win9x serial
  • Auto-insert your Office2kserial
  • Why FedEx Sucks