class Apiotics::Hardware

Public Class Methods

add_wifi_details(uniflash_path, config, wifi_path) click to toggle source
# File lib/apiotics/hardware.rb, line 239
def self.add_wifi_details(uniflash_path, config, wifi_path)
  pwd = ApioticsSetting.find_by(key: "wifi_key").value

  encrypted = File.read(wifi_path)

  decrypted = encrypted.apiotics_decrypt(pwd)
  
  target_path = "wifi_settings.json"
  path = Rails.root.join('lib', 'uniflash', 'downloads', 'wifi_settings.json')
  File.write(path, decrypted)
  string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project add_file --name #{config["firmware_file_name"].split(".")[0]} --file #{path} --fs_path #{target_path} --overwrite --flags publicread"
  msg = system(string)
  File.delete(path)
end
bits() click to toggle source
# File lib/apiotics/hardware.rb, line 7
def self.bits
  OS.bits
end
brand_and_burn_sd_image(download_directory, image_path, wifi_settings, cellular, config_file_path, config) click to toggle source
# File lib/apiotics/hardware.rb, line 405
def self.brand_and_burn_sd_image(download_directory, image_path, wifi_settings, cellular, config_file_path, config)
  status = false
  Dir.chdir download_directory
  script_path = nil
  if Hardware.mac == true
    script_path = "#{download_directory}/brand_and_burn.mac.sh"
  elsif Hardware.linux == true
    script_path = "#{download_directory}/brand_and_burn.sh"
  end
  if script_path != nil
    #puts "Please wait..."
    puts "Running sudo -S #{script_path} brand_and_burn #{config["user"]} #{image_path} no_disk #{wifi_settings["ssid"]} #{wifi_settings["password"]} #{wifi_settings["security_mode"]} #{config_file_path} 0 #{cellular.to_s} dhcp"
    puts "Please enter your password so that the image may be written to your SD card."
    IO.popen("sudo -S #{script_path} brand_and_burn #{config["user"]} #{image_path} no_disk #{wifi_settings["ssid"]} #{wifi_settings["password"]} #{wifi_settings["security_mode"]} #{config_file_path} 0 #{cellular.to_s} dhcp") do |io|
      while (line = io.gets) do
        puts line
      end
    end
    status = true
  else
    puts "Unrecognized operating system, exiting."
  end
  status
end
brand_uniflash_image(uniflash_path, config) click to toggle source
# File lib/apiotics/hardware.rb, line 220
def self.brand_uniflash_image(uniflash_path, config)
  puts "Adding Hive and Worker Type details to the firmware image...\n"
  details_hash = {
    "hive_public_key" => config["hive_public_key"],
    "hive_private_key" => config["hive_private_key"],
    "worker_type" => config["worker_type"]
  }
  path = Rails.root.join('lib', 'uniflash', 'downloads', 'branding.json')
  File.write(path, details_hash.to_json)
  target_path = "branding.json"
  string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project add_file --name #{config["firmware_file_name"].split(".")[0]} --file #{path} --fs_path #{target_path} --overwrite --flags publicread"
  msg = system(string)
  File.delete(path)
  wifi_path = Rails.root.join('lib', 'uniflash', 'downloads', 'wifi_settings')
  if File.exist?(wifi_path)
    Hardware.add_wifi_details(uniflash_path, config, wifi_path)
  end
end
cellular(state) click to toggle source
# File lib/apiotics/hardware.rb, line 254
def self.cellular(state)
  current_state = ApioticsSetting.find_by(key: "cellular")
  if current_state == nil
    current_state = ApioticsSetting.new
    current_state.key = "cellular"
  end
  if state == "on"
    state = 1
  else
    state = 0
  end
  
  current_state.value = state
  current_state.save
end
check_linux_uniflash_install() click to toggle source
# File lib/apiotics/hardware.rb, line 139
def self.check_linux_uniflash_install #need a Linux installation to check where UniFlash installs itself
  status = false
  puts "Checking for Uniflash installation...\n"
  path = "#{Dir.home}/ti/uniflash_4.3.0/dslite.sh"
  if File.exist?(path)
    puts "Uniflash installation found.\n"
    status = true
  else
    puts "No Uniflash installation found.\n"
  end
  return status
end
check_mac_uniflash_install() click to toggle source
# File lib/apiotics/hardware.rb, line 126
def self.check_mac_uniflash_install
  status = false
  puts "Checking for Uniflash installation...\n"
  path = "/Applications/ti/uniflash_4.3.0/dslite.sh"
  if File.exist?(path)
    puts "Uniflash installation found.\n"
    status = true
  else
    puts "No Uniflash installation found.\n"
  end
  return status
