summaryrefslogtreecommitdiff
path: root/lib/agi_server.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/agi_server.rb')
-rw-r--r--lib/agi_server.rb123
1 files changed, 123 insertions, 0 deletions
diff --git a/lib/agi_server.rb b/lib/agi_server.rb
new file mode 100644
index 0000000..29c06c4
--- /dev/null
+++ b/lib/agi_server.rb
@@ -0,0 +1,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