diff options
Diffstat (limited to 'lib/agi_server.rb')
-rw-r--r-- | lib/agi_server.rb | 123 |
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 |