end
check_sd_card_scripts() click to toggle source
# File lib/apiotics/hardware.rb, line 313
def self.check_sd_card_scripts
  status = nil
  download_directory = Rails.root.join('lib', 'sd_card')
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
  download_directory = Rails.root.join('lib', 'sd_card', 'downloads')
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
  Dir.chdir download_directory
  system = nil
  if Hardware.mac == true
    system = "mac"
  elsif Hardware.linux == true
    system = "linux"
  end
  downloaded = false
  unless system == nil
    if system == "mac"
      if File.exist?("#{download_directory}/brand_and_burn.mac.sh")
        downloaded = true
      end
    elsif system == "linux"
      if File.exist?("#{download_directory}/brand_and_burn.sh")
        downloaded = true
      end
    end
    if downloaded == false
      scripts = Apiotics::Portal.sd_scripts(system)
      file = File.open("#{download_directory}/sd_scripts.tgz", 'wb')
      file.write(scripts)
      file.close
      `tar xvzf #{download_directory}/sd_scripts.tgz -C #{download_directory}`
      `rm #{download_directory}/sd_scripts.tgz`
    end
    if system == "mac"
      if File.exist?("#{download_directory}/brand_and_burn.mac.sh")
        status = download_directory
      end
    elsif system == "linux"
      if File.exist?("#{download_directory}/brand_and_burn.sh")
        status = download_directory
      end
    end
  end
  return status
end
check_uniflash_install() click to toggle source
# File lib/apiotics/hardware.rb, line 152
def self.check_uniflash_install
  status = false
  if Hardware.mac == true
    if Hardware.check_mac_uniflash_install == true
      status = "/Applications/ti/uniflash_4.3.0/dslite.sh"
    end
  elsif Hardware.linux == true
    if Hardware.check_linux_uniflash_install == true
      status = "#{Dir.home}/ti/uniflash_4.3.0/dslite.sh"
    end
  else
    puts "Your computer is not running a supported OS.  Please use either Mac OS or Linux to install your firmware.\n"
  end
  return status
end
create_uniflash_image(uniflash_path, config) click to toggle source
# File lib/apiotics/hardware.rb, line 214
def self.create_uniflash_image(uniflash_path, config)
  puts "Creating uniflash firmware image...\n"
  string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project create_image --name #{config['firmware_file_name'].split(".")[0]} --sli_file #{config['firmware_file_name'].split(".")[0]}.sli"
  msg = system(string)
end
edit_json_config_mac_address(mac_address, config) click to toggle source
# File lib/apiotics/hardware.rb, line 194
def self.edit_json_config_mac_address(mac_address, config)
  status = false
  puts "Editing device configuration to assign device MAC address..."
  path = "#{Dir.home}/.SLImageCreator/projects/#{config['firmware_file_name'].split(".")[0]}/#{config['firmware_file_name'].split(".")[0]}.json"
  if File.exist?(path)
    puts "json configuration file found...\n"
    file = File.read(path)
    puts "updating MAC address...\n"
    json_config = JSON.parse(file)
    json_config["header"]["DEV_MAC_ADDR"] = mac_address
    json_config["systemFiles"]["CONFIG_TYPE_MAC"]["MAC_ADDR"] = mac_address
    puts "writing updated json configuration file...\n"
    File.write(path, json_config.to_json)
    status = true
  else
    puts "Error: json configuration file could not be found at #{path}\n"
  end
  return status
end
fetch_wifi() click to toggle source
# File lib/apiotics/hardware.rb, line 538
def self.fetch_wifi
  return_hash = nil
  download_directory = Rails.root.join('lib', 'wifi')
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
  Dir.chdir download_directory
  path = Rails.root.join('lib', 'wifi', 'wifi_settings')
  if File.exist?(path)
    pwd = ApioticsSetting.find_by(key: "wifi_key")
    if pwd != nil
      pwd = pwd.value
      encrypted_settings = File.read(path)
      return_hash = encrypted_settings.apiotics_decrypt(pwd)
    end
    return_hash = JSON.parse(return_hash)
  end
  return_hash
end
find_uniflash_mac_address(uniflash_path, config) click to toggle source
# File lib/apiotics/hardware.rb, line 178
def self.find_uniflash_mac_address(uniflash_path, config)
  mac_addr = nil
  string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} device info"
  puts "Finding device MAC address... \n"
  msg = `#{string}`
  mac_addr_start = msg.rindex("MAC          : ")
  if mac_addr_start != nil
    mac_addr_start = mac_addr_start + 15
    mac_addr_end = msg.rindex("PROG MAC") - 1
    mac_addr = msg[mac_addr_start..mac_addr_end].chomp
  else
    puts "Could not read MAC address.  Please press the reset button on your board and try running rake firmware:install again.\n"
  end
  return mac_addr
