From 057ae07db5bae696e8ec16be04e4e583eabb5d28 Mon Sep 17 00:00:00 2001
From: Tim Young <Tim.Young@LightSys.org>
Date: Sat, 22 Aug 2015 13:43:37 -0700
Subject: [PATCH] Auto-join wireless if ssid and keys match

---
 EduNetworkBuilder/Network.cs        | 49 +++++++++++++++++++++++++++
 EduNetworkBuilder/NetworkBuilder.cs |  1 +
 EduNetworkBuilder/NetworkDevice.cs  | 52 +++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/EduNetworkBuilder/Network.cs b/EduNetworkBuilder/Network.cs
index 17f0292..c39bcb6 100644
--- a/EduNetworkBuilder/Network.cs
+++ b/EduNetworkBuilder/Network.cs
@@ -1111,6 +1111,39 @@ namespace EduNetworkBuilder
             return distance(start.myLocation(), dest.myLocation());
         }
 
+        /// <summary>
+        /// Return the closest wireless device we can connect to
+        /// </summary>
+        /// <param name="start"></param>
+        /// <returns></returns>
+        public NetworkCard BestWirelessLinkForDevice(NetworkCard start)
+        {
+            NetworkDevice starting = GetDeviceFromID(start.myID);
+            NetworkCard found = null;
+            NetworkDevice checking = null;
+            double l_distance = 10000;
+            if (starting == null) return null;
+            NetworkCard answer=null;
+            foreach(NetworkComponent nc in NetComponents)
+            {
+                if(NB.GetComponentType(nc) == GeneralComponentType.device)
+                {
+                    checking = (NetworkDevice)nc;
+                    if (checking == starting) continue;
+                    answer = checking.HasWPortSSIDKey(start.SSID, start.EncryptionKey);
+                    if(answer != null)
+                    {
+                        double tdist = distance(starting, checking);
+                       if(tdist < l_distance)
+                       {
+                           l_distance = tdist;
+                           found = answer;
+                       }
+                    }
+                }
+            }
+            return found;
+        }
 
         /****************************************
          * Do On All Devices
@@ -1145,6 +1178,22 @@ namespace EduNetworkBuilder
             return didanything;
         }
 
+        public bool DoAllAutoJoin()
+        {
+            bool didanything = false;
+            NetworkDevice nd;
+            foreach (NetworkComponent nc in NetComponents.ToList())
+            {
+                if (NB.GetComponentType(nc) == GeneralComponentType.device)
+                {
+                    nd = (NetworkDevice)nc;
+                    didanything = nd.AutoJoinWireless() || didanything;
+                }
+            }
+
+            return didanything;
+        }
+
         public void DoAllClearArp()
         {
             NetworkDevice nd;
diff --git a/EduNetworkBuilder/NetworkBuilder.cs b/EduNetworkBuilder/NetworkBuilder.cs
index 9b8c5a6..789c6c2 100644
--- a/EduNetworkBuilder/NetworkBuilder.cs
+++ b/EduNetworkBuilder/NetworkBuilder.cs
@@ -350,6 +350,7 @@ namespace EduNetworkBuilder
             didanything = didanything || myNetwork.DoAllVerifyLinks();
 
             //now, update wireless links if we can.
+            didanything = myNetwork.DoAllAutoJoin() || didanything;
 
             //If we have done anything, check for tests being completed
             if (didanything)
diff --git a/EduNetworkBuilder/NetworkDevice.cs b/EduNetworkBuilder/NetworkDevice.cs
index e1721fb..6a87021 100644
--- a/EduNetworkBuilder/NetworkDevice.cs
+++ b/EduNetworkBuilder/NetworkDevice.cs
@@ -665,6 +665,58 @@ namespace EduNetworkBuilder
                 MessageBox.Show("The network card," + NICs[index].NicName() + " is locked as part of the puzzle.", "Locked NIC");
             }
         }
+        public bool AutoJoinWireless()
+        {
+            bool didsomething = false;
+            bool tryit = false;
+            Network myNet = NB.GetNetwork();
+
+            foreach(NetworkCard nic in NICs)
+            {
+                tryit = false;
+                if (nic.GetNicType != NicType.wlan) continue;
+                if (nic.SSID == "") continue;
+                if (!nic.isConnected(false)) tryit = true;
+                if(!tryit)
+                {
+                    //Check distance
+                    NetworkComponent nc = myNet.GetComponentFromID(nic.ConnectedLink);
+                    if(nc != null)
+                    {
+                        NetworkLink nl = (NetworkLink)nc;
+                        double distance = nl.LinkDistance();
+                        if (distance > NB.WirelessReconnectDistance)
+                            tryit = true;
+                    }
+                }
+                //Tryit tells us if we should try to reconnect.
+                if (tryit)
+                {
+                    //We want to find the closest device with an open wport that matches ssid/key and connect to it.
+                    NetworkCard Closest = myNet.BestWirelessLinkForDevice(nic);
+                    if(Closest != null)
+                    {
+                        NetworkLink newLink = new NetworkLink(nic.myID, Closest.myID, LinkType.wireless);
+                        myNet.AddItem(newLink);
+                        didsomething = true;
+                    }
+                }
+            }
+            return didsomething;
+        }
+
+        public NetworkCard HasWPortSSIDKey(string SSID, string Key)
+        {
+            foreach(NetworkCard nic in NICs)
+            {
+                if(nic.GetNicType == NicType.wport && !nic.isConnected(false))
+                {
+                    if (nic.SSID == SSID && nic.EncryptionKey == Key)
+                        return nic;
+                }
+            }
+            return null;
+        }
 
         public List<string> NetworkCardStrings(bool OnlyUnused=true, bool OnlyLinkable=false, NicType fromNic = NicType.none)
         {