Sunr1ses / google-voice-sipsorcery-dialplans

Automatically exported from code.google.com/p/google-voice-sipsorcery-dialplans
1 stars 0 forks source link

Destination number never rings. #130

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Use simple dial plan with sipsorcery on a Linksys WIP-300 wifi voip phone
2. Connected through a 4G modem (CLEAR)

What is the expected output? What do you see instead?
The other number (another cellphone) should ring and I should be able to pick 
up, instead it never rings. When I tried calling from my cellphone to the GV 
number it does connect successfully.

What version of the product are you using? On what operating system?
Mac Snow Leopard

Please provide any additional information below.
Console output:
DialPlan 06:05:49:985 sip1(19048): Logging into google.com for 
guanacux@gmail.com.
DialPlan 06:05:50:064 sip1(19048): Google Voice pre-login page loaded 
successfully.
DialPlan 06:05:50:251 sip1(19048): GALX key KBNoa5z3XaQ successfully retrieved.
DialPlan 06:05:52:767 sip1(19048): Google Voice home page loaded successfully.
DialPlan 06:05:53:642 sip1(19048): Call key CrpVa67S1Y1nHECPEOGjYVzqrHo= 
successfully retrieved for guanacux@gmail.com, proceeding with callback.
DialPlan 06:05:53:642 sip1(15748): SIP Proxy setting application server for 
next call to user guanacux as udp:69.59.142.213:5070.
DialPlan 06:05:53:829 sip1(19048): Google Voice Call to 16182011779 initiated, 
callback #14256063958, phone type 7, timeout 45s.
DialPlan 06:06:38:828 sip1(19048): Google Voice Call timed out waiting for 
callback.
DialPlan 06:06:39:296 sip1(19048): Google Voice Call to 16182011779 was 
successfully cancelled.
DialPlan 06:06:39:296 sip1(19048): Dialplan cleanup for guanacux.
DialPlan 06:06:39:328 sip1(19048): Dial plan execution completed without 
answering and with no last failure status.
DialPlan 06:06:39:328 sip1(19048): UAS call failed with a response status of 
480.

Original issue reported on code.google.com by guana...@gmail.com on 15 Jun 2011 at 6:13

GoogleCodeExporter commented 8 years ago
The problem is here:

DialPlan 06:06:38:828 sip1(19048): Google Voice Call timed out waiting for 
callback.

It means that Google Voice (most likely) called you back at +1 (425) 606-3958 
but this call never reached your Sipsorcery SIP account. First, check your 
IPKall settings, the DID must be forwarding calls to user: <your Sipsorcery SIP 
account name> and server: sipsorcery.com. If this is true, check if you get the 
callback when you initiate the call manually, from Google Voice website.

Original comment by mte...@gmail.com on 15 Jun 2011 at 11:50

GoogleCodeExporter commented 8 years ago
I check the IPKall account and everything seems fine. Username is correct. 
proxy is 'sipsorcery.com'. 

I tried a GV call from the web interface of GV and the same problem came up. I 
can't hear the other party but they can hear me fine.

This is what the console gave me at that call:

DialPlan 20:31:45:739 sip1(14740): No dialplan specified for incoming call to 
mnegro@sipsorcery.com, registered bindings will be used.
DialPlan 20:31:45:739 sip1(14740): Forwarding incoming call for 
mnegro@sipsorcery.com to 1 bindings.
NewCall 20:31:45:739 sip1(14740): Executing script dial plan for call to mnegro.
DialPlan 20:31:45:786 sip1(14740): Commencing Dial with: mnegro@sipsorcery.com.
DialPlan 20:31:45:802 sip1(14740): Call leg is for local domain looking up 
bindings for mnegro@sipsorcery.com for call leg mnegro@sipsorcery.com.
DialPlan 20:31:45:817 sip1(14740): 1 found for mnegro@sipsorcery.com.
DialPlan 20:31:45:817 sip1(14740): ForkCall commencing call leg to 
sip:mnegro@64.107.81.80:24681.
DialPlan 20:31:45:817 sip1(14740): SIPClientUserAgent Call using alternate 
outbound proxy of udp:69.59.142.213:5060.
DialPlan 20:31:45:817 sip1(14740): Switching to sip:mnegro@64.107.81.80:24681 
via udp:69.59.142.213:5060.
DialPlan 20:31:45:817 sip1(14740): SDP on UAC call had public IP not mangled, 
RTP socket 66.54.140.46:21708.
DialPlan 20:31:45:911 sip1(14740): Information response 100 Trying for 
sip:mnegro@64.107.81.80:24681.
DialPlan 20:31:45:927 sip1(14740): Information response 180 Ringing for 
sip:mnegro@64.107.81.80:24681.
DialPlan 20:31:45:927 sip1(14740): UAS call progressing with Ringing.
DialPlan 20:31:46:489 sip1(14740): Response 200 OK for 
sip:mnegro@64.107.81.80:24681.
DialPlan 20:31:46:489 sip1(14740): SDP on UAC response had RTP socket mangled 
from 192.168.80.147:16450 to 64.107.81.80:16450.
DialPlan 20:31:46:489 sip1(14740): Cancelling all call legs for ForkCall app.
DialPlan 20:31:46:489 sip1(14740): Answering client call with a response status 
of 200.
DialPlan 20:31:46:536 sip1(14740): Dial command was successfully answered in 
0.72s.
DialPlan 20:31:46:536 sip1(14740): Dialplan cleanup for mnegro.
DialPlan 20:31:46:536 sip1(14740): Dial plan execution completed with normal 
clearing.
DialPlan 20:31:58:396 sip1(14740): Matching dialogue found for BYE to 
sip:69.59.142.213:5060 from udp:69.59.142.213:5060.