end
get_sd_image(download_directory, worker_name, config) click to toggle source
# File lib/apiotics/hardware.rb, line 358
def self.get_sd_image(download_directory, worker_name, config)
  Dir.chdir download_directory
  worker_directory = download_directory.to_s + "/#{worker_name.downcase}"
  Dir.mkdir worker_directory unless Dir.exist?(worker_directory)
  image_name = "#{worker_name.downcase}-#{config['device_name'].underscore}-#{config['device_version']}"
  image_name = image_name.gsub(" ", "_")
  image_path = "#{worker_directory}/#{image_name}.img.gz"
  unless File.exist?(image_path)
    `rm #{worker_directory}/*`
    Apiotics::Portal.get_sd_image(worker_directory, worker_name, image_name)
    #zip_path = "#{download_directory}/#{worker_name}.img.gz"
    #`gunzip -c #{zip_path} > #{image_path}`
    #`rm #{zip_path}`
  end
  return image_path
end
import_uniflash_image(uniflash_path, path, config) click to toggle source
# File lib/apiotics/hardware.rb, line 168
def self.import_uniflash_image(uniflash_path, path, config)
  project_path = "#{Dir.home}/.SLImageCreator/projects/#{config['firmware_file_name'].split(".")[0]}"
  if Dir.exist?(project_path)
    FileUtils.remove_dir(project_path)
  end
  string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project import --file #{path}"
  puts "Creating uniflash project... \n"
  msg = system(string)
end
install(worker_name, name) click to toggle source
# File lib/apiotics/hardware.rb, line 488
def self.install(worker_name, name)
  if ActiveRecord::Base.connection.table_exists? 'apiotics_settings'
    config = Apiotics::Portal.openocd_worker_config(worker_name)
    config = JSON.parse(config)
    if config["installer"] == "Open OCD 0.10"
      Hardware.openocd(worker_name, name, config)
    elsif config["installer"] == "Uniflash 4.3.0"
      Hardware.uniflash(worker_name, name, config)
    elsif config["installer"] == "SD Card"
      Hardware.sd_card(worker_name, name, config)
    else
      puts "Unknown installer for #{worker_name}.  Please check the installer settings for the #{worker_name} device on the Apiotics portal.\n"
    end
  else
    puts "Please run rails g apiotics:install before running this command."
  end
end
linux() click to toggle source
# File lib/apiotics/hardware.rb, line 11
def self.linux
  OS.linux?
end
mac() click to toggle source
# File lib/apiotics/hardware.rb, line 15
def self.mac
  OS.mac?
end
openocd(worker_name, name, config) click to toggle source
# File lib/apiotics/hardware.rb, line 78
def self.openocd(worker_name, name, config)
  msg = ""
  download_directory = Rails.root.join('lib', 'openocd')
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
  download_directory = Rails.root.join('lib', 'openocd', 'downloads')
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
  Dir.chdir download_directory
  unless config["openocd_config_file_name"] == nil || config["openocd_config_file_name"] == ""
    path = Rails.root.join('lib', 'openocd', 'downloads', config["firmware_file_name"])
    if File.exist?(path)
      puts "Device firmware already cached at #{path}. Using cached version. To download a new copy of the device firmware, delete the file at #{path}.\n"
    else
      puts "Downloading device firmware...\n"
      firmware_data = Apiotics::Portal.download_firmware(worker_name)
      file = File.new(path, 'w')
      file.write firmware_data["file"].force_encoding(Encoding::UTF_8)
      file.close
    end
    clean_string = "1" * 68 * 8
    clean = Array.new
    clean[0] = clean_string
    clean_bits = clean.pack("B*")
    if name != nil
      if name.length > 64
        name = name[0..63]
      end
      data = File.open(path, 'r+')
      version_offset = 2048
      offset = version_offset + 4 + 68 + 68 + 68
      IO.write(data, clean_bits.force_encoding(Encoding::UTF_8), offset)
      name = name + "\0"
      IO.write(data, name, offset)
      data.close
    else
      data = File.open(path, 'r+')
      version_offset = 2048
      offset = version_offset + 4 + 68 + 68 + 68
      IO.write(data, clean_bits.force_encoding(Encoding::UTF_8), offset)
      data.close
    end
    msg = self.openocd_install_firmware(config["openocd_config_file_name"], path, config["openocd_start_address"])
  else
    k = Apiotics.configuration.targets.keys
    puts "Worker could not be found.  The workers associated with your Hive are: #{k.join(',')}"
  end
  return msg
