diff --git a/apps/home/home.py b/apps/home/home.py index 3ca0d12..d7300bc 100644 --- a/apps/home/home.py +++ b/apps/home/home.py @@ -223,12 +223,12 @@ def home_main(): #if wifi still needs poking if (wifi_timeout > 0): - if wifi.nic().is_connected(): + if wifi.is_connected(): wifi_timeout = -1 #wifi is connected, but if becomes disconnected, reconnect after 5 sec wifi_reconnect_timeout = 5 else: - wifi.nic().update() + wifi.update() if tick: @@ -276,7 +276,7 @@ def home_main(): ledg.on() # display the wifi logo - rssi = wifi.nic().get_rssi() + rssi = wifi.rssi() if rssi == 0: rssi = last_rssi else: diff --git a/bootstrap.py b/bootstrap.py index dc739f8..0e4fe60 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -233,17 +233,31 @@ def download(url, target, expected_hash): except ValueError as e: print(e) +if type(w) is dict: + # convert original format json (dict, one network) to new (list, many networks) + w = [w] + wifi_info = "\nMore information:\nbadge.emfcamp.org/TiLDA_MK3/wifi" -if "ssid" not in w: +if not all( [ ("ssid" in config) for config in w ] ): label.text("Couldn't find a valid wifi.json :(" + wifi_info) while True: pyb.wfi() -label.text("Connecting to '%s'.\nIf this is incorrect, please check your wifi.json%s" % (w["ssid"], wifi_info)) n = network.CC3100() -if ("pw" in w) and w["pw"]: - n.connect(w["ssid"], w["pw"], timeout=10) -else: - n.connect(w["ssid"], timeout=10) +visible_ssids = [ ap['ssid'] for ap in n.list_aps() ] +known_ssids = [ ap['ssid'] for ap in w ] + +if len(set(known_ssids).intersection(visible_ssids)) < 1: + label.text("Couldn't find any networks listed in wifi.json :(" + wifi_info) + while True: pyb.wfi() + +for ap in w: + if ap["ssid"] in visible_ssids: + label.text("Connecting to '%s'.\nIf this is incorrect, please check your wifi.json%s" % (ap["ssid"], wifi_info)) + if ("pw" in ap) and ap["pw"]: + n.connect(ap["ssid"], ap["pw"], timeout=10) + else: + n.connect(ap["ssid"], timeout=10) + break # found a visible AP, don't bother with any more success = False failure_counter = 0 diff --git a/lib/wifi.py b/lib/wifi.py index eca5435..d3fd2d6 100644 --- a/lib/wifi.py +++ b/lib/wifi.py @@ -7,7 +7,17 @@ import json import pyb + +class NICState: + NOT_CONNECTED = 1 + NO_VISIBLE_SSIDS = 2 + CONNECTING = 3 + CONNECTED = 3 + _nic = None +_network = None +_state = NICState.NOT_CONNECTED + def nic(): global _nic @@ -17,7 +27,7 @@ def nic(): def create_default_config(): with open("wifi.json", "wt") as file: - file.write(json.dumps({"ssid": "emfcamp-insecure"})) + file.write(json.dumps([{"ssid": "emfcamp-insecure"}])) file.flush() os.sync() @@ -30,40 +40,116 @@ def connection_details(): except ValueError as e: print(e) - if "ssid" not in data: + if type(data) is dict: + # convert original format data (dict, one network) to new (list, many networks) + data = [data] + + if not all( [ ("ssid" in config) for config in data ] ): raise OSError("Couldn't find a valid wifi.json. See https://badge.emf.camp for more information") return data def ssid(): - return connection_details()["ssid"] + global _network + if _network is None: + return "Not connected" + return _network["ssid"] + +def rssi(): + v = 0 + if is_connected(): + v = nic().get_rssi() + return v + +def update(): + nic().update() + +def disconnect(): + nic().disconnect() def connect(wait = True, timeout = 10): - if nic().is_connected(): + + print( "wifi.connect(wait=%r)" % (wait) ) + + global _network, _state + + if is_connected(): + print( "-> already connected.") return - details = connection_details() - - if "pw" in details and details["pw"]: - if wait: - nic().connect(details["ssid"], details["pw"], timeout=timeout) - wait_for_connection() - else: - nic().connect(details["ssid"], details["pw"], timeout=None) - else: - if wait: - nic().connect(details["ssid"], timeout=timeout) - wait_for_connection() - else: - nic().connect(details["ssid"], timeout=None) + _state = NICState.CONNECTING + + networks = connection_details() + visible_ssids = [ ap['ssid'] for ap in nic().list_aps() ] + print( "-> visible_ssids: %r" % visible_ssids ) + known_ssids = [ ap['ssid'] for ap in networks ] + print( "-> known_ssids: %r" % known_ssids ) + + if len(set(known_ssids).intersection(visible_ssids)) < 1: + print( "--> no known ssids visible!" ) + _state = NICState.NO_VISIBLE_SSIDS + return + + exc = None + for details in networks: + + if details["ssid"] in visible_ssids: + + _network = details + + try: + if "pw" in details and details["pw"]: + if wait: + nic().connect(details["ssid"], details["pw"], timeout=timeout) + wait_for_connection() + else: + nic().connect(details["ssid"], details["pw"], timeout=None) + else: + if wait: + nic().connect(details["ssid"], timeout=timeout) + wait_for_connection() + else: + nic().connect(details["ssid"], timeout=None) + except OSError as e: + # hold OSErrors and if we fail to connect to anything, throw the most recent + exc = e + + # found an AP to connect to, don't bother trying any more + break + + if exc is not None: + raise exc def wait_for_connection(): + print( "wifi.py: wait_for_connection()" ) + global _state while not nic().is_connected(): nic().update() pyb.delay(100) + _state = NICState.CONNECTED def is_connected(): - return nic().is_connected() + global _state + c = nic().is_connected() + if c: + _state = NICState.CONNECTED + return c def connection_text(): - return "Connecting to wifi '%s'. If this doesn't work, please check your wifi.json. More information: badge.emfcamp.org/TiLDA_MK3/wifi" % (ssid()) + global _state + text = "" + + if (_state == NICState.NOT_CONNECTED) or (_state == NICState.CONNECTING): + text = "Connecting to wifi" + if _network is not None: + text += " %s" % (ssid()) + text += ". If this doesn't work, please check your wifi.json." + + elif _state == NICState.NO_VISIBLE_SSIDS: + text = "No visible wifi networks have details in your wifi.json." + + elif _state == NICState.CONNECTED: + text = "Wifi connnected to %." % (ssid()) + + text += " More information: badge.emfcamp.org/TiLDA_MK3/wifi" + return text