Flexible table-controlled dialplan, optimized for US, GV

Catalog of dial plans
gm_w
Posts: 3
Joined: Wed May 26, 2010 11:11 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by gm_w » Wed May 26, 2010 11:32 am

i cannot get the US toll free that routes thru gizmo to work now. It used to work before.... is there something we need to modify now?

MikeTelis
Posts: 1582
Joined: Wed Jul 30, 2008 6:48 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by MikeTelis » Wed May 26, 2010 12:55 pm

Are you sure it's routed thru Gizmo? If you didn't change the code, it should try ENUM database first and route thru one of the gateways listed in there. Gizmo is used only if the gateway failed.

Could you post console log here?

notchy
Posts: 14
Joined: Sat Feb 20, 2010 3:19 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by notchy » Wed Jun 16, 2010 10:45 pm

I have my Ruby plan working 90% but it still needs tweaking.

I have a Google Voice account
I also have a SIP provider (VOIP.MS)

I would like the option of allowing most outbound calls going through Google Voice but if I need the option to allow a certain call to sometime go through my provider how can I achieve that with my posted Ruby Dial Plan.

So my example would be :

Google Voice --> 905-967-1111 (default)

I would like the option of overriding this and allow SIP Provider to dial #2 905-967-1111
I thought the above would allow this from the "VSPtab" section of my code but it doesn't work.

Please be patient with me, I'm not really a programmer.

Code: Select all

#Ruby

Area = '786'                       # My area code
Tz   = -5                          # Time zone (GMT-5)

# Speed dial entries. Format: "key" => "number"

Speeddial = {
 
  '411' => '8004664411',        # Google 411
  '911' => 'XXX',            # Emergency
}

# Serviced domains, must be in lowercase!

Domains  = ['sipsorcery.com','174.129.236.7']

# Excluded Prefixes. Provides a safeguard against accidentally calling premium
# numbers. Accepts both strings and patterns, spaces ignored

ExcludedPrefixes = [
   ' 1 (900 | 976 | 809)',            # USA Premium
   '44 (9 | 55 | 87 (0|1))',          # UK Premium
   '44 84 (4|5)',                     # UK Local Premium
   '44 70',                           # UK Personal Premium
   '43 (8|9)',                        # Austria Premium
   '32 (7|90)',                       # Belgium Premium
   '45 (1 | 50 (1|2|3) | 70 (1|2))',  # Denmark Premium
   '45 (8|9) 0',                      # Denmark Premium (...)
   '33 (7|9)',                        # France Premium
   '49 (1 | 900)',                    # Germany Premium
   '39 [^3]',                         # Italy Premium (...)
   '31 (14 | 6 (3|8|9) | 8 | 9)',     # Netherlands Premium (...)
   '48 (39 | (2|7|8) 0)',             # Poland Premium
   '46 9 (00 | 39 | 44)',             # Sweden Premium
   '41 90 (0|1|6)',                   # Switzerland Premium
]

# Providers: "key" => "template". Template format: prefix@Provider

VSPtab = {
  '0' => '00 @ F9',                # Future-nine default route
  '2' => '@ VOIPMS',               #VOIP.MS
  '3' => '03 @ F9',                # Future-nine white route
  '4' => '@ VOIPMS',               # Future-nine premium route
  '5' => '@ Gizmo',                # Gizmo5
  '*' => '* @ Voxalot',            # Voxalot with * prefix
}

# ********************  G o o g l e V o i c e  *****************************
# !!!!!!!!!!!!    Make sure to enter your credentials below    !!!!!!!!!!!!!

def googleVoice
  sys.GoogleVoiceCall('256@gmail.com','bfff','19671111',@num,'.*',1,90)
end

# ********************  s e l e c t   V S P  *******************************