end
openocd_install_firmware(config_script, firmware_path, starting_address) click to toggle source
# File lib/apiotics/hardware.rb, line 63
def self.openocd_install_firmware(config_script, firmware_path, starting_address)
  directory = Rails.root.join('lib', 'openocd', 'gnuarmeclipse')
  unless Dir.exist?(directory)
    self.save_openocd
    self.unpack_openocd
  end
  directory = Rails.root.join('lib', 'openocd', 'gnuarmeclipse', 'openocd')
  Dir.chdir directory
  version_folder = Dir['*/'].first[0..-2]
  directory = Rails.root.join('lib', 'openocd', 'gnuarmeclipse', 'openocd', version_folder)
  Dir.chdir directory
  string = "bin/openocd -f \"scripts/board/" + config_script + "\"" + " -c \"program " + firmware_path.to_s + " exit " + starting_address.to_s + "\""
  msg = system(string)
end
save_openocd() click to toggle source
# File lib/apiotics/hardware.rb, line 19
def self.save_openocd
  os = nil
  if self.linux == true 
    if self.bits == 64
      os = "debian64"
    elsif self.bits == 32
      os = "debian32"
    end
  elsif self.mac == true
    os = "mac"
  end
  if os == "debian64" || os == "debian32"
    group = Etc.getgrnam('plugdev')
    login = Etc.getlogin
    info = Etc.getpwnam(login)
    username = info.gecos.split(/,/).first
    unless group.mem.include?(username)
      puts "Please enter your password: \n"
      password = system "stty -echo"
      `usermod -a -G plugdev #{username} -p #{password}`
      `exec $SHELL`
    end
  end
  unless os == nil
    data = Apiotics::Portal.openocd(os)
    directory = Rails.root.join('lib', 'openocd')
    Dir.mkdir directory unless Dir.exist?(directory)
    path = Rails.root.join('lib', 'openocd', 'openocd.tgz')
    file = File.new(path, 'w')
    file.write data.force_encoding(Encoding::UTF_8)
    file.close
  end
end
sd_card(worker_name, name, config) click to toggle source

def self.burn_sd_image(download_directory, image_path)

Dir.chdir download_directory
img_path = image_path.chomp(".img.gz") + "_branded.img.gz"
puts "Burning #{image_path}..."
if Hardware.mac == true
  execute_path = download_directory.to_s + "/burn_image_to_disk.mac.sh"
elsif Hardware.linux == true
  execute_path = download_directory.to_s + "/burn_image_to_disk.sh"
else
  execute_path = nil
end
if execute_path == nil
  puts "This computer is not running a recognized OS.  Exiting."
else
  puts "Running sudo #{execute_path} #{image_path}"
  #pwd = STDIN.getpass("Password:")
  IO.popen("sudo -S #{execute_path} #{img_path}") do |io|
    while (line = io.gets) do
      puts line
    end
  end
end

end

# File lib/apiotics/hardware.rb, line 454
def self.sd_card(worker_name, name, config)
  #puts "Grab a coffee, this may take a few minutes..."
  download_directory = Apiotics::Hardware.check_sd_card_scripts
  if download_directory != nil
    image_path = Apiotics::Hardware.get_sd_image(download_directory, worker_name, config)
    image_size = Apiotics::Portal.get_image_size(worker_name)
    if File.size(image_path) == image_size.to_i
      wifi_settings = Apiotics::Hardware.fetch_wifi
      if wifi_settings == nil
        puts "No wifi settings detected.  To configure wifi run rake firmware:wifi."
        wifi_settings = {
          "ssid" => "NONE",
          "password" => "NONE",
          "security_mode" => "NONE"
        }
      end     
      config_file_path = Apiotics::Hardware.sd_config_file(worker_name, name, download_directory)
      cellular = ApioticsSetting.find_by(key: "cellular")
      if cellular == nil
        cellular = 0
      else
        cellular = cellular.value
      end  
      Apiotics::Hardware.brand_and_burn_sd_image(download_directory, image_path, wifi_settings, cellular, config_file_path, config)
    else
      puts "Error in download, file downloaded does not match file size on server.  Please try running this command again."
      File.delete(image_path)
    end
  else
    puts "SD card installation scripts not available. Exiting."
  end
    
