Fix not being able to connect to hidden networks.

To connect to a hidden wireless network, the client needs
to wait for the wireless beacon before being able to connect
to get the bssid and essid.

* Add flag if the user manually inputs their ssid.
* Add special case for if the network is hidden
pull/462/head
connor rigby 2018-03-08 09:04:58 -08:00 committed by Connor Rigby
parent 9124afcc76
commit 18fc385776
6 changed files with 66 additions and 16 deletions

View File

@ -16,6 +16,7 @@ defmodule Farmbot.System.ConfigStorage.NetworkInterface do
field(:ipv4_method, :string)
field(:migrated, :boolean)
field(:maybe_hidden, :boolean)
end
@required_fields [:name, :type]

View File

@ -118,17 +118,29 @@ defmodule Farmbot.Target.Bootstrap.Configurator.Router do
case settings["type"] do
"wireless" ->
# lol
maybe_hidden? = if Map.get(settings, "maybe_hidden", false) do
true
else
false
end
%ConfigStorage.NetworkInterface{
name: iface,
type: "wireless",
ssid: Map.fetch!(settings, "ssid"),
psk: Map.fetch!(settings, "psk"),
security: "WPA-PSK",
ipv4_method: "dhcp"
ipv4_method: "dhcp",
maybe_hidden: maybe_hidden?
}
"wired" ->
%ConfigStorage.NetworkInterface{name: iface, type: "wired", ipv4_method: "dhcp"}
%ConfigStorage.NetworkInterface{
name: iface,
type: "wired",
ipv4_method: "dhcp"
}
end
|> ConfigStorage.insert!()
end

View File

@ -17,16 +17,18 @@ defmodule Farmbot.Target.Network.Manager do
def init({interface, opts} = args) do
Elixir.Logger.remove_backend Elixir.Logger.Backends.Console
Logger.busy(3, "Waiting for interface up.")
unless interface in Nerves.NetworkInterface.interfaces() do
Process.sleep(1000)
init(args)
end
SystemRegistry.register()
{:ok, _} = Elixir.Registry.register(Nerves.NetworkInterface, interface, [])
{:ok, _} = Elixir.Registry.register(Nerves.Udhcpc, interface, [])
{:ok, _} = Elixir.Registry.register(Nerves.WpaSupplicant, interface, [])
Network.setup(interface, opts)
{:ok, %{interface: interface, ip_address: nil, connected: false, not_found_timer: nil, ntp_timer: nil, dns_timer: nil}}
{:ok, %{interface: interface, opts: opts, ip_address: nil, connected: false, not_found_timer: nil, ntp_timer: nil, dns_timer: nil}}
end
def handle_call(:ip, _, state) do
@ -63,15 +65,27 @@ defmodule Farmbot.Target.Network.Manager do
first_boot = ConfigStorage.get_config_value(:bool, "settings", "first_boot")
# stored in minutes
delay_timer = (ConfigStorage.get_config_value(:float, "settings", "network_not_found_timer") || 1) * 60_000
maybe_hidden? = Keyword.get(state.opts, :maybe_hidden, false)
cond do
# Check if the network might be hidden first.
maybe_hidden? ->
Logger.warn 1, "Possibly hidden network not found. Starting timer (hidden=#{maybe_hidden?})"
timer = Process.send_after(self(), :network_not_found_timer, round(delay_timer))
{:noreply, %{state | not_found_timer: timer, connected: false}}
# If its not hidden, just reset. Probably a typo.
first_boot ->
Logger.error 1, "Network not found"
Farmbot.System.factory_reset("WIFI Authentication failed. (network not found)")
{:stop, :normal, state}
# If not first boot, and we have a valid number for the delay timer.
delay_timer > 0 ->
Logger.warn 1, "Network not found. Starting timer."
Logger.warn 1, "Network not found. Starting timer (hidden=#{maybe_hidden?})"
timer = Process.send_after(self(), :network_not_found_timer, round(delay_timer))
{:noreply, %{state | not_found_timer: timer, connected: false}}
# I don't think this can even happen.
is_nil(delay_timer) ->
Logger.error 1, "Network not found"
Farmbot.System.factory_reset("WIFI Authentication failed. (network not found)")

View File

@ -26,9 +26,9 @@ defmodule Farmbot.Target.Network do
# TODO Expand this to allow for more settings.
def to_network_config(config)
def to_network_config(%NetworkInterface{ssid: ssid, psk: psk, type: "wireless"} = config) do
def to_network_config(%NetworkInterface{ssid: ssid, psk: psk, type: "wireless", maybe_hidden: hidden?} = config) do
Logger.debug(3, "wireless network config: ssid: #{config.ssid}")
{config.name, [ssid: ssid, key_mgmt: :"WPA-PSK", psk: psk]}
{config.name, [ssid: ssid, key_mgmt: :"WPA-PSK", psk: psk, maybe_hidden: hidden?]}
end
def to_network_config(%NetworkInterface{type: "wired"} = config) do

View File

@ -0,0 +1,9 @@
defmodule Farmbot.System.ConfigStorage.Migrations.AddMaybeHiddenNetworkFlag do
use Ecto.Migration
def change do
alter table("network_interfaces") do
add(:maybe_hidden, :boolean)
end
end
end

View File

@ -5,6 +5,7 @@
<title> Configure Farmbot's Network </title>
<link rel="stylesheet" href="/styles.css">
<script type="text/javascript">
function ssidSelectOnChange(iface) {
var elem = document.getElementById(iface + "_ssid_select");
var selected = elem.options[elem.selectedIndex];
@ -13,15 +14,19 @@
replaceSelect(iface);
}
}
function replaceSelect(iface) {
console.log("Replaceing select element with input element")
var elem = document.getElementById(iface + "_ssid_select");
console.log("Replaceing select element with input element");
var selectElem = document.getElementById(iface + "_ssid_select");
var inputNode = document.createElement("input");
inputNode.setAttribute("name", iface + "_ssid");
inputNode.setAttribute("type", "text");
elem.parentNode.insertBefore(inputNode, elem.nextSibling);
elem.outerHTML = "";
delete elem;
selectElem.parentNode.insertBefore(inputNode, selectElem.nextSibling);
selectElem.outerHTML = "";
delete selectElem;
var maybeHiddenToggle = document.getElementById(iface + "_maybe_hidden");
maybeHiddenToggle.setAttribute("value", "true");
}
function selectInterface(iface, type) {
@ -33,6 +38,7 @@
for(i=0; i<elems.length; i++){ elems[i].setAttribute("hidden", true) }
}
}
</script>
</head>
@ -68,15 +74,23 @@
<label>Password</label>
<input type=password name="<%= interface %>_psk" />
<input hidden=true name="<%= interface %>_type" value="wireless" />
<input hidden=true name="<%= interface %>_maybe_hidden" id="<%= interface %>_maybe_hidden" value="false" />
</fieldset>
<% end %>
<% end %>
<% end %>
<div class="button">
<input type=submit value="next">
</div>
</form>
</div>
</div>
<div class="button">
<input type=submit value="next">
</div>
</form>
</body>