THANK YOU FOR ALL YOUR HELP!

Original comment by marlonne...@gmail.com on 15 Jun 2011 at 8:33

GoogleCodeExporter commented 8 years ago
Even when I dialed the IP Kall directly I have the same issue...I can't heat 
party B. but party B can hear me (party A) fine. I hope that helps. It sounds 
to me that my dialplan has an issue...so here is my dial plan:

# Copyright(c) 2010 Mike Telis

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# Click "View raw file" in the lower right for the best copy/paste view

AREA_CODE = '210' # my area code
GV_USER   = 'marlonnegro06@gmail.com@gmail.com'  # my GV e-mail address 
(user@gmail.com)
GV_PASS   = '******'  # my GV password
CB_NUMBER = '12062037167'  # my 11-digit SIP number (only one)

SPEED_DIAL = {                     # my speed dial numbers
 '1'   => '17734139119',          # Jorge
 '123' => '12345678901',          # Work
 '45'  => '17479876543',          # Gizmo BFF
 '411' => '8004664411',           # Google 411
 '266' => '4153767253@podlinez.com',     # CNN Headlines
}

begin
   sys.Log "** Call from #{req.Header.From} to #{req.URI.User} **"

 if sys.Out    # if outbound call
   num = req.URI.User.to_s        # Get a string copy of the number to dial

   num = SPEED_DIAL[num] || num   # Substitute with speed dial entry, if any

   case num
     when /@/ then sys.Dial num   # URI dialing
     when /^[2-9]\d{6}$/          # Local call, 7-digit number
       num = '1'+ AREA_CODE + num # prefix it with country and area code
     when /^[01]?([2-9]\d{9})/    # US number with or without country code
       num = '1' + $1             # add country code and truncate number to 10-digit
     when /^(011|00|\+)(\d{9,})/  # international number
       num = '+' + $2             # GoogleVoiceCall works with '+' prefix only

     else sys.Respond 603, 'Wrong number, check & dial again'
   end

   sys.Log "Calling #{num} via Google Voice"
   sys.GoogleVoiceCall GV_USER, GV_PASS, CB_NUMBER, num, '.*', CB_NUMBER =~ /^1206/ ? 7 : 1, 30

 else          # sys.Out
   sys.Dial "#{sys.Username}@local"
 end

rescue
 sys.Log("** Error: " + $!) unless $!.to_s =~ /Thread was being aborted./
end

Original comment by marlonne...@gmail.com on 15 Jun 2011 at 8:37

GoogleCodeExporter commented 8 years ago
1-way audio problem has nothing to do with the dialplan and account settings. 
Typically it's related to STUN / router settings or codec incompatibility. BTW, 
you've stolen topic from original poster, not exactly a good deed.

Original comment by mte...@gmail.com on 16 Jun 2011 at 3:03

GoogleCodeExporter commented 8 years ago
It was a related problem with the same setup actually. About the original post, 
it does ring from the GV interface now, but it gives me that one way audio 
problem as well...Which codec or stun should I use?

Original comment by guana...@gmail.com on 16 Jun 2011 at 7:09

GoogleCodeExporter commented 8 years ago
Use G.711 aka PCM (PCMU, PCMA), this codec is ubiquitous. I use 
stun.voxalot.com, works so far :)

If it doesn't help, put ATA or PC (whatever you use as SIP client) into DMZ of 
your router.

Original comment by mte...@gmail.com on 16 Jun 2011 at 9:59

GoogleCodeExporter commented 8 years ago
I have a Linksys PAP2T (bought new NOT from any VoIP provider) and it is 
running the G.711u and I change it to G.711a and same results, I also tried a 
few stun servers (voxalot, sipsorcery, etc) and the same results. When I try 
calling from the GV interface, I can't hear the other person but they can hear 
me. What else can it be..

Here is the console output:

nitor 21:57:36:623: basetype=console, ipaddress=*, user=mnegro, event=*, 
request=*, serveripaddress=*, server=*, regex=.*.
Registrar 21:58:46:061 sip1(7840): Authentication required for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930.
Registrar 21:58:46:202 sip1(7840): Binding update request for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930, expiry requested 3600s 
granted 3600s.
RegisterSuccess 21:58:46:233 sip1(7840): Registration successful for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930, binding 
sip:mnegro@192.168.80.27:5060;expiry=3600 (1).
RegisterSuccess 21:58:46:233 sip1(7840): Registration successful for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930, binding 
sip:mnegro@192.168.80.147:5060;expiry=3600 (2).
Registrar 22:01:13:016 sip1(7840): Authentication required for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930.
Registrar 22:01:13:282 sip1(7840): Binding update request for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930, expiry requested 3600s 
granted 3600s.
RegisterSuccess 22:01:13:328 sip1(7840): Registration successful for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930, binding 
sip:mnegro@192.168.80.27:5060;expiry=3600 (1).
RegisterSuccess 22:01:13:328 sip1(7840): Registration successful for 
mnegro@sipsorcery.com from udp:64.107.81.80:37930, binding 
sip:mnegro@192.168.80.147:5060;expiry=3600 (2).
DialPlan 22:02:57:548 sip1(21972): No dialplan specified for incoming call to 
mnegro@sipsorcery.com, registered bindings will be used.
DialPlan 22:02:57:564 sip1(21972): Forwarding incoming call for 
mnegro@sipsorcery.com to 2 bindings.
NewCall 22:02:57:564 sip1(21972): Executing script dial plan for call to mnegro.
DialPlan 22:02:57:611 sip1(21972): Commencing Dial with: mnegro@sipsorcery.com.
DialPlan 22:02:57:642 sip1(21972): Call leg is for local domain looking up 
bindings for mnegro@sipsorcery.com for call leg mnegro@sipsorcery.com.
DialPlan 22:02:57:642 sip1(21972): 2 found for mnegro@sipsorcery.com.
DialPlan 22:02:57:642 sip1(21972): ForkCall commencing call leg to 
sip:mnegro@64.107.81.80:37930.
DialPlan 22:02:57:642 sip1(21972): ForkCall commencing call leg to 
sip:mnegro@64.107.81.80:11014.
DialPlan 22:02:57:642 sip1(21972): SIPClientUserAgent Call using alternate 
outbound proxy of udp:69.59.142.213:5060.
DialPlan 22:02:57:642 sip1(21972): SIPClientUserAgent Call using alternate 
outbound proxy of udp:69.59.142.213:5060.
DialPlan 22:02:57:642 sip1(21972): Switching to sip:mnegro@64.107.81.80:37930 
via udp:69.59.142.213:5060.
DialPlan 22:02:57:642 sip1(21972): Switching to sip:mnegro@64.107.81.80:11014 
via udp:69.59.142.213:5060.
DialPlan 22:02:57:658 sip1(21972): SDP on UAC call had public IP not mangled, 
RTP socket 66.54.140.46:18028.
DialPlan 22:02:57:658 sip1(21972): SDP on UAC call had public IP not mangled, 
RTP socket 66.54.140.46:18028.
DialPlan 22:02:57:908 sip1(21972): Information response 100 Trying for 
sip:mnegro@64.107.81.80:37930.
DialPlan 22:02:58:080 sip1(21972): Information response 180 Ringing for 
sip:mnegro@64.107.81.80:37930.
DialPlan 22:02:58:080 sip1(21972): UAS call progressing with Ringing.
DialPlan 22:02:58:408 sip1(21972): Response 200 OK for 
sip:mnegro@64.107.81.80:37930.
DialPlan 22:02:58:423 sip1(21972): SDP on UAC response had RTP socket mangled 
from 192.168.80.27:16450 to 64.107.81.80:16450.
DialPlan 22:02:58:423 sip1(21972): Cancelling all call legs for ForkCall app.
DialPlan 22:02:58:423 sip1(21972): Cancelling forwarded call leg, sending 
CANCEL to sip:mnegro@64.107.81.80:11014.
DialPlan 22:02:58:423 sip1(21972): Answering client call with a response status 
of 200.
DialPlan 22:02:58:517 sip1(21972): Dial command was successfully answered in 
0.88s.
DialPlan 22:02:58:517 sip1(21972): Dialplan cleanup for mnegro.
DialPlan 22:02:58:720 sip1(21972): Dial plan execution completed with normal 
clearing.
DialPlan 22:03:11:580 sip1(21972): Matching dialogue found for BYE to 
sip:69.59.142.213:5060 from udp:69.59.142.213:5060.