end
sd_config_file(worker_name, name, download_directory) click to toggle source
# File lib/apiotics/hardware.rb, line 375
def self.sd_config_file(worker_name, name, download_directory)
  worker_directory = download_directory.to_s + "/#{worker_name.downcase}"
  Dir.mkdir worker_directory unless Dir.exist?(worker_directory)
  config_file_path = "#{worker_directory}/#{worker_name.downcase}.json"
  if File.exist?(config_file_path)
    config = File.read(config_file_path)
    config = JSON.parse(config)
  else
    config = {}
  end
  config["port"] = "8883"
  config["download"] = true
  config["public_key"] = Apiotics.configuration.public_key
  config["private_key"] = Apiotics.configuration.private_key
  if name == nil || name == ""
    config["name"] = ""
  else
    config["name"] = name.to_s
  end
  config["worker_type"] = worker_name
  config["portal"] = Apiotics.configuration.portal
  config["message_validation"] = false
  config["local_server"] = "localhost"
  config["local_port"] = "8001"
  config["containers"] = false
  config["driver_logging"] = true
  File.write(config_file_path, config.to_json)
  config_file_path
end
uniflash(worker_name, name, config) click to toggle source
# File lib/apiotics/hardware.rb, line 276
def self.uniflash(worker_name, name, config)
  uniflash_path = Hardware.check_uniflash_install
  if uniflash_path != false 
    download_directory = Rails.root.join('lib', 'uniflash')
    Dir.mkdir download_directory unless Dir.exist?(download_directory)
    download_directory = Rails.root.join('lib', 'uniflash', 'downloads')
    Dir.mkdir download_directory unless Dir.exist?(download_directory)
    Dir.chdir download_directory
    unless config["openocd_config_file_name"] == nil || config["openocd_config_file_name"] == ""
      path = Rails.root.join('lib', 'uniflash', 'downloads', config["firmware_file_name"])
      if File.exist?(path)
        puts "Device firmware already cached at #{path}. Using cached version. To download a new copy of the device firmware, delete the file at #{path}.\n"
      else
        puts "Downloading device firmware...\n"
        firmware_data = Apiotics::Portal.download_firmware(worker_name)
        file = File.new(path, 'w')
        file.write firmware_data["file"].force_encoding(Encoding::UTF_8)
        file.close
      end
      Hardware.import_uniflash_image(uniflash_path, path, config)
      mac_address = Hardware.find_uniflash_mac_address(uniflash_path, config)
      unless mac_address == nil
        if Hardware.edit_json_config_mac_address(mac_address, config)
          Hardware.brand_uniflash_image(uniflash_path, config)
          Hardware.create_uniflash_image(uniflash_path, config)
          Hardware.write_uniflash_image(uniflash_path, config)
        end
      end
    else
      k = Apiotics.configuration.targets.keys
      puts "Worker could not be found.  The workers associated with your Hive are: #{k.join(',')}"
    end
  else
    puts "Could not find Uniflash 4.3.0.  If you need to install it, please visit http://processors.wiki.ti.com/index.php/Category:CCS_UniFlash and install version 4.3.0.\n"
  end
end
unpack_openocd() click to toggle source
# File lib/apiotics/hardware.rb, line 53
def self.unpack_openocd
  directory = Rails.root.join('lib', 'openocd')
  Dir.chdir directory
  path = Rails.root.join('lib', 'openocd', 'openocd.tgz')
  msg = system("tar -xvzf #{path}")
  if msg == true
    File.delete(path) if File.exist?(path)
  end
end
wifi(ssid, password, security_mode) click to toggle source
# File lib/apiotics/hardware.rb, line 506
def self.wifi(ssid, password, security_mode)
  args = {
    "ssid" => ssid,
    "password" => password,
    "security_mode" => security_mode
  }
  args.keys.each do |key|
    if args[key] == nil
      args[key] = "NONE"
    end
  end
  
  pwd = ApioticsSetting.find_by(key: "wifi_key")
  if pwd == nil
    s = ApioticsSetting.new
    s.key = "wifi_key"
    s.value = SecureRandom.hex
    s.save
    pwd = s.value
  else
    pwd = pwd.value
  end

  encrypted_wifi_config = args.to_json.apiotics_encrypt(pwd)
  
  download_directory = Rails.root.join('lib', 'wifi')
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
  Dir.chdir download_directory
  path = Rails.root.join('lib', 'wifi', 'wifi_settings')
  File.write(path, encrypted_wifi_config)
end
write_uniflash_image(uniflash_path, config) click to toggle source
# File lib/apiotics/hardware.rb, line 270
def self.write_uniflash_image(uniflash_path, config)
  puts "Writing uniflash firmware image...\n"
  string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} image program --file #{config['firmware_file_name'].split(".")[0]}.sli"
  msg = system(string)
end