farmbot_os/farmbot_os/platform/target/configurator/vintage_network_layer.ex

74 lines
2.1 KiB
Elixir

defmodule FarmbotOS.Platform.Target.Configurator.VintageNetworkLayer do
@moduledoc """
Implementation of Network configuration layer using
VintageNet
"""
require FarmbotCore.Logger
@behaviour FarmbotOS.Configurator.NetworkLayer
@impl FarmbotOS.Configurator.NetworkLayer
def list_interfaces() do
VintageNet.all_interfaces()
|> Kernel.--(["usb0", "lo"])
|> Enum.map(fn ifname ->
[{["interface", ^ifname, "mac_address"], mac_address}] =
VintageNet.get_by_prefix(["interface", ifname, "mac_address"])
{ifname, %{mac_address: mac_address}}
end)
end
@impl FarmbotOS.Configurator.NetworkLayer
def scan(ifname) do
{:ok, aps} = do_scan(ifname)
Enum.map(aps, fn %{
bssid: bssid,
ssid: ssid,
signal_percent: signal,
flags: flags
} ->
%{
ssid: ssid,
bssid: bssid,
level: signal,
security: flags_to_security(flags)
}
end)
|> Enum.uniq_by(fn %{ssid: ssid} -> ssid end)
|> Enum.sort(fn
%{level: level1}, %{level: level2} -> level1 >= level2
end)
|> Enum.filter(fn %{ssid: ssid} ->
String.length(to_string(ssid)) > 0
end)
end
defp do_scan(ifname) do
_ = VintageNet.scan(ifname)
case VintageNet.get_by_prefix(["interface", ifname, "wifi", "access_points"]) do
[{_, []}] ->
FarmbotCore.Logger.debug(3, "AP list was empty. Trying again")
Process.sleep(100)
do_scan(ifname)
[{_, [_ | _] = aps}] ->
{:ok, aps}
_ ->
:error
end
end
defp flags_to_security([:wpa2_psk_ccmp | _]), do: "WPA-PSK"
defp flags_to_security([:wpa2_psk_ccmp_tkip | _]), do: "WPA-PSK"
defp flags_to_security([:wpa_psk_ccmp | _]), do: "WPA-PSK"
defp flags_to_security([:wpa_psk_ccmp_tkip | _]), do: "WPA-PSK"
defp flags_to_security([:wpa2_eap_ccmp | _]), do: "WPA-EAP"
defp flags_to_security([:wpa_eap_ccmp_tkip | _]), do: "WPA-EAP"
defp flags_to_security([_ | rest]), do: flags_to_security(rest)
defp flags_to_security([]), do: "NONE"
end