THANK YOU!

Original comment by marlonne...@gmail.com on 16 Jun 2011 at 10:06

GoogleCodeExporter commented 8 years ago
Probably you forgot to enable NAT mapping in your ATA. See, this issue has 
nothing to do with Sipsorcery, Google Voice or IPKall, the problem is somewhere 
in your router and/or ATA configuration.

Original comment by mte...@gmail.com on 18 Jun 2011 at 2:18

GoogleCodeExporter commented 8 years ago
I see..I thought that was enable because it works fine directly with sipgate. I 
have a Clear 4G Modem and it has NAT configuration and DMZ capabilities. I have 
tried forwarding port 5060 on it and placing the wifi ip phone on DMZ and still 
the same results. I have also tried doing a complex dial plan using sipgate 
(knowing that it works) but since it has to go through sipsorcery when I dial, 
I still hear nothing.

I don't know what must I be doing wrong anymore...we should go back to square 
zero.

Original comment by guana...@gmail.com on 18 Jun 2011 at 3:45

GoogleCodeExporter commented 8 years ago
The problem is with RTP traffic and therefore, you must forward RTP ports to 
your ATA. 5060 is SIP port; you'll find RTP ports range in your ATA settings :)

Original comment by mte...@gmail.com on 18 Jun 2011 at 6:06

GoogleCodeExporter commented 8 years ago
Thank you...After all this time, I changed ISP providers and that solved it!. I 
was using CLEAR 4G Modem and I switched back to AT&T and that did it. There 
might have been a way to put the Wifi VoIP in the DMZ with the 4G modem but I 
tried with it's simple web interface and it didn't work. AT&T worked out of the 
box with the simple dial plan. Thank you everyone for all the support!

Original comment by guana...@gmail.com on 25 Jun 2011 at 7:04

GoogleCodeExporter commented 8 years ago
use this

# Copyright 2010 Mike Telis
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# Click "View raw file" in the lower right for the best copy/paste view

class Hash; alias :+ :merge; end; Home,Mobile,Work,Gizmo = 1,2,3,7

# --------BEGIN MANDATORY ENTRIES SECTION-----------------------------#         

Area = '215'          # my area code, this will be added to 7-digit dialouts
Tz   = -5             # my time zone (GMT format, e.g. Eastern = -5, Central = 
-6)

# *************** Google Voice Configuration Section *********************

Credentials = { :usr => 'login', :pwd => 'pass' } # Your GV login and password

# Your account description is next. It should contain at least one callback
# number.

GVaccount = [
  Credentials + { :cb => '(206) 242-1234' }, # IPKall callback number
  Credentials + { :cb => '(747) 234-5678' }, # Gizmo callback number
]

# *************** SIP Provider Configuration Section *********************

VSPtab = {
  '0' => '00 @ F9',                # Future-nine default route
  '2' => '02 @ F9',                # Future-nine grey route
  '3' => '03 @ F9',                # Future-nine white route
  '4' => '04 @ F9',                # Future-nine premium route
  '5' => '@ Sipgate',              # sipgate
  '6' => '@ Gizmo',                # gizmo 
}

# ------ END MANDATORY ENTRIES SECTION-----------------------------#            

# ------ BEGIN OPTIONAL PARAMETERS SECTION ------------------------#            

# Speed dial entries. Format: "short code" => "destination (POTS or SIP)"

Speeddial = {
  '0'   => '123456789',                # my 0 (zero) key's speeddial number
  '1'   => 'wwwxxxyyyy',               # home speed dial
  '411' => '8004664411',               # Google's Directory Assistance, GOOG-411  
  '303' => '303@sip.blueface.ie',      # Blueface speaking clock (Ireland time)
  '266' => '4153767253@podlinez.net',  # CNN Headlines (266 = "CNN")
  '677' => '8186882773@podlinez.net',  # NPR's most e-mailed stories (677 ="NPR")                     
  '742' => '6506441934@podlinez.net',  # Prairie Home Companion's, or PHC's
                                       # News from Lake Wobegon (742 = "PHC")
  '932' => '7755333366',               # Columbus OH-based national weather (932 = "WEA[ther]")                    
}

# CNAM table: number in ENUM format => caller's name

CNAM = {
 '12125551212' => 'Dear mom',
 '12153332211' => 'Bratty kid',
}

# Uncomment next line and insert your White Pages API key, if you have it
# WP_key = 'Your_White_Pages_API_key_here'      # White Pages API key

# ------ END OPTIONAL PARAMETERS SECTION ==------------------------#            

# Serviced domains, must be in lowercase!

Domains  = 
['sipsorcery.com','sip.sipsorcery.com','sip1.sipsorcery.com','sip2.sipsorcery.co
m','69.59.142.213']
Host     =  'sipsorcery.com' # incoming calls will come with this host

# Enum list from sipbroker

EnumDB = [
 'e164.org',
 'e164.info',
 'e164.arpa',
 'e164.televolution.net',
 'enum.org',
]

# Uncomment line below to enable misdialing safeguards
# EnableSafeguards = 1

Allowed_Country = %w{  
1 33 36 39 41 420 44 49 7 86 883 886 90 972
}

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

ExcludedPrefixes = [
   ' 1 (900 | 809)',               # USA Premium
   ' 1 \d\d\d 555 1212',           # USA Directory assistance
   '44 (9 | 55 | 70 | 84 | 87)',   # UK Premium
   '49 (1 [^567] | 900)',          # Germany Premium
   '39 (1 | 84 | 89)',             # Italy Premium 
   '420 90',                       # Czech Premium 
]

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

def selectVSP    # VoIP provider selection

  case @num
    when /^1([2-9]\d\d)/                 # North America
      case $1                            # check area code
         when "747"                   
           route(6,"Gizmo5 to Gizmo5 call")
         else
           gvcall GVaccount
           sys.Log("GoogleVoiceCall failed, routing thru Future-Nine")
           route(4,"Destination - North America non-GV")
      end

    when /^972(5|6)/                    # Israel mobile
       route(3,"Destination - Israel mobile")

    else
      rejectCall(603,"Number's too short, check & dial again") if @num.length < 9
      route(0,"Default route applied")
  end
end

# ****************************  C H E C K   N U M **************************

def checkNum
  @num.match(/^\D/) && return  # skip if number doesn't begin with a digit

  # Reject calls to not blessed countries and premium numbers 
  # (unless VSP was forced using #n dial prefix)

  rejectCall(503,"Calls to this country not allowed") unless @num.match "^(#{Allowed_Country.join('|')})"
  rejectCall(503,"Calls to #$&* not allowed") if @num.match '^(' + ExcludedPrefixes.map { |x| "(:?#{x.gsub(/\s*/,'')})" }.join('|') + ')'
end  

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

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

  num.gsub!(/%(..)/) {$1.to_i(16).chr} # Convert %hh into ASCII
  @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

    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,6}$/       # Local call, 7-digit number
          @num = '1' + Area + @num  # prefix it with country and area code
        when /^[01]?([2-9]\d{9,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
            rejectCall(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?
      checkNum if defined? EnableSafeguards

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

      EnumDB.each do |db|   # Look in all enum databases
        if enumuri = sys.ENUMLookup("#{@num}.#{db}")
          sys.Log("ENUM entry found: '#{enumuri}' in #{db} database")
          sys.Dial(enumuri) # If yes, call that URI
          status()
          sys.Log("Call to #{enumuri} failed (#{@reason})")
        end
      end                   # ENUM not found or failed, call via regular VSP
    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

# ****************************  G V   C A L L  *****************************

def gvcall accounts, n = [2,accounts.length].min, r = 0
  n.times do |acnt|
    a = {:num => @num, :tmo => 15, :match => '.*'}   # init with num & default values
    a.update(accounts[(acnt+r) % accounts.length])   # add other params
    a[:cb].gsub!(/\D/,'')                            # Delete all but digits
    a[:type] ||= (a[:cb] =~ /^1?747/) ? Gizmo : Home # if no type, define it depending on area code
    sys.GoogleVoiceCall *a.values_at(:usr, :pwd, :cb, :num, :match, :type, :tmo)
  end
end

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

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

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

def status
  begin
    @code, @reason = 487, 'Cancelled by Sipsorcery' unless @code
    sys.LastDialled.each do |ptr|
      if ptr
        ptr = ptr.TransactionFinalResponse
        @code = ptr.StatusCode; @reason = ptr.ReasonPhrase; break if @code == 200
      end
    end
  rescue
  end
end

# ************************  r e j e c t C a l l  ***************************

def rejectCall code, reason
  @code = code; @reason = reason
  sys.Respond code, reason
end 

# *************************  f o r m a t N u m  ****************************

def formatNum(num)
  case num
    when /^([17])(\d{3})(\d{3})(\d{4})$/,       # USA, Russia
         /^(380|375)(\d{2})(\d{3})(\d{4})$/,    # Ukraine, Belarus
         /^(41)(\d{2})(\d{3})(\d{4})$/,         # Swiss
         /^(972|998)(\d{2})(\d{3})(\d{4})$/,    # Israel, Uzbekistan
         /^(36)(\d)(\d{3})(\d{4})$/             # Hungary

      "+#$1 (#$2) #$3-#$4"

    when /^(33|44)(\d)(\d{2})(\d{2})(\d{2})(\d{2})$/ # France, UK

      "+#$1 (#$2) #$3 #$4 #$5 #$6"

    when /^(39|34|49)(\d+)$/                    # Italy, Spain, Germany

      "+#$1 #$2"

    when /^(420)(\d{3})(\d{3})(\d{3})$/         # Czech Republic

      "+#$1 #$2 #$3 #$4"

    else num    # No match - skip formatting
  end
end

# *******************************  M A I N  *****************************
begin
  sys.Log("** Call from #{req.Header.From} to #{req.URI.User} **") 
  sys.ExtendScriptTimeout(15)    # preventing long running dialscript time-out
  @t = Time.now + ((Tz+8)*60*60) # Get current time and adjust to local (GMT+3). 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 int'l prefix (if present)

    name = ('1' + name) if name =~ /^[2-9]\d\d[2-9]\d{6}$/
    name.sub!(/^(\+|00|011)/,'')   # Remove international prefixes, if any

    prs = req.URI.User.split('.')  # parse User into chunks
    trunk = prs[-2]                # get trunk name
    user  = prs[-1]                # called user name

    # Check CNAM first. If not found and US number, try to lookup caller's name in Whitepages

    if !(cname = CNAM[name]) && name =~ /^1([2-9]\d\d[2-9]\d{6})$/ && defined?(WP_key)
      url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'http%3A%2F%2Fapi.whitepages.com%2Freverse_phone%2F1.0%2F%3Fphone%3D#{$1}%3Bapi_key%3D#{WP_key}'%20and%20itemPath%3D'wp.listings.listing'&format=json"
      if js = sys.WebGet(url,4).to_s
        cname, dname, city, state = %w(businessname displayname city state).map {|x| js =~ /"#{x}":"([^"]+)"/; $1}
        cname ||= dname; cname ||= "#{city}, #{state}" if city && state
      end
    end

    sys.Log("Caller's number: '#{name}'"); sys.Log("Caller's name:   '#{cname}'") if cname

    sys.SetFromHeader(formatNum(cname || name), nil, Host)  # Set FromName & FromHost for sys.Dial

    # Forward call to bindings
    # Change FromURI when forwarding to @local, or else Bria won't
    # find contact in its phonebook!

    callswitch("#{user}@local[fu=#{name}]",45) unless (30..745) === @t.hour*100 + @t.min # forward straight to VM from 0:30a to 7:45a

    @code, @reason = 480, "#{user} is asleep" unless @code # if nothing else, must be night hour
    @code = 486 if trunk =~ /IPCOMM/i ## *** temporary fix for IPCOMMS ***

  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.include?(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

Original comment by ThomasJK...@gmail.com on 15 Jul 2011 at 8:16

GoogleCodeExporter commented 8 years ago
Closed as resolved. Marked Invalid as the "no audio" problem was caused by the 
ISP, not our scripts.

Original comment by easter...@gmail.com on 1 Mar 2012 at 10:25