diff --git a/examples/provisioning/ble_prov/ble_prov_test.py b/examples/provisioning/ble_prov/ble_prov_test.py index c61001545..ccbf5c5f9 100644 --- a/examples/provisioning/ble_prov/ble_prov_test.py +++ b/examples/provisioning/ble_prov/ble_prov_test.py @@ -17,7 +17,6 @@ from __future__ import print_function import re import os -import time import ttfw_idf import esp_prov @@ -82,19 +81,7 @@ def test_examples_provisioning_ble(env, extra_data): if not esp_prov.apply_wifi_config(transport, security): raise RuntimeError("Failed to send apply config") - success = False - while True: - time.sleep(5) - print("Wi-Fi connection state") - ret = esp_prov.get_wifi_config(transport, security) - if (ret == 1): - continue - elif (ret == 0): - print("Provisioning was successful") - success = True - break - - if not success: + if not esp_prov.wait_wifi_connected(transport, security): raise RuntimeError("Provisioning failed") diff --git a/examples/provisioning/ble_prov/main/app_prov.c b/examples/provisioning/ble_prov/main/app_prov.c index 19ea1b311..7ce62346f 100644 --- a/examples/provisioning/ble_prov/main/app_prov.c +++ b/examples/provisioning/ble_prov/main/app_prov.c @@ -248,8 +248,8 @@ static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_bas /* If none of the expected reasons, * retry connecting to host SSID */ g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - esp_wifi_connect(); } + esp_wifi_connect(); } } diff --git a/examples/provisioning/console_prov/main/app_prov.c b/examples/provisioning/console_prov/main/app_prov.c index b260db5f4..c02e48280 100644 --- a/examples/provisioning/console_prov/main/app_prov.c +++ b/examples/provisioning/console_prov/main/app_prov.c @@ -186,8 +186,8 @@ static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_bas /* If none of the expected reasons, * retry connecting to host SSID */ g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - esp_wifi_connect(); } + esp_wifi_connect(); } } diff --git a/examples/provisioning/custom_config/main/app_prov.c b/examples/provisioning/custom_config/main/app_prov.c index d9859cdb4..16e893a99 100644 --- a/examples/provisioning/custom_config/main/app_prov.c +++ b/examples/provisioning/custom_config/main/app_prov.c @@ -211,8 +211,8 @@ static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_bas /* If none of the expected reasons, * retry connecting to host SSID */ g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - esp_wifi_connect(); } + esp_wifi_connect(); } } diff --git a/examples/provisioning/manager/wifi_prov_mgr_test.py b/examples/provisioning/manager/wifi_prov_mgr_test.py index c8727c8ad..4289ab704 100644 --- a/examples/provisioning/manager/wifi_prov_mgr_test.py +++ b/examples/provisioning/manager/wifi_prov_mgr_test.py @@ -17,7 +17,6 @@ from __future__ import print_function import re import os -import time import ttfw_idf import esp_prov @@ -86,24 +85,7 @@ def test_examples_wifi_prov_mgr(env, extra_data): if not esp_prov.apply_wifi_config(transport, security): raise RuntimeError("Failed to send apply config") - success = False - retry = 0 - while True: - time.sleep(5) - print("Wi-Fi connection state") - ret = esp_prov.get_wifi_config(transport, security) - if (ret == 1): - continue - elif (ret == 0): - print("Provisioning was successful") - success = True - elif (ret == 3 and retry < 3): - retry = retry + 1 - print("Connection failed.. retry again...: ", ret) - continue - break - - if not success: + if not esp_prov.wait_wifi_connected(transport, security): raise RuntimeError("Provisioning failed") # Check if BTDM memory is released after provisioning finishes diff --git a/examples/provisioning/softap_prov/main/app_prov.c b/examples/provisioning/softap_prov/main/app_prov.c index 73c8bdfc6..11e798854 100644 --- a/examples/provisioning/softap_prov/main/app_prov.c +++ b/examples/provisioning/softap_prov/main/app_prov.c @@ -197,8 +197,8 @@ static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_bas /* If none of the expected reasons, * retry connecting to host SSID */ g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - esp_wifi_connect(); } + esp_wifi_connect(); } } diff --git a/examples/provisioning/softap_prov/softap_prov_test.py b/examples/provisioning/softap_prov/softap_prov_test.py index f129f3500..1689d6f95 100644 --- a/examples/provisioning/softap_prov/softap_prov_test.py +++ b/examples/provisioning/softap_prov/softap_prov_test.py @@ -17,7 +17,6 @@ from __future__ import print_function import re import os -import time import ttfw_idf import esp_prov @@ -52,64 +51,55 @@ def test_examples_provisioning_softap(env, extra_data): print("SoftAP SSID : " + ssid) print("SoftAP Password : " + password) - ctrl = wifi_tools.wpa_cli(iface, reset_on_exit=True) - print("Connecting to DUT SoftAP...") - ip = ctrl.connect(ssid, password) - got_ip = dut1.expect(re.compile(r"softAP assign IP to station,IP is: (\d+.\d+.\d+.\d+)"), timeout=30)[0] - if ip != got_ip: - raise RuntimeError("SoftAP connected to another host! " + ip + "!=" + got_ip) - print("Connected to DUT SoftAP") + try: + ctrl = wifi_tools.wpa_cli(iface, reset_on_exit=True) + print("Connecting to DUT SoftAP...") + ip = ctrl.connect(ssid, password) + got_ip = dut1.expect(re.compile(r"softAP assign IP to station,IP is: (\d+.\d+.\d+.\d+)"), timeout=60)[0] + if ip != got_ip: + raise RuntimeError("SoftAP connected to another host! " + ip + "!=" + got_ip) + print("Connected to DUT SoftAP") - print("Starting Provisioning") - verbose = False - protover = "V0.1" - secver = 1 - pop = "abcd1234" - provmode = "softap" - ap_ssid = "myssid" - ap_password = "mypassword" - softap_endpoint = ip.split('.')[0] + "." + ip.split('.')[1] + "." + ip.split('.')[2] + ".1:80" + print("Starting Provisioning") + verbose = False + protover = "V0.1" + secver = 1 + pop = "abcd1234" + provmode = "softap" + ap_ssid = "myssid" + ap_password = "mypassword" + softap_endpoint = ip.split('.')[0] + "." + ip.split('.')[1] + "." + ip.split('.')[2] + ".1:80" - print("Getting security") - security = esp_prov.get_security(secver, pop, verbose) - if security is None: - raise RuntimeError("Failed to get security") + print("Getting security") + security = esp_prov.get_security(secver, pop, verbose) + if security is None: + raise RuntimeError("Failed to get security") - print("Getting transport") - transport = esp_prov.get_transport(provmode, softap_endpoint) - if transport is None: - raise RuntimeError("Failed to get transport") + print("Getting transport") + transport = esp_prov.get_transport(provmode, softap_endpoint) + if transport is None: + raise RuntimeError("Failed to get transport") - print("Verifying protocol version") - if not esp_prov.version_match(transport, protover): - raise RuntimeError("Mismatch in protocol version") + print("Verifying protocol version") + if not esp_prov.version_match(transport, protover): + raise RuntimeError("Mismatch in protocol version") - print("Starting Session") - if not esp_prov.establish_session(transport, security): - raise RuntimeError("Failed to start session") + print("Starting Session") + if not esp_prov.establish_session(transport, security): + raise RuntimeError("Failed to start session") - print("Sending Wifi credential to DUT") - if not esp_prov.send_wifi_config(transport, security, ap_ssid, ap_password): - raise RuntimeError("Failed to send Wi-Fi config") + print("Sending Wifi credential to DUT") + if not esp_prov.send_wifi_config(transport, security, ap_ssid, ap_password): + raise RuntimeError("Failed to send Wi-Fi config") - print("Applying config") - if not esp_prov.apply_wifi_config(transport, security): - raise RuntimeError("Failed to send apply config") + print("Applying config") + if not esp_prov.apply_wifi_config(transport, security): + raise RuntimeError("Failed to send apply config") - success = False - while True: - time.sleep(5) - print("Wi-Fi connection state") - ret = esp_prov.get_wifi_config(transport, security) - if (ret == 1): - continue - elif (ret == 0): - print("Provisioning was successful") - success = True - break - - if not success: - raise RuntimeError("Provisioning failed") + if not esp_prov.wait_wifi_connected(transport, security): + raise RuntimeError("Provisioning failed") + finally: + ctrl.reset() if __name__ == '__main__': diff --git a/tools/ci/python_packages/wifi_tools.py b/tools/ci/python_packages/wifi_tools.py index 13376e52e..b926efb55 100644 --- a/tools/ci/python_packages/wifi_tools.py +++ b/tools/ci/python_packages/wifi_tools.py @@ -51,16 +51,26 @@ class wpa_cli: iface_path = service.GetInterface(self.iface_name) self.iface_obj = bus.get_object("fi.w1.wpa_supplicant1", iface_path) self.iface_ifc = dbus.Interface(self.iface_obj, "fi.w1.wpa_supplicant1.Interface") + self.iface_props = dbus.Interface(self.iface_obj, 'org.freedesktop.DBus.Properties') if self.iface_ifc is None: raise RuntimeError('supplicant : Failed to fetch interface') - self.old_network = self.iface_obj.Get("fi.w1.wpa_supplicant1.Interface", "CurrentNetwork", - dbus_interface='org.freedesktop.DBus.Properties') + self.old_network = self._get_iface_property("CurrentNetwork") + print("Old network is %s" % self.old_network) + if self.old_network == '/': self.old_network = None else: self.connected = True + def _get_iface_property(self, name): + """ Read the property with 'name' from the wi-fi interface object + + Note: The result is a dbus wrapped type, so should usually convert it to the corresponding native + Python type + """ + return self.iface_props.Get("fi.w1.wpa_supplicant1.Interface", name) + def connect(self, ssid, password): if self.connected is True: self.iface_ifc.Disconnect() @@ -69,6 +79,8 @@ class wpa_cli: if self.new_network is not None: self.iface_ifc.RemoveNetwork(self.new_network) + print("Pre-connect state is %s, IP is %s" % (self._get_iface_property("State"), get_wiface_IPv4(self.iface_name))) + self.new_network = self.iface_ifc.AddNetwork({"ssid": ssid, "psk": password}) self.iface_ifc.SelectNetwork(self.new_network) @@ -76,7 +88,14 @@ class wpa_cli: retry = 10 while retry > 0: time.sleep(5) + + state = str(self._get_iface_property("State")) + print("wpa iface state %s (scanning %s)" % (state, bool(self._get_iface_property("Scanning")))) + if state in ["disconnected", "inactive"]: + self.iface_ifc.Reconnect() + ip = get_wiface_IPv4(self.iface_name) + print("wpa iface %s IP %s" % (self.iface_name, ip)) if ip is not None: self.connected = True return ip diff --git a/tools/esp_prov/esp_prov.py b/tools/esp_prov/esp_prov.py index 3ce67d700..463a13983 100644 --- a/tools/esp_prov/esp_prov.py +++ b/tools/esp_prov/esp_prov.py @@ -266,6 +266,32 @@ def get_wifi_config(tp, sec): return None +def wait_wifi_connected(tp, sec): + """ + Wait for provisioning to report Wi-Fi is connected + + Returns True if Wi-Fi connection succeeded, False if connection consistently failed + """ + TIME_PER_POLL = 5 + retry = 3 + + while True: + time.sleep(TIME_PER_POLL) + print("\n==== Wi-Fi connection state ====") + ret = get_wifi_config(tp, sec) + if ret == "connecting": + continue + elif ret == "connected": + print("==== Provisioning was successful ====") + return True + elif retry > 0: + retry -= 1 + print("Waiting to poll status again (status %s, %d tries left)..." % (ret, retry)) + else: + print("---- Provisioning failed ----") + return False + + def desc_format(*args): desc = '' for arg in args: @@ -449,14 +475,4 @@ if __name__ == '__main__': exit(7) print("==== Apply config sent successfully ====") - while True: - time.sleep(5) - print("\n==== Wi-Fi connection state ====") - ret = get_wifi_config(obj_transport, obj_security) - if (ret == 1): - continue - elif (ret == 0): - print("==== Provisioning was successful ====") - else: - print("---- Provisioning failed ----") - break + wait_wifi_connected(obj_transport, obj_security) diff --git a/tools/esp_prov/prov/wifi_prov.py b/tools/esp_prov/prov/wifi_prov.py index 9140291f9..8bd6cd147 100644 --- a/tools/esp_prov/prov/wifi_prov.py +++ b/tools/esp_prov/prov/wifi_prov.py @@ -45,19 +45,24 @@ def config_get_status_response(security_ctx, response_data): cmd_resp1.ParseFromString(decrypted_message) print_verbose(security_ctx, "Response type " + str(cmd_resp1.msg)) print_verbose(security_ctx, "Response status " + str(cmd_resp1.resp_get_status.status)) + if cmd_resp1.resp_get_status.sta_state == 0: print("++++ WiFi state: " + "connected ++++") + return "connected" elif cmd_resp1.resp_get_status.sta_state == 1: print("++++ WiFi state: " + "connecting... ++++") + return "connecting" elif cmd_resp1.resp_get_status.sta_state == 2: print("++++ WiFi state: " + "disconnected ++++") + return "disconnected" elif cmd_resp1.resp_get_status.sta_state == 3: print("++++ WiFi state: " + "connection failed ++++") if cmd_resp1.resp_get_status.fail_reason == 0: print("++++ Failure reason: " + "Incorrect Password ++++") elif cmd_resp1.resp_get_status.fail_reason == 1: print("++++ Failure reason: " + "Incorrect SSID ++++") - return cmd_resp1.resp_get_status.sta_state + return "failed" + return "unknown" def config_set_config_request(security_ctx, ssid, passphrase): diff --git a/tools/esp_prov/transport/transport_http.py b/tools/esp_prov/transport/transport_http.py index 3c7aed013..c68612882 100644 --- a/tools/esp_prov/transport/transport_http.py +++ b/tools/esp_prov/transport/transport_http.py @@ -31,10 +31,10 @@ class Transport_HTTP(Transport): raise RuntimeError("Unable to resolve hostname :" + hostname) if certfile is None: - self.conn = http.client.HTTPConnection(hostname, timeout=30) + self.conn = http.client.HTTPConnection(hostname, timeout=45) else: ssl_ctx = ssl.create_default_context(cafile=certfile) - self.conn = http.client.HTTPSConnection(hostname, context=ssl_ctx, timeout=30) + self.conn = http.client.HTTPSConnection(hostname, context=ssl_ctx, timeout=45) try: print("Connecting to " + hostname) self.conn.connect()