Skip to content

Instantly share code, notes, and snippets.

@adkron
Created August 3, 2017 04:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adkron/6cf8dea157abbcfeb4acf3a086b303da to your computer and use it in GitHub Desktop.
Save adkron/6cf8dea157abbcfeb4acf3a086b303da to your computer and use it in GitHub Desktop.
defmodule Nerves.Network.IFSupervisor do
use Supervisor
@moduledoc false
def start_link(options \\ []) do
Supervisor.start_link(__MODULE__, [], options)
end
def init([]) do
{:ok, {{:one_for_one, 10, 3600}, []}}
end
def setup(ifname, settings) when is_atom(ifname) do
setup(to_string(ifname), settings)
end
def setup(ifname, settings) do
ensure_process ifname, :already_added, fn ->
manager_module = manager(if_type(ifname), settings)
child = worker(manager_module,
[ifname, settings, [name: pidname]],
id: pidname)
Supervisor.start_child(__MODULE__, child)
end
end
def teardown(ifname) do
ensure_process ifname, :not_started, fn ->
Supervisor.terminate_child(__MODULE__, pidname)
Supervisor.delete_child(__MODULE__, pidname)
end
end
def scan(ifname) do
ensure_process ifname, :not_started, fn ->
GenServer.call(pidname, :scan, 30_000)
end
end
def status(ifname) do
ensure_process ifname, :not_started, fn ->
Nerves.NetworkInterface.status(ifname)
end
end
defp ensure_process(ifname, error_code, fun) do
pidname = pname(ifname)
if Process.whereis(pidname) do
fun.()
else
{:error, error_code}
end
end
defp pname(ifname) do
String.to_atom("Nerves.Network.Interface." <> ifname)
end
# Return the appropriate interface manager based on the interface's type
# and settings
defp manager(:wired, settings) do
case Keyword.get(settings, :ipv4_address_method) do
:static -> Nerves.Network.StaticManager
:linklocal -> Nerves.Network.LinkLocalManager
:dhcp -> Nerves.Network.DHCPManager
end
end
defp manager(:wireless, _settings) do
Nerves.Network.WiFiManager
end
# Categorize networks into wired and wireless based on their if names
defp if_type(<<"eth", _rest::binary>>), do: :wired
defp if_type(<<"usb", _rest::binary>>), do: :wired
defp if_type(<<"lo", _rest::binary>>), do: :wired # Localhost
defp if_type(<<"wlan", _rest::binary>>), do: :wireless
defp if_type(<<"ra", _rest::binary>>), do: :wireless # Ralink
# systemd predictable names
defp if_type(<<"en", _rest::binary>>), do: :wired
defp if_type(<<"sl", _rest::binary>>), do: :wired # SLIP
defp if_type(<<"wl", _rest::binary>>), do: :wireless
defp if_type(<<"ww", _rest::binary>>), do: :wired # wwan (not really supported)
defp if_type(_ifname), do: :wired
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment