142 lines
3.4 KiB
Elixir
142 lines
3.4 KiB
Elixir
defmodule Farmbot.Target.Network.Utils do
|
|
import Farmbot.Config, only: [get_config_value: 3]
|
|
require Farmbot.Logger
|
|
alias Farmbot.Target.Network.ScanResult
|
|
|
|
def build_hostap_ssid do
|
|
{:ok, hostname} = :inet.gethostname()
|
|
|
|
if String.starts_with?(to_string(hostname), "farmbot-") do
|
|
to_string('farmbot-' ++ Enum.take(hostname, -4))
|
|
else
|
|
to_string(hostname)
|
|
end
|
|
end
|
|
|
|
@doc "Scan on an interface."
|
|
def scan(iface) do
|
|
do_scan(iface)
|
|
|> ScanResult.decode()
|
|
|> ScanResult.sort_results()
|
|
|> ScanResult.decode_security()
|
|
|> Enum.filter(&Map.get(&1, :ssid))
|
|
|> Enum.map(&Map.update(&1, :ssid, nil, fn ssid -> to_string(ssid) end))
|
|
|> Enum.reject(&String.contains?(&1.ssid, "\\x00"))
|
|
|> Enum.uniq_by(fn %{ssid: ssid} -> ssid end)
|
|
end
|
|
|
|
defp wait_for_results(pid) do
|
|
Nerves.WpaSupplicant.request(pid, :SCAN_RESULTS)
|
|
|> String.trim()
|
|
|> String.split("\n")
|
|
|> tl()
|
|
|> Enum.map(&String.split(&1, "\t"))
|
|
|> reduce_decode()
|
|
|> case do
|
|
[] ->
|
|
Process.sleep(500)
|
|
wait_for_results(pid)
|
|
|
|
res ->
|
|
res
|
|
end
|
|
end
|
|
|
|
defp reduce_decode(results, acc \\ [])
|
|
defp reduce_decode([], acc), do: Enum.reverse(acc)
|
|
|
|
defp reduce_decode([[bssid, freq, signal, flags, ssid] | rest], acc) do
|
|
decoded = %{
|
|
bssid: bssid,
|
|
frequency: String.to_integer(freq),
|
|
flags: flags,
|
|
level: String.to_integer(signal),
|
|
ssid: ssid
|
|
}
|
|
|
|
reduce_decode(rest, [decoded | acc])
|
|
end
|
|
|
|
defp reduce_decode([[bssid, freq, signal, flags] | rest], acc) do
|
|
decoded = %{
|
|
bssid: bssid,
|
|
frequency: String.to_integer(freq),
|
|
flags: flags,
|
|
level: String.to_integer(signal),
|
|
ssid: nil
|
|
}
|
|
|
|
reduce_decode(rest, [decoded | acc])
|
|
end
|
|
|
|
defp reduce_decode([_ | rest], acc) do
|
|
reduce_decode(rest, acc)
|
|
end
|
|
|
|
def do_scan(iface) do
|
|
pid = :"Nerves.WpaSupplicant.#{iface}"
|
|
|
|
if Process.whereis(pid) do
|
|
Nerves.WpaSupplicant.request(pid, :SCAN)
|
|
wait_for_results(pid)
|
|
else
|
|
[]
|
|
end
|
|
end
|
|
|
|
def get_level(ifname, ssid) do
|
|
r = scan(ifname)
|
|
|
|
if res = Enum.find(r, &(Map.get(&1, :ssid) == ssid)) do
|
|
res.level
|
|
end
|
|
end
|
|
|
|
@doc "Tests if we can make dns queries."
|
|
def test_dns(hostname \\ nil)
|
|
|
|
def test_dns(nil) do
|
|
case get_config_value(:string, "authorization", "server") do
|
|
nil ->
|
|
test_dns(get_config_value(:string, "settings", "default_dns_name"))
|
|
|
|
url when is_binary(url) ->
|
|
%URI{host: hostname} = URI.parse(url)
|
|
test_dns(hostname)
|
|
end
|
|
end
|
|
|
|
def test_dns(hostname) when is_binary(hostname) do
|
|
test_dns(to_charlist(hostname))
|
|
end
|
|
|
|
def test_dns(hostname) do
|
|
:ok = :inet_db.clear_cache()
|
|
# IO.puts "testing dns: #{hostname}"
|
|
case :inet.parse_ipv4_address(hostname) do
|
|
{:ok, addr} -> {:ok, {:hostent, hostname, [], :inet, 4, [addr]}}
|
|
_ -> :inet_res.gethostbyname(hostname)
|
|
end
|
|
end
|
|
|
|
@fb_data_dir Farmbot.OS.FileSystem.data_path()
|
|
@tzdata_dir Application.app_dir(:tzdata, "priv")
|
|
def maybe_hack_tzdata do
|
|
case Tzdata.Util.data_dir() do
|
|
@fb_data_dir ->
|
|
:ok
|
|
|
|
_ ->
|
|
Farmbot.Logger.debug(3, "Hacking tzdata.")
|
|
objs_to_cp = Path.wildcard(Path.join(@tzdata_dir, "*"))
|
|
|
|
for obj <- objs_to_cp do
|
|
File.cp_r(obj, @fb_data_dir)
|
|
end
|
|
|
|
Application.put_env(:tzdata, :data_dir, @fb_data_dir)
|
|
:ok
|
|
end
|
|
end
|
|
end
|