def selectVSP    # VoIP provider selection

  # Reject calls to premium numbers unless VSP was forced

  ExcludedPrefixes.each { |p| p.gsub!(/\s*/,''); sys.Respond(503,"Calls to #{$1}* not allowed") if @num =~ /^(#{p})/ }

  case @num
    when /^1([2-9]\d\d)/                # North America
      case $1                           # check area code
#       when "808", "907", "867"        # AK, HI, Canada Yukon
#         route(4,"Destination - Alaska, Hawaii, Yukon")
        when /(800|866|877|888|747)/    # Toll-free and 1-747 calling
          route(2,"Destination - US toll-free for VOIPMS")
        else
          googleVoice
          sys.Log("GoogleVoiceCall failed, routing thru VOIPMS")
          route(2,"Destination - North America")
        end
    when /^972(5|6)/                    # Israel mobile
      route(3,"Destination - Israel mobile")
    else
      route(4,"Default route applied")
  end
end

# **************************  C A L L    S W I T C H  **********************

def callswitch(num,*args)
  route                 # Initialize vars

  @num = num unless @num = Speeddial[num]     # If there is speed dial entry for it...

  @l = "URI dialing: #{@num}" # Assume URI dialing
  unless @num =~ /@/          # If we already have URI, skip all number processing
    @num.gsub!(/%(..)/) {$1.to_i(16).chr} # Convert %hh into ASCII

    if @num =~ /^#(.)(.*)/    # If number starts with '#'
      @p = $1; @num = $2      # next char is VSP code
    end

    @num.gsub!(/[^0-9*+]/,'') # Delete all fancy chars (only digits, '+' and '*' allowed)

    # sub! below removes prefixes:
    #  '+' - international format
    #   00 - European style international prefix (00)
    #  011 - US style international prefix (011)

    unless @num.sub!(/^(\+|00|011)/,'')  # If no international prefix, process special cases below
      case @num
        when /^[2-9]\d{6}$/         # Local call, 7-digit number
          @num = "1#{Area}#{@num}"  # prefix it with country and area code
        when /^[01]?([2-9]\d{9})/   # US number with or without "1" country code
          @num = '1' + $1           # add country code and truncate number to 10-digit
        when /^\*/                  # Voxalot voicemail, echotest & other special numbers
          else
            sys.Respond(603,'Wrong number, check & dial again')
      end
    end

    sys.Log("Number in ENUM format: #{@num}")

    @l = "Forced routing to provider #{@p}, template '#{VSPtab[@p]}'" # Assume user explicitly selected VSP

    if @p.empty?        # Automatic VSP selection?

      # Invoke selectVSP prior to ENUM lookup just in case we need to modify @num

      route                 # re-initialize variables
      selectVSP             # Pick appropriate provider for the call

      if enumuri = sys.ENUMLookup("+#{@num}.e164.org") # Check if NAPTR exists for the number
        sys.Log("ENUM entry found: '#{enumuri}'")      # If yes, call that URI
        sys.Dial(enumuri)                              # if call failed, call via regular VSP.
        status()                                       # If this is not what you want, add "return"
        sys.Log("Call to #{enumuri} failed (#{@reason}), will call again via regular VoIP provider")
      end

    end # @p.empty
  end   # URI

  dial(*args)   # dial selected number or URI
end

# *******************************  D I A L  ********************************

def dial(*args)
  sys.Log(@l) unless @l.empty?               # for the record :)
  if tpl=VSPtab[@p.to_s]                     # if provider is in our table
    tpl.gsub!(/\s*/,'')                      # Remove spaces
    @num = tpl.gsub(/@/,@num+'@')            # Insert number before '@'
  end
  sys.Dial(@num,*args) # Dial
  status()             # We shouldn't be here! Get error code...
  sys.Log("Call failed: code #{@code}, #{@reason}")
end

# ******************************  R O U T E  *******************************

def route(p='', l='')
  @p = p; @l = l
end

# *****************************  S T A T U S  ******************************

def status
  if (ptr = sys.LastDialled[0]).nil?
    @code = 487; @reason = 'Cancelled by Sipsorcery'
  else
    ptr = ptr.TransactionFinalResponse
    @code = ptr.StatusCode; @reason = ptr.ReasonPhrase
#   sys.Log("#{ptr.ToString()}")
  end
end

# *******************************  M A I N  ********************************
begin
  sys.Log("** Call from #{req.Header.From.ToString()} to #{req.URI.User} **")

  t = Time.now + ((Tz+8)*60*60)  # Get current time and adjust to local. SS Server is in GMT-8
  sys.Log(t.strftime('Local time: %c'))

  if sys.In               # If incoming call...
    name = req.Header.from.FromURI.User.to_s    # Get caller ID

    # Prepend 10-digit numbers with "1" (US country code) and remove 011 prefix (if present)

    name = ('1' + name) if name =~ /^[2-9]\d\d[2-9]\d{6}$/
    name.sub!(/^011/,'')

    sys.Log("FromName: '#{name}'")

    # Set FromName for sys.Dial. Change FromURI when forwarding to @local, or 
    # else Bria won't find contact in its phonebook!

    sys.SetFromHeader(name, nil, nil)

    if sys.IsAvailable()                              # If my ATA is registered
      callswitch("#{sys.Username}@local[fu=#{name}]") # forward all incoming calls to it
    elsif (8..23) === t.hour                          # else forward calls to my home
      sys.Log("#{sys.Username} is not online, forwarding call to home number...")
      callswitch("1234",35)                              # Note that '1234' is in my speed dial list
    end

    sys.Respond(480, "#{sys.Username} Not online") # switch to voice mail

  else                    # Outbound call ...

    # check if it's URI or phone number.
    # If destination's host is in our domain, it's a phone call

    num = req.URI.User.to_s; reqHost = req.URI.Host.to_s  # Get User and Host
    host = reqHost.downcase.slice(/[^:]+/)                # Convert to lowercase and delete optional ":port"

    num << '@' << reqHost unless Domains.find {|x| x == host} # URI dialing unless host is in our domain list

    callswitch(num)

  end
  sys.Respond(@code,@reason) # Forward error code to ATA
rescue
   # Gives a lot more details at what went wrong (borrowed from Myatus' dialplan)
   sys.Log("** Error: " + $!) unless $!.to_s =~ /Thread was being aborted./
end
GV+SG+SS

MikeTelis
Posts: 1582
Joined: Wed Jul 30, 2008 6:48 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by MikeTelis » Thu Jun 17, 2010 4:14 am

Could you post console log for

#2 905-967-1111

call? It should work... if it doesn't I guess the problem is that '#2' interferes with your ATA or softphone dialplan, they remove it from the dial string before sending it to Sipsorcery. That's why I'd like to see what you get in the Console.

notchy
Posts: 14
Joined: Sat Feb 20, 2010 3:19 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by notchy » Thu Jun 17, 2010 12:22 pm

If I don't input #2 and the phone # I'm dialing then the call goes through fine. It seems that Google Voice is always attempting to make the call even though I'm trying to override with my SIP provider of dialing #2. Which is VOIP.MS.

I know VOIP.MS works b/c I use it to dial toll free #'s and that part works in the code.

Here is my console log :

Code: Select all

Monitor 12:14:17:323: basetype=console, ipaddress=*, user=XXXX, event=*, request=*, serveripaddress=*, server=*, regex=.*.
ContactRegisterInProgress 12:14:19:042 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:14:19:042 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:14:20:386 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
ContactRegisterInProgress 12:14:29:151 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:14:29:151 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:14:30:589 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
DialPlan 12:14:39:807 sip1: New call from udp:69.196.154.86:5060 successfully authenticated by digest.
DialPlan 12:14:39:838 sip1: Using dialplan Complex Dial Plan for Out call to sip:24169671111@sipsorcery.com.
NewCall 12:14:39:838 sip1: Executing script dial plan for call to 24169671111.
DialPlan 12:14:39:932 sip1: ** Call from "C-Solutions" <sip:XXX@sipsorcery.com>;tag=ec0344721b2666c8o0 to 24169671111 **
DialPlan 12:14:39:948 sip1: Local time: 06/17/2010 08:14
DialPlan 12:14:39:979 sip1: Number in ENUM format: 12416967111
DialPlan 12:14:40:010 sip1: SDP on GoogleVoiceCall call had RTP socket mangled from 192.168.1.122:16448 to 69.196.154.86:16448.
DialPlan 12:14:40:010 sip1: UAS call progressing with Ringing.
DialPlan 12:14:40:010 sip1: Logging into google.com for XXXXX@gmail.com.
DialPlan 12:14:40:041 sip1: Google Voice pre-login page loaded successfully.
DialPlan 12:14:40:057 sip1: GALX key ieW3f1ESzso successfully retrieved.
ContactRegisterInProgress 12:14:40:448 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:14:40:448 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:14:40:729 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
DialPlan 12:14:41:229 sip1: Google Voice home page loaded successfully.
DialPlan 12:14:41:323 sip1: Call key +XHEQwAZMyLD/jkLxfkEhjv5sPk= successfully retrieved for XXXXX@gmail.com, proceeding with callback.
DialPlan 12:14:41:323 sip1: SIP Proxy setting application server for next call to user XXX as udp:69.59.142.213:5070.
DialPlan 12:14:41:416 sip1: Google Voice Call to 12416967111 forwarding to 18455132891 successfully initiated, callback timeout=30s.
DialPlan 12:14:44:995 sip1: SIP Proxy directing incoming call for user XXXX to application server udp:69.59.142.213:5070.
DialPlan 12:14:45:010 sip1: Google Voice Call callback received.
DialPlan 12:14:45:010 sip1: Answering client call with a response status of 200.
DialPlan 12:14:45:073 sip1: Google Voice Call was successfully answered in 5.06s.
DialPlan 12:14:45:166 sip1: Dial plan execution completed with normal clearing.
ContactRegisterInProgress 12:14:50:588 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:14:50:588 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:14:50:901 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
DialPlan 12:14:51:557 sip1: Matching dialogue found for BYE to sip:69.59.142.213:5060 from udp:69.59.142.213:5060.
ContactRegisterInProgress 12:15:00:682 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:15:00:682 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:15:01:088 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
ContactRegisterInProgress 12:15:10:978 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:15:10:978 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:15:11:275 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
ContactRegisterInProgress 12:15:21:072 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:15:21:072 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:15:21:447 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
ContactRegisterInProgress 12:15:31:181 sip1: Checking SIP Provider registration for VOIPMS.
ContactRegisterInProgress 12:15:31:181 sip1: DNS Manager does not currently have an entry for sip:toronto.voip.ms, delaying 10s.
NATKeepAlive 12:15:31:681 sip1: Requesting NAT keep-alive from proxy socket udp:69.59.142.213:5060 to udp:69.196.154.86:5060.
GV+SG+SS

MikeTelis
Posts: 1582
Joined: Wed Jul 30, 2008 6:48 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by MikeTelis » Thu Jun 17, 2010 12:39 pm

DialPlan 12:14:39:932 sip1: ** Call from "C-Solutions" <sip:XXX@sipsorcery.com>;tag=ec0344721b2666c8o0 to 24169671111 **
My guess was right, your ATA or softphone removed the '#' sign. The pound symbol is hex 23, so correct string is %2324169671111.

Check your ATA and/or softphone settings. Most certainly it's the dialplan (yes! X-Lite and Bria have dialplans of their own, check out account settings).

notchy
Posts: 14
Joined: Sat Feb 20, 2010 3:19 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by notchy » Thu Jun 17, 2010 12:48 pm

so how do i correct this. I forgot to mention I have a PAP2T device.

this is my dial plan :

*123|1xxxxxxxxxx|[2-9]xxxxxxxxx|011xxxxxxxxxxxxxxxxxxxxxxxxx| L:20,S:7,( x | *xx | 911S0 | 1[2-9]xx[2-9]xxxxxxS0 <:@sipbroker.com> | [x*][x*]. <:@sipbroker.com> | <#:>[x*][x*]. ))
GV+SG+SS

MikeTelis
Posts: 1582
Joined: Wed Jul 30, 2008 6:48 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by MikeTelis » Thu Jun 17, 2010 1:09 pm

<#:> tells ATA to remove leading #. You get what you asked for!

Try replacing <#:>[x*][x*]. with [*#]xx.|##xx.

notchy
Posts: 14
Joined: Sat Feb 20, 2010 3:19 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by notchy » Thu Jun 17, 2010 3:03 pm

Mike,

thanks so much it works great.
GV+SG+SS

MikeTelis
Posts: 1582
Joined: Wed Jul 30, 2008 6:48 am

Re: Flexible table-controlled dialplan, optimized for US, GV

Post by MikeTelis » Thu Jun 17, 2010 6:44 pm

Great! Probably I should have posted this on the 1st page but anyway: there is a more advanced version of this dialplan, it supports CNAM and alternating GV accounts.

Post Reply