summaryrefslogtreecommitdiff
path: root/app/controllers/config_snom_controller.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/config_snom_controller.rb')
-rw-r--r--app/controllers/config_snom_controller.rb1169
1 files changed, 1169 insertions, 0 deletions
diff --git a/app/controllers/config_snom_controller.rb b/app/controllers/config_snom_controller.rb
new file mode 100644
index 0000000..40f0c4e
--- /dev/null
+++ b/app/controllers/config_snom_controller.rb
@@ -0,0 +1,1169 @@
+class ConfigSnomController < ApplicationController
+ MAX_SIP_ACCOUNTS_COUNT = 11
+ MAX_SOFTKEYS_COUNT = 12 + (42 * 3) - 1
+ MAX_DIRECTORY_ENTRIES = 20
+ KEYPAD_TO_CHAR = {
+ '0' => [' ','-','.',',','0'],
+ '1' => [' ','-','.',',','1'],
+ '2' => ['a','b','c','2'],
+ '3' => ['d','e','f','3'],
+ '4' => ['g','h','i','4'],
+ '5' => ['j','k','l','5'],
+ '6' => ['m','n','o','6'],
+ '7' => ['p','q','r','s','7'],
+ '8' => ['t','u','v','8'],
+ '9' => ['w','x','y','z','9'],
+ }
+
+ skip_authorization_check
+
+ before_filter { |controller|
+ @mac_address = params[:mac_address].to_s.upcase.gsub(/[^0-9A-F]/,'')
+ @provisioning_authenticated = false
+
+ if !params[:provisioning_key].blank?
+ @phone = Phone.where({ :provisioning_key => params[:provisioning_key] }).first
+ if @phone
+ @provisioning_authenticated = true
+ @mac_address = @phone.mac_address
+ end
+ end
+
+ if ! @mac_address.blank? then
+ if !@phone
+ @phone = Phone.where({ :mac_address => @mac_address }).first
+ end
+
+ if ! @phone && PROVISIONING_AUTO_ADD_PHONE
+ tenant = Tenant.where(:id => PROVISIONING_AUTO_TENANT_ID).first
+ if ! tenant
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- Tenant not found -->",
+ )
+ return
+ end
+
+ @phone = tenant.phones.build
+ @phone.mac_address = @mac_address
+ @phone.hot_deskable = true
+
+ mac_address_to_model = {
+ '00041325' => 'Snom 300',
+ '00041328' => 'Snom 300',
+ '0004132D' => 'Snom 300',
+ '0004132F' => 'Snom 300',
+ '00041334' => 'Snom 300',
+ '00041350' => 'Snom 300',
+ '0004133B' => 'Snom 300',
+ '00041337' => 'Snom 300',
+ '00041324' => 'Snom 320',
+ '00041327' => 'Snom 320',
+ '0004132C' => 'Snom 320',
+ '00041331' => 'Snom 320',
+ '00041335' => 'Snom 320',
+ '00041338' => 'Snom 320',
+ '00041351' => 'Snom 320',
+ '00041323' => 'Snom 360',
+ '00041329' => 'Snom 360',
+ '0004132B' => 'Snom 360',
+ '00041339' => 'Snom 360',
+ '00041390' => 'Snom 360',
+ '00041326' => 'Snom 370',
+ '0004132E' => 'Snom 370',
+ '0004133A' => 'Snom 370',
+ '00041352' => 'Snom 370',
+ '00041340' => 'Snom 820',
+ '00041345' => 'Snom 821',
+ '00041348' => 'Snom 821',
+ '00041341' => 'Snom 870',
+ }
+
+ @phone.phone_model = PhoneModel.where(:name => mac_address_to_model[@mac_address[0, 8]]).first
+ if ! @phone.save
+ render(
+ :status => 500,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- #{@phone.errors.messages.inspect} -->",
+ )
+ return
+ end
+
+ if ! PROVISIONING_AUTO_ADD_SIP_ACCOUNT
+ return
+ end
+
+ caller_name_index = 0
+ sip_account_last = tenant.sip_accounts.where('caller_name LIKE ?', "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}%").sort { |item1, item2|
+ item1.caller_name.gsub(/[^0-9]/, '').to_i <=> item2.caller_name.gsub(/[^0-9]/, '').to_i
+ }.last
+
+ if sip_account_last
+ caller_name_index = sip_account_last.caller_name.gsub(/[^0-9]/, '').to_i
+ end
+ caller_name_index = caller_name_index + 1
+
+ @sip_account = tenant.sip_accounts.build
+ @sip_account.caller_name = "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}#{caller_name_index}"
+ @sip_account.call_waiting = CALL_WAITING
+ @sip_account.clir = DEFAULT_CLIR_SETTING
+ @sip_account.clip = DEFAULT_CLIP_SETTING
+ @sip_account.voicemail_pin = random_pin
+ @sip_account.callforward_rules_act_per_sip_account = CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT
+ @sip_account.hotdeskable = false
+ loop do
+ @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME)
+ break unless SipAccount.exists?(:auth_name => @sip_account.auth_name)
+ end
+ @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD)
+
+ if ! @sip_account.save
+ render(
+ :status => 500,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- #{@sip_account.errors.messages.inspect} -->",
+ )
+ return
+ end
+
+ phone_sip_account = PhoneSipAccount.new()
+ phone_sip_account.phone_id = @phone.id
+ phone_sip_account.sip_account_id = @sip_account.id
+
+ if ! phone_sip_account.save
+ render(
+ :status => 500,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- #{phone_sip_account.errors.messages.inspect} -->",
+ )
+ return
+ end
+
+ end
+ elsif ! params[:phone].blank? then
+ @phone = Phone.where({ :id => params[:phone].to_i }).first
+ end
+
+ if ! @phone
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- Phone not found -->",
+ )
+ end
+
+ if ! params[:sip_account].blank?
+ @sip_account = @phone.sip_accounts.where({ :id => params[:sip_account].to_i }).first
+ if ! @sip_account
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- SipAccount not found -->",
+ )
+ end
+ end
+
+ if ! params[:type].blank?
+ @type = params[:type].to_s.strip.downcase
+ end
+
+ if ! params[:keys].blank?
+ @dialpad_keys = params[:keys].to_s.strip
+ end
+ }
+
+
+ def show
+ send_sensitve = @provisioning_authenticated || !@phone.provisioning_key_active
+ @phone_settings = Hash.new()
+
+ if defined?(PROVISIONING_KEY_LENGTH) && PROVISIONING_KEY_LENGTH > 0
+ if @phone.provisioning_key.blank?
+ @phone.update_attributes({ :provisioning_key => SecureRandom.hex(PROVISIONING_KEY_LENGTH), :provisioning_key_active => false })
+ elsif @provisioning_authenticated
+ @phone.update_attributes({ :provisioning_key_active => true })
+ end
+
+ if send_sensitve
+ if defined?(PROVISIONING_PROTOCOL) && PROVISIONING_PROTOCOL
+ provisioning_protocol = PROVISIONING_PROTOCOL
+ else
+ provisioning_protocol = request.protocol
+ end
+ @phone_settings[:setting_server] = "#{provisioning_protocol}#{request.host_with_port}/snom-#{@phone.provisioning_key}.xml"
+ end
+ end
+
+ if defined?(PROVISIONING_SET_HTTP_USER) && @phone.http_user.blank?
+ if PROVISIONING_SET_HTTP_USER.class == Fixnum
+ @phone.update_attributes({ :http_user => SecureRandom.hex(PROVISIONING_SET_HTTP_USER) })
+ elsif PROVISIONING_SET_HTTP_USER.class == String
+ @phone.update_attributes({ :http_user => PROVISIONING_SET_HTTP_USER })
+ end
+ end
+
+ if defined?(PROVISIONING_SET_HTTP_PASSWORD) && @phone.http_password.blank?
+ if PROVISIONING_SET_HTTP_PASSWORD.class == Fixnum
+ @phone.update_attributes({ :http_password => SecureRandom.hex(PROVISIONING_SET_HTTP_PASSWORD) })
+ elsif PROVISIONING_SET_HTTP_PASSWORD.class == String
+ @phone.update_attributes({ :http_password => PROVISIONING_SET_HTTP_PASSWORD })
+ end
+ end
+
+ if send_sensitve
+ @phone_settings[:http_user] = @phone.http_user
+ @phone_settings[:http_pass] = @phone.http_password
+ if defined?(PROVISIONING_ADMIN_PASSWORD)
+ if PROVISIONING_ADMIN_PASSWORD.class == TrueClass
+ @phone_settings[:admin_mode_password] = @phone.http_password
+ elsif PROVISIONING_ADMIN_PASSWORD.class == String
+ @phone_settings[:admin_mode_password] = PROVISIONING_ADMIN_PASSWORD
+ end
+ end
+ end
+
+ if ! request.env['HTTP_USER_AGENT'].index('snom')
+ Rails.logger.info "---> User-Agent indicates not a Snom phone (#{request.env['HTTP_USER_AGENT'].inspect})"
+ else
+ Rails.logger.info "---> Phone #{@mac_address.inspect}, IP address #{request.remote_ip.inspect}"
+ @phone.update_attributes({ :ip_address => request.remote_ip })
+ end
+
+ @softkeys = Array.new()
+ @sip_accounts = Array.new()
+
+ if send_sensitve
+ @phone.sip_accounts.each do |sip_account|
+ if (sip_account.sip_accountable_type == @phone.phoneable_type) and (sip_account.sip_accountable_id == @phone.phoneable_id)
+ snom_sip_account = {
+ :id => sip_account.id,
+ :active => 'on',
+ :pname => sip_account.auth_name,
+ :pass => sip_account.password,
+ :host => sip_account.host,
+ :outbound => sip_account.host,
+ :name => sip_account.auth_name,
+ :realname => 'Call',
+ :idle_text => sip_account.caller_name,
+ :mailbox => "<sip:#{sip_account.auth_name}@#{sip_account.host}>"
+ }
+ @sip_accounts.push(snom_sip_account)
+ sip_account_index = @sip_accounts.length
+ sip_account.softkeys.order(:position).each do |softkey|
+ if softkey.softkey_function
+ softkey_function = softkey.softkey_function.name
+ end
+ case softkey_function
+ when 'blf'
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "blf <sip:#{softkey.number}@#{sip_account.host}>|f-ia-"})
+ when 'speed_dial'
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed #{softkey.number}"})
+ when 'dtmf'
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "dtmf #{softkey.number}"})
+ when 'log_out'
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed f-lo"})
+ when 'log_in'
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed f-li-#{softkey.number}"})
+ when 'conference'
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "blf <sip:#{softkey.number}@#{sip_account.host}>|f-ta-"})
+ when 'call_forwarding'
+ @softkeys.push({
+ :context => sip_account_index,
+ :function => softkey.function,
+ :label => softkey.label,
+ :softkey => softkey,
+ :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
+ :subscription => {
+ :to => "f-cftg-#{softkey.call_forward_id}@#{sip_account.host}",
+ :for => "#{sip_account.auth_name}@#{sip_account.host}"
+ },
+ :actions => [{
+ :type => :url,
+ :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?id=#{softkey.call_forward_id}&function=toggle",
+ :when => 'on press',
+ }],
+ })
+ when 'call_forwarding_always'
+ phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first
+ if phone_number
+ account_param = (phone_number.phone_numberable_id != snom_sip_account[:id] ? "&account=#{phone_number.phone_numberable_id}" : '')
+ else
+ phone_number = sip_account.phone_numbers.first
+ account_param = ''
+ end
+
+ @softkeys.push({
+ :context => sip_account_index,
+ :function => softkey.function,
+ :label => softkey.label,
+ :softkey => softkey,
+ :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
+ :subscription => {
+ :to => "f-cfutg-#{phone_number.id}@#{sip_account.host}",
+ :for => "#{sip_account.auth_name}@#{sip_account.host}"
+ },
+ :actions => [{
+ :type => :url,
+ :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?type=always&function=toggle#{account_param}",
+ :when => 'on press',
+ }],
+ })
+ when 'call_forwarding_assistant'
+ phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first
+ if phone_number
+ account_param = (phone_number.phone_numberable_id != snom_sip_account[:id] ? "&account=#{phone_number.phone_numberable_id}" : '')
+ else
+ phone_number = sip_account.phone_numbers.first
+ account_param = ''
+ end
+
+ @softkeys.push({
+ :context => sip_account_index,
+ :function => softkey.function,
+ :label => softkey.label,
+ :softkey => softkey,
+ :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
+ :subscription => {
+ :to => "f-cfatg-#{phone_number.id}@#{sip_account.host}",
+ :for => "#{sip_account.auth_name}@#{sip_account.host}"
+ },
+ :actions => [{
+ :type => :url,
+ :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?type=assistant&function=toggle#{account_param}",
+ :when => 'on press',
+ }],
+ })
+ when 'hunt_group_membership'
+ phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'HuntGroup').first
+ if phone_number
+ hunt_group = HuntGroup.where(:id => phone_number.phone_numberable_id).first
+ end
+
+ sip_account_phone_numbers = Array.new()
+ SipAccount.where(:id => @sip_accounts.first[:id]).first.phone_numbers.each do |phone_number|
+ sip_account_phone_numbers.push(phone_number.number)
+ end
+
+ hunt_group_member_numbers = PhoneNumber.where(:number => sip_account_phone_numbers, :phone_numberable_type => 'HuntGroupMember')
+
+ hunt_group_member = nil
+ if hunt_group and hunt_group_member_numbers
+ hunt_group_member_numbers.each do |hunt_group_member_number|
+ hunt_group_member = hunt_group.hunt_group_members.where(:id => hunt_group_member_number.phone_numberable_id).first
+ if hunt_group_member
+ break
+ end
+ end
+ end
+
+ if hunt_group_member
+ @softkeys.push({
+ :context => sip_account_index,
+ :function => softkey.function,
+ :label => softkey.label,
+ :softkey => softkey,
+ :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
+ :subscription => {
+ :to => "f-hgmtg-#{hunt_group_member.id}@#{sip_account.host}",
+ :for => "#{sip_account.auth_name}@#{sip_account.host}"
+ },
+ :actions => [{
+ :type => :url,
+ :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/hunt_group.xml?group=#{hunt_group.id}&account=#{hunt_group_member.id}&function=toggle",
+ :when => 'on press',
+ }],
+ })
+ else
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => 'none'})
+ end
+ when 'acd_membership'
+ acd_agent = nil
+ phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'AutomaticCallDistributor').first
+ if phone_number
+ acd = AutomaticCallDistributor.where(:id => phone_number.phone_numberable_id).first
+ if acd
+ acd_agent = acd.acd_agents.where(:destination_type => 'SipAccount', :destination_id => sip_account.id).first
+ end
+ end
+
+ if acd_agent
+ @softkeys.push({
+ :context => sip_account_index,
+ :function => softkey.function,
+ :label => softkey.label,
+ :softkey => softkey,
+ :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
+ :subscription => {
+ :to => "f-acdmtg-#{acd_agent.id}@#{sip_account.host}",
+ :for => "#{sip_account.auth_name}@#{sip_account.host}"
+ },
+ :actions => [{
+ :type => :url,
+ :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/acd.xml?acd=#{acd.id}&agent=#{acd_agent.id}&function=toggle",
+ :when => 'on press',
+ }],
+ })
+ else
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => 'none'})
+ end
+ when 'hold'
+ @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "keyevent F_R"})
+ else
+ @softkeys.push({:label => softkey.label, :data => 'none'})
+ end
+ end
+ end
+ end
+ end
+
+ languages_map = {
+ 'ca' => 'Catalan',
+ 'bs' => 'Bosanski',
+ 'da' => 'Dansk',
+ 'de' => 'Deutsch',
+ 'cs' => 'Cestina',
+ 'en' => 'English',
+ 'es' => 'Espanol',
+ 'fi' => 'Suomi',
+ 'et' => 'Estonian',
+ 'fr' => 'Francais',
+ 'he' => 'Hebrew',
+ 'hu' => 'Hungarian',
+ 'it' => 'Italiano',
+ 'nl' => 'Dutch',
+ 'no' => 'Norsk',
+ 'pl' => 'Polski',
+ 'pt' => 'Portugues',
+ 'si' => 'Slovenian',
+ 'sk' => 'Slovencina',
+ 'ru' => 'Russian',
+ 'sv' => 'Svenska',
+ 'tr' => 'Turkce',
+ }
+
+ tone_schemes_map = {
+ '1' => 'USA', # United States
+ '61' => 'AUS', # Australia
+ '43' => 'AUT', # Austria
+ '86' => 'CHN', # China
+ '45' => 'DNK', # Denmark
+ '33' => 'FRA', # France
+ '49' => 'GER', # Germany
+ '44' => 'GBR', # Great Britain
+ '91' => 'IND', # India
+ '39' => 'ITA', # Italy
+ '81' => 'JPN', # Japan
+ '52' => 'MEX', # Mexico
+ '31' => 'NLD', # Netherlands
+ '47' => 'NOR', # Norway
+ '64' => 'NZL', # New Zealand
+ '34' => 'ESP', # Spain
+ '46' => 'SWE', # Sweden
+ '41' => 'SWI', # Switzerland
+ }
+
+ if @phone.phoneable
+ if @phone.phoneable_type == 'Tenant'
+ tenant = @phone.phoneable
+ language = tenant.language.code
+ elsif @phone.phoneable_type == 'User'
+ tenant = @phone.phoneable.current_tenant
+ language = @phone.phoneable.language.code
+ end
+ end
+
+ if tenant && tenant.country
+ tone_scheme = tenant.country.country_code
+ end
+
+ @phone_settings[:tone_scheme] = tone_schemes_map.include?(tone_scheme.to_s) ? tone_schemes_map[tone_scheme.to_s] : 'USA'
+ @phone_settings[:language] = languages_map.include?(language.to_s) ? languages_map[language.to_s] : 'English'
+
+ xml_applications_url = "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{(@sip_accounts.blank? ? '0' : @sip_accounts.first[:id])}"
+ @dkeys = {
+ :menu => 'keyevent F_SETTINGS',
+ :retrieve => 'speed f-vmcheck',
+ :conf => 'keyevent F_CONFERENCE',
+ :redial => "url #{xml_applications_url}/call_history.xml?type=dialed",
+ :directory => "url #{xml_applications_url}/phone_book.xml",
+ :idle_ok => "url #{xml_applications_url}/call_history.xml?type=dialed",
+ :idle_cancel => "keyevent F_CANCEL",
+ :idle_up => "keyevent F_PREV_ID",
+ :idle_down => "keyevent F_NEXT_ID",
+ :idle_left => "url #{xml_applications_url}/call_history.xml?type=received",
+ :idle_right => "url #{xml_applications_url}/call_history.xml?type=missed",
+ }
+
+ # Remap conference key to first conference if found
+ #conference = Conference.where(:conferenceable_type => @phone.phoneable_type, :conferenceable_id => @phone.phoneable_id).first
+ #if conference and conference.phone_numbers
+ # @dkeys[:conf] = "speed f_ta_#{conference.phone_numbers.first.number}"
+ #end
+
+ @sip_accounts.length().upto(MAX_SIP_ACCOUNTS_COUNT) do |index|
+ snom_sip_account = {
+ :id => index,
+ :active => 'off',
+ :pname => '',
+ :pass => '',
+ :host => '',
+ :outbound => '',
+ :name => '',
+ :realname => '',
+ :idle_text => '',
+ }
+ @sip_accounts.push(snom_sip_account)
+ end
+
+ @softkeys.length().upto(MAX_SOFTKEYS_COUNT) do |index|
+ @softkeys.push({:label => "", :data => "none"})
+ end
+
+ @state_settings_url = "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/state_settings.xml"
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render
+ }
+ }
+ end
+
+ def idle_screen
+
+ snom_360_bg = 'Qk0+BAAAAAAAAD4AAAAoAAAAgAAAAEAAAAABAAEAAAAAAAAEAAATCwAAEwsAAAIAAAACAAAA////
+AAAAAAAAAAAAAAAAAAAAAbbZxzbbAAAAAAAAAAAAAAG222222wAAAAAAAAAAAAAB9ttttt8AAAAA
+AAAAAAAAAbbbbbbbAAAAAAAAAAAAAAG222222wAAAAAAAAAAAAABttttttsAAAAAAAAAAAAAAOPx
+xx+OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkkkkkkkkkkkkkkAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAACSSSSSSSSSSSSSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAA'
+
+ @phone_xml_object = {
+ :image => {
+ :data => snom_360_bg,
+ :location_x => 0,
+ :location_y => 0,
+ :invert => 0
+ },
+ :clock => {
+ :location_x => 128,
+ :location_y => 0,
+ },
+ :date => {
+ :location_x => 100,
+ :location_y => 40,
+ },
+ :line => {
+ :location_x => 0,
+ :location_y => 0,
+ },
+ }
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render
+ }
+ }
+ end
+
+ def log_in
+
+ base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}"
+ exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml"
+
+ log_in_number = params[:log_in].to_s.gsub(/[^0-9]/,'')
+ pin = params[:pin].to_s.gsub(/[^0-9]/,'')
+
+ if ! params[:user].blank?
+ user = User.where(:id => params[:user].to_i).first
+ phone_number = PhoneNumber.where(:number => log_in_number, :phone_numberable_type => 'SipAccount').first
+ if phone_number
+ sip_account = phone_number.phone_numberable
+ end
+ elsif ! params[:log_in].blank?
+ phone_number = PhoneNumber.where(:number => log_in_number, :phone_numberable_type => 'SipAccount').first
+ if phone_number && phone_number.phone_numberable && phone_number.phone_numberable.sip_accountable && phone_number.phone_numberable.sip_accountable_type == 'User'
+ user = phone_number.phone_numberable.sip_accountable
+ end
+ end
+
+ @phone_xml_object = {
+ :name => "snom_phone_text",
+ :title => "Error",
+ :prompt => "Log in",
+ :text => 'Log in failed!',
+ :fetch_url => base_url,
+ :fetch_mil => '2000',
+ }
+
+ if ! user
+ @phone_xml_object = {
+ :name => "snom_phone_input",
+ :title => "Log In",
+ :prompt => "Log In",
+ :url => base_url,
+ :display_name => "Log In",
+ :query_string_param => "log_in",
+ :default_value => log_in_number,
+ :input_flags => "n",
+ :softkeys => [
+ {:name => "F1", :label => "Exit", :url => exit_url}
+ ]
+ }
+ elsif pin.blank?
+ @phone_xml_object = {
+ :name => "snom_phone_input",
+ :title => "PIN",
+ :prompt => "PIN",
+ :url => base_url,
+ :display_name => "PIN",
+ :query_string_param => "user=#{user.id}&log_in=#{log_in_number}&pin",
+ :default_value => "",
+ :input_flags => "pn",
+ :softkeys => [
+ {:name => "F1", :label => "Exit", :url => exit_url}
+ ]
+ }
+ elsif user.authenticate_by_pin?(pin)
+ if @phone.user_login(user, sip_account)
+ @phone_xml_object = {
+ :name => "snom_phone_text",
+ :title => "Log in successful",
+ :prompt => "Log in",
+ :text => "#{user.to_s} logged in",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ end
+ end
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render :action => "_#{@phone_xml_object[:name]}"
+ }
+ }
+ end
+
+ def log_out
+ if ! @phone
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- Phone not found -->",
+ )
+ return
+ end
+
+ exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml"
+
+ if @phone.user_logout()
+ @phone_xml_object = {
+ :name => "snom_phone_text",
+ :title => "Log out successful",
+ :prompt => "Log out",
+ :text => 'Log out successful',
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ else
+ @phone_xml_object = {
+ :name => "snom_phone_text",
+ :title => "Error",
+ :prompt => "Log out",
+ :text => 'Log out failed!',
+ :fetch_url => exit_url,
+ :fetch_mil => '2000',
+ }
+ end
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render :action => "_#{@phone_xml_object[:name]}"
+ }
+ }
+ end
+
+ def phone_book
+
+ if ! @sip_account
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- SipAccount not found -->",
+ )
+ return
+ end
+
+ @phone_xml_object = {
+ :name => 'snom_phone_directory',
+ :title => "$(lang:menu100_phone_book) #{@dialpad_keys}".strip,
+ :entries => [],
+ :softkeys => [],
+ }
+
+ phone_books = Array.new()
+ phone_books = phone_books + @sip_account.sip_accountable.try(:phone_books).all
+ if @sip_account.sip_accountable.class == User
+ phone_books = phone_books + @sip_account.sip_accountable.try(:current_tenant).try(:phone_books).all
+ end
+
+ phone_book_ids = Array.new()
+ phone_books.each do |phone_book|
+ phone_book_ids << phone_book.id
+ end
+
+ PhoneBookEntry.where(:phone_book_id => phone_book_ids).order(:last_name).order(:first_name).limit(MAX_DIRECTORY_ENTRIES).each do |phone_book_entry|
+ if phone_book_entry.phone_numbers.count > 1
+ @phone_xml_object[:entries] << { :text => phone_book_entry.to_s, :number => phone_book_entry.phone_numbers.first }
+ end
+ phone_book_entry.phone_numbers.each do |phone_number|
+ if phone_book_entry.phone_numbers.count > 1
+ entry_name = " #{phone_number.name} #{phone_number.number}"
+ else
+ entry_name = "#{phone_book_entry.to_s} #{phone_number.number}"
+ end
+
+ @phone_xml_object[:entries] << { :text => entry_name, :number => phone_number.number }
+ end
+ end
+
+ base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}"
+ phone_book_url = "#{base_url}?type=#{@type.to_s}"
+ for key_id in (0..9)
+ @phone_xml_object[:softkeys] << {:name => key_id, :url => "#{phone_book_url}&keys=#{@dialpad_keys.to_s}#{key_id}" }
+ end
+ @phone_xml_object[:softkeys] << {:name => '*', :url => "#{phone_book_url}&keys=#{@dialpad_keys.to_s[0..-2]}" }
+ @phone_xml_object[:softkeys] << {:name => '#', :url => "#{phone_book_url}&keys=" }
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render :action => "_#{@phone_xml_object[:name]}"
+ }
+ }
+
+ end
+
+ def call_history
+
+ if ! @sip_account
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- SipAccount not found -->",
+ )
+ return
+ end
+
+ if ['dialed', 'missed', 'received'].include? @type
+ @phone_xml_object = {
+ :name => "snom_phone_directory",
+ :title => "$(lang:menu100_call_lists) - #{@type.to_s.camelize}",
+ :entries => []
+ }
+
+ if @type == 'missed'
+ hunt_group_member_ids = PhoneNumber.where(:phone_numberable_type => 'HuntGroupMember', :number => @sip_account.phone_numbers.map {|a| a.number}).map {|a| a.phone_numberable_id}
+ hunt_group_ids = HuntGroupMember.where(:id => hunt_group_member_ids, :active => true).map {|a| a.hunt_group_id}
+ calls = CallHistory.where('entry_type = ? AND ((call_historyable_type = "SipAccount" AND call_historyable_id = ?) OR (call_historyable_type = "HuntGroup" AND call_historyable_id IN (?)))', @type, @sip_account.id, hunt_group_ids).order('start_stamp DESC').limit(MAX_DIRECTORY_ENTRIES)
+ else
+ calls = @sip_account.call_histories.where(:entry_type => @type).order('start_stamp DESC').limit(MAX_DIRECTORY_ENTRIES)
+ end
+
+ calls.each do |call|
+ display_name = call.display_name
+ phone_number = call.display_number
+ phone_book_entry = call.phone_book_entry_by_number(phone_number)
+ if display_name.blank?
+ display_name = phone_book_entry.to_s
+ end
+
+ @phone_xml_object[:entries].push({
+ :selected => false,
+ :number => phone_number,
+ :text => "#{call_date_compact(call.start_stamp)} #{display_name} #{call.display_number}",
+ })
+ end
+ else
+ base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}"
+ @phone_xml_object = {
+ :name => 'snom_phone_menu',
+ :title => '$(lang:menu100_call_lists)',
+ :entries => [
+ {:text => '$(lang:list_missed)', :url => "#{base_url}?&type=missed", :selected => false},
+ {:text => '$(lang:list_taken)', :url => "#{base_url}?&type=received", :selected => false},
+ {:text => '$(lang:list_dialed)', :url => "#{base_url}?&type=dialed", :selected => false},
+ ]
+ }
+ end
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render :action => "_#{@phone_xml_object[:name]}"
+ }
+ }
+
+ end
+
+ def state_settings
+ @base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}"
+
+ @sip_account_ids = Array.new()
+ @phone.sip_accounts.each do |sip_account|
+ if (sip_account.sip_accountable_type == @phone.phoneable_type) and (sip_account.sip_accountable_id == @phone.phoneable_id)
+ @sip_account_ids.push(sip_account.id)
+ end
+ end
+
+ if @phone.hot_deskable
+ @enable_login = true
+ if @phone.phoneable_type != 'Tenant'
+ @enable_logout = true
+ end
+ end
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render
+ }
+ }
+ end
+
+ def call_forwarding
+ if ! params[:type].blank?
+ @type = params[:type]
+ end
+
+ if ! params[:function].blank?
+ @function = params[:function]
+ end
+
+ if ! params[:id].blank?
+ @call_forwarding_id = params[:id].to_i
+ end
+
+ if ! params[:sip_account].blank?
+ @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first
+ end
+
+ if ! params[:account].blank?
+ @sip_account = SipAccount.where({ :id => params[:account].to_i }).first
+ end
+
+
+ if ! @sip_account
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- SipAccount not found -->",
+ )
+ return
+ end
+
+ exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml"
+
+ if @function == 'toggle'
+ if @call_forwarding_id
+ call_forwarding = @sip_account.call_forwards.where(:id => @call_forwarding_id).first
+
+ if !call_forwarding and @sip_account.softkeys.where(:call_forward_id => @call_forwarding_id).count > 0
+ call_forwarding = CallForward.where(:id => @call_forwarding_id).first
+ end
+
+ if call_forwarding
+ call_forwarding.toggle
+ end
+ elsif @type
+ call_forwarding = @sip_account.call_forwarding_toggle(@type)
+ end
+ if !call_forwarding
+ render(
+ :status => 500,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- Call forwarding not set: #{@sip_account.errors.messages.inspect} -->",
+ )
+ return
+ end
+
+ if !call_forwarding.errors.blank?
+ error_messages = Array.new()
+ call_forwarding.errors.messages.each_pair do |key, message|
+ error_messages.push(message.join(';'))
+ end
+ @phone_xml_object = {
+ :name => 'snom_phone_text',
+ :title => t("call_forwards.name"),
+ :prompt => t("call_forwards.name"),
+ :text => "ERROR #{error_messages.join(',')} #{call_forwarding.to_s})",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ elsif call_forwarding.active
+ @phone_xml_object = {
+ :name => 'snom_phone_text',
+ :title => t("call_forwards.name"),
+ :prompt => t("call_forwards.name"),
+ :text => "ON #{call_forwarding.to_s})",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ else
+ @phone_xml_object = {
+ :name => 'snom_phone_text',
+ :title => t("call_forwards.name"),
+ :prompt => t("call_forwards.name"),
+ :text => "OFF #{call_forwarding.to_s}",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ end
+ end
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render :action => "_#{@phone_xml_object[:name]}"
+ }
+ }
+ end
+
+ def hunt_group
+ if ! params[:function].blank?
+ @function = params[:function]
+ end
+
+ if ! params[:sip_account].blank?
+ @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first
+ end
+
+ if ! params[:group].blank?
+ @hunt_group = HuntGroup.where({ :id => params[:group].to_i }).first
+ end
+
+ if ! @sip_account
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- SipAccount not found -->",
+ )
+ return
+ end
+
+ if ! @hunt_group
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- HuntGroup not found -->",
+ )
+ return
+ end
+
+ if ! params[:account].blank?
+ hunt_group_member = @hunt_group.hunt_group_members.where({ :id => params[:account].to_i }).first
+ end
+
+ if ! hunt_group_member
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- HuntGroupMember not found -->",
+ )
+ return
+ end
+
+ exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml"
+
+ if @function == 'toggle'
+ if hunt_group_member.can_switch_status_itself == true
+ if hunt_group_member.active
+ hunt_group_member.active = false
+ else
+ hunt_group_member.active = true
+ end
+
+ if ! hunt_group_member.save
+ render(
+ :status => 500,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- #{hunt_group_member.errors.inspect} -->",
+ )
+ return
+ end
+ end
+
+ if hunt_group_member.active
+ @phone_xml_object = {
+ :name => 'snom_phone_text',
+ :title => 'Hunt Group',
+ :prompt => 'Hunt Group',
+ :text => "#{@hunt_group.name} on",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ else
+ @phone_xml_object = {
+ :name => 'snom_phone_text',
+ :title => 'Hunt Group',
+ :prompt => 'Hunt Group',
+ :text => "#{@hunt_group.name} off",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ end
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render :action => "_#{@phone_xml_object[:name]}"
+ }
+ }
+ end
+ end
+
+ def acd
+ if ! params[:function].blank?
+ @function = params[:function]
+ end
+
+ if ! params[:sip_account].blank?
+ @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first
+ end
+
+ if ! params[:acd].blank?
+ @acd = AutomaticCallDistributor.where({ :id => params[:acd].to_i }).first
+ end
+
+ if ! @sip_account
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- SipAccount not found -->",
+ )
+ return
+ end
+
+ if ! @acd
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- AutomaticCallDistributor not found -->",
+ )
+ return
+ end
+
+ if ! params[:agent].blank?
+ acd_agent = @acd.acd_agents.where({ :id => params[:agent].to_i }).first
+ end
+
+ if ! acd_agent
+ render(
+ :status => 404,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- ACD Agent not found -->",
+ )
+ return
+ end
+
+ exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml"
+
+ if @function == 'toggle'
+ if acd_agent.status == 'active'
+ acd_agent.status = 'inactive'
+ else
+ acd_agent.status = 'active'
+ end
+
+ if ! acd_agent.save
+ render(
+ :status => 500,
+ :layout => false,
+ :content_type => 'text/plain',
+ :text => "<!-- #{acd_agent.errors.inspect} -->",
+ )
+ return
+ end
+
+ if acd_agent.status == 'active'
+ @phone_xml_object = {
+ :name => 'snom_phone_text',
+ :title => 'ACD',
+ :prompt => 'ACD',
+ :text => "#{@acd.name} on",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ else
+ @phone_xml_object = {
+ :name => 'snom_phone_text',
+ :title => 'ACD',
+ :prompt => 'ACD',
+ :text => "#{@acd.name} off",
+ :fetch_url => exit_url,
+ :fetch_mil => '1000',
+ }
+ end
+
+ respond_to { |format|
+ format.any {
+ self.formats = [ :xml ]
+ render :action => "_#{@phone_xml_object[:name]}"
+ }
+ }
+ end
+ end
+
+ def exit
+ render(
+ :status => 200,
+ :layout => false,
+ :content_type => 'text/xml',
+ :text => "<exit />",
+ )
+ end
+
+ def call_date_compact(date)
+ if date.strftime('%Y%m%d') == DateTime::now.strftime('%Y%m%d')
+ return date.strftime('%H:%M')
+ end
+ return date.strftime('%d.%m %H:%M')
+ end
+
+end