1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
module AGIServer
DEFAULT_AGI_SERVER_HOST = nil
DEFAULT_AGI_SERVER_PORT = 4573
def self.log_debug(message)
puts "DEBUG-AGI-Server: #{message.to_s}"
#Rails.logger.debug "AGI-Server: #{message}"
end
def self.log_error(message)
puts "ERROR-AGI-Server: #{message.to_s}"
#Rails.logger.error "AGI-Server: #{message}"
end
class Client
AGI_AVAILABLE_METHODS = ['directory_lookup']
@client = nil
@options = nil
def set_variable(variable_name, variable_value)
if !@client
return false
end
@client.puts "SET VARIABLE #{variable_name.to_s} \"#{variable_value.to_s}\""
end
def directory_lookup
number = @options['agi_arg_1'].to_s.gsub(/[^0-9A-Za-z\*_-]/, '')
number_type = @options['agi_arg_3'].to_s
client_id = @options['agi_arg_2'].to_i
if number.blank?
number = @options['agi_dnid'].to_s.gsub(/[^0-9A-Za-z\*_-]/, '')
number_type = "unknown"
client_id = 1
end
if client_id > 0
if number != ""
phone_number = PhoneNumber.where(:number => number, :phone_numberable_type => "SipAccount").first
if phone_number.blank?
set_variable(:directory_status, 'unknown')
set_variable(:directory_message, 'Number not found in directory')
return nil
end
set_variable(:directory_status, 'exact_match')
set_variable(:directory_message, 'Exact match')
set_variable(:directory_number_type, phone_number.phone_numberable_type)
set_variable(:directory_number_destination, phone_number.phone_numberable.to_s)
set_variable(:directory_number_host, "1")
set_variable(:directory_number_name, phone_number.name)
set_variable(:directory_number_number, phone_number.number)
set_variable(:directory_number_country_code, phone_number.country_code)
set_variable(:directory_number_area_code, phone_number.area_code)
set_variable(:directory_number_central_office_code, phone_number.central_office_code)
set_variable(:directory_number_subscriber_number, phone_number.subscriber_number)
set_variable(:directory_number_extension, phone_number.extension)
if phone_number.phone_numberable_type == "SipAccount"
set_variable(:directory_caller_name, phone_number.phone_numberable.caller_name)
end
else
set_variable(:directory_status, 'error')
set_variable(:directory_message, 'No number specified')
end
else
set_variable(:directory_status, 'error')
set_variable(:directory_message, 'No ID')
end
end
def handler(client)
@client = client
@options = Hash.new
while @client
buffer = @client.gets().strip
if buffer == ""
if @options['agi_network_script'] && AGI_AVAILABLE_METHODS.include?(@options['agi_network_script'].to_s.downcase)
self.send(@options['agi_network_script'].to_s.downcase)
end
break
elsif buffer =~ /^.*:\s/
key, value = buffer.split(': ')
@options[key]= value
end
end
@client.close
end
end
def self.server( host = DEFAULT_AGI_SERVER_HOST, port = DEFAULT_AGI_SERVER_PORT )
log_debug("Starting server process.")
require 'socket'
server = TCPServer.open(4573)
if server
run_server = true
end
client_handler_id = 0
while run_server
log_debug("Server listening on: #{server.local_address.ip_address}:#{server.local_address.ip_port}")
Thread.start(server.accept) do |client|
remote_ip = client.remote_address.ip_address
remote_port = client.remote_address.ip_port
begin
client_handler = Client.new
client_handler_id = client_handler.object_id
log_debug("[#{client_handler_id}] Connection opened: #{remote_ip}:#{remote_port}")
client_handler.handler(client)
log_debug("[#{client_handler_id}] Connection closed: #{remote_ip}:#{remote_port}")
rescue => e
log_error("[#{client_handler_id}] #{e.class.to_s}: #{e.to_s}, closing connection: #{remote_ip}:#{remote_port}")
ensure
client.close()
end
end
end
end
end
|