From a9fd632545cde585cc8f95ed27982e74f73ca000 Mon Sep 17 00:00:00 2001 From: Dustin Mollo Date: Fri, 5 Apr 2019 10:02:55 -0700 Subject: [PATCH 1/4] Added support for WPA2 Enterprise, including example code. --- adafruit_esp32spi/adafruit_esp32spi.py | 28 +++++++++++ examples/esp32spi_wpa2ent_simpletest.py | 63 +++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 examples/esp32spi_wpa2ent_simpletest.py diff --git a/adafruit_esp32spi/adafruit_esp32spi.py b/adafruit_esp32spi/adafruit_esp32spi.py index 76e6cc8..fe0af99 100644 --- a/adafruit_esp32spi/adafruit_esp32spi.py +++ b/adafruit_esp32spi/adafruit_esp32spi.py @@ -82,6 +82,10 @@ _SEND_DATA_TCP_CMD = const(0x44) _GET_DATABUF_TCP_CMD = const(0x45) +_SET_ENT_IDENT_CMD = const(0x4A) +_SET_ENT_UNAME_CMD = const(0x4B) +_SET_ENT_PASSWD_CMD = const(0x4C) +_SET_ENT_ENABLE_CMD = const(0x4F) _START_CMD = const(0xE0) _END_CMD = const(0xEE) @@ -376,6 +380,30 @@ def wifi_set_passphrase(self, ssid, passphrase): if resp[0][0] != 1: raise RuntimeError("Failed to set passphrase") + def wifi_set_entidentity(self, ident): + """Sets the WPA2 Enterprise anonymous identity""" + resp = self._send_command_get_response(_SET_ENT_IDENT_CMD, [ident]) + if resp[0][0] != 1: + raise RuntimeError("Failed to set enterprise anonymous identity") + + def wifi_set_entusername(self, username): + """Sets the desired WPA2 Enterprise username""" + resp = self._send_command_get_response(_SET_ENT_UNAME_CMD, [username]) + if resp[0][0] != 1: + raise RuntimeError("Failed to set enterprise username") + + def wifi_set_entpassword(self, password): + """Sets the desired WPA2 Enterprise password""" + resp = self._send_command_get_response(_SET_ENT_PASSWD_CMD, [password]) + if resp[0][0] != 1: + raise RuntimeError("Failed to set enterprise password") + + def wifi_set_entenable(self): + """Enables WPA2 Enterprise mode""" + resp = self._send_command_get_response(_SET_ENT_ENABLE_CMD) + if resp[0][0] != 1: + raise RuntimeError("Failed to enable enterprise mode") + @property def ssid(self): """The name of the access point we're connected to""" diff --git a/examples/esp32spi_wpa2ent_simpletest.py b/examples/esp32spi_wpa2ent_simpletest.py new file mode 100644 index 0000000..26ede47 --- /dev/null +++ b/examples/esp32spi_wpa2ent_simpletest.py @@ -0,0 +1,63 @@ +import time +import board +import busio +from digitalio import DigitalInOut + +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_esp32spi.adafruit_esp32spi_requests as requests + +print("ESP32 SPI WPA2 Enterprise test") + +# For running on the PyPortal, use this block +esp32_cs = DigitalInOut(board.ESP_CS) +esp32_ready = DigitalInOut(board.ESP_BUSY) +esp32_reset = DigitalInOut(board.ESP_RESET) + +# For a board that doesn't have the ESP pin definitions, use this block and +# set the pins as needed. To connect your board to an ESP32 HUZZAH, here +# are the pin-outs on the HUZZAH32: +# https://learn.adafruit.com/adding-a-wifi-co-processor-to-circuitpython-esp8266-esp32/firmware-files#esp32-only-spi-firmware-3-8 +#esp32_cs = DigitalInOut(board.D8) +#esp32_ready = DigitalInOut(board.D5) +#esp32_reset = DigitalInOut(board.D7) + +spi = busio.SPI(board.SCK, board.MOSI, board.MISO) +esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) + +requests.set_interface(esp) + +if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: + print("ESP32 found and in idle mode") +print("Firmware vers.", esp.firmware_version) +print("MAC addr:", [hex(i) for i in esp.MAC_address]) + +# Set up the SSID you would like to connect to +esp.wifi_set_network(b'YOUR_SSID_HERE') + +# If your WPA2 Enterprise network requires an anonymous +# identity to be set, you may set that here +esp.wifi_set_entidentity(b'') + +# Set the WPA2 Enterprise username you'd like to use +esp.wifi_set_entusername(b'MY_USERNAME') + +# Set the WPA2 Enterprise password you'd like to use +esp.wifi_set_entpassword(b'MY_PASSWORD') + +# Once the network settings have been configured, +# we need to enable WPA2 Enterprise mode on the ESP32 +esp.wifi_set_entenable() + +# Wait for the network to come up +print("Connecting to AP...") +while not esp.is_connected: + print(".", end = "") + time.sleep(2) + +print("") +print("Connected to", str(esp.ssid, 'utf-8'), "\tRSSI:", esp.rssi) +print("My IP address is", esp.pretty_ip(esp.ip_address)) +print("IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))) +print("Ping google.com: %d ms" % esp.ping("google.com")) + +print("Done!") From 4110a445bd763e9c1612601f31c8156888a0b2a0 Mon Sep 17 00:00:00 2001 From: Dustin Mollo Date: Fri, 5 Apr 2019 10:23:30 -0700 Subject: [PATCH 2/4] Fixed line endings --- examples/esp32spi_wpa2ent_simpletest.py | 120 ++++++++++++------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/examples/esp32spi_wpa2ent_simpletest.py b/examples/esp32spi_wpa2ent_simpletest.py index 26ede47..3534db0 100644 --- a/examples/esp32spi_wpa2ent_simpletest.py +++ b/examples/esp32spi_wpa2ent_simpletest.py @@ -1,63 +1,63 @@ -import time -import board -import busio -from digitalio import DigitalInOut - -from adafruit_esp32spi import adafruit_esp32spi -import adafruit_esp32spi.adafruit_esp32spi_requests as requests - -print("ESP32 SPI WPA2 Enterprise test") - -# For running on the PyPortal, use this block +import time +import board +import busio +from digitalio import DigitalInOut + +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_esp32spi.adafruit_esp32spi_requests as requests + +print("ESP32 SPI WPA2 Enterprise test") + +# For running on the PyPortal, use this block esp32_cs = DigitalInOut(board.ESP_CS) esp32_ready = DigitalInOut(board.ESP_BUSY) esp32_reset = DigitalInOut(board.ESP_RESET) - -# For a board that doesn't have the ESP pin definitions, use this block and -# set the pins as needed. To connect your board to an ESP32 HUZZAH, here -# are the pin-outs on the HUZZAH32: -# https://learn.adafruit.com/adding-a-wifi-co-processor-to-circuitpython-esp8266-esp32/firmware-files#esp32-only-spi-firmware-3-8 -#esp32_cs = DigitalInOut(board.D8) -#esp32_ready = DigitalInOut(board.D5) -#esp32_reset = DigitalInOut(board.D7) - -spi = busio.SPI(board.SCK, board.MOSI, board.MISO) -esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) - -requests.set_interface(esp) - -if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: - print("ESP32 found and in idle mode") -print("Firmware vers.", esp.firmware_version) -print("MAC addr:", [hex(i) for i in esp.MAC_address]) - -# Set up the SSID you would like to connect to -esp.wifi_set_network(b'YOUR_SSID_HERE') - -# If your WPA2 Enterprise network requires an anonymous -# identity to be set, you may set that here -esp.wifi_set_entidentity(b'') - -# Set the WPA2 Enterprise username you'd like to use -esp.wifi_set_entusername(b'MY_USERNAME') - -# Set the WPA2 Enterprise password you'd like to use -esp.wifi_set_entpassword(b'MY_PASSWORD') - -# Once the network settings have been configured, -# we need to enable WPA2 Enterprise mode on the ESP32 -esp.wifi_set_entenable() - -# Wait for the network to come up -print("Connecting to AP...") -while not esp.is_connected: - print(".", end = "") - time.sleep(2) - -print("") -print("Connected to", str(esp.ssid, 'utf-8'), "\tRSSI:", esp.rssi) -print("My IP address is", esp.pretty_ip(esp.ip_address)) -print("IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))) -print("Ping google.com: %d ms" % esp.ping("google.com")) - -print("Done!") + +# For a board that doesn't have the ESP pin definitions, use this block and +# set the pins as needed. To connect your board to an ESP32 HUZZAH, here +# are the pin-outs on the HUZZAH32: +# https://learn.adafruit.com/adding-a-wifi-co-processor-to-circuitpython-esp8266-esp32/firmware-files#esp32-only-spi-firmware-3-8 +#esp32_cs = DigitalInOut(board.D8) +#esp32_ready = DigitalInOut(board.D5) +#esp32_reset = DigitalInOut(board.D7) + +spi = busio.SPI(board.SCK, board.MOSI, board.MISO) +esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) + +requests.set_interface(esp) + +if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: + print("ESP32 found and in idle mode") +print("Firmware vers.", esp.firmware_version) +print("MAC addr:", [hex(i) for i in esp.MAC_address]) + +# Set up the SSID you would like to connect to +esp.wifi_set_network(b'YOUR_SSID_HERE') + +# If your WPA2 Enterprise network requires an anonymous +# identity to be set, you may set that here +esp.wifi_set_entidentity(b'') + +# Set the WPA2 Enterprise username you'd like to use +esp.wifi_set_entusername(b'MY_USERNAME') + +# Set the WPA2 Enterprise password you'd like to use +esp.wifi_set_entpassword(b'MY_PASSWORD') + +# Once the network settings have been configured, +# we need to enable WPA2 Enterprise mode on the ESP32 +esp.wifi_set_entenable() + +# Wait for the network to come up +print("Connecting to AP...") +while not esp.is_connected: + print(".", end = "") + time.sleep(2) + +print("") +print("Connected to", str(esp.ssid, 'utf-8'), "\tRSSI:", esp.rssi) +print("My IP address is", esp.pretty_ip(esp.ip_address)) +print("IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))) +print("Ping google.com: %d ms" % esp.ping("google.com")) + +print("Done!") From e9bbf9509ed0de8d74ca952d42f283b11e6b33b7 Mon Sep 17 00:00:00 2001 From: Dustin Mollo Date: Sat, 6 Apr 2019 12:25:07 -0700 Subject: [PATCH 3/4] Updated WPA2 Enterprise example code to check ESP32 firmware version; updated README.rst to recommended checking version dependencies in example code. --- README.rst | 5 +++- examples/esp32spi_wpa2ent_simpletest.py | 34 ++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index b8e9368..ab42fc8 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,10 @@ Introduction :target: https://travis-ci.com/adafruit/Adafruit_CircuitPython_ESP32SPI :alt: Build Status -CircuitPython driver library for using ESP32 as WiFi co-processor using SPI +CircuitPython driver library for using ESP32 as WiFi co-processor using SPI. +The companion firmware `is available on GitHub +`_. Please be sure to check the example code for +any specific firmware version dependencies that may exist. Dependencies diff --git a/examples/esp32spi_wpa2ent_simpletest.py b/examples/esp32spi_wpa2ent_simpletest.py index 3534db0..78ba1dd 100644 --- a/examples/esp32spi_wpa2ent_simpletest.py +++ b/examples/esp32spi_wpa2ent_simpletest.py @@ -1,3 +1,12 @@ +# Example code implementing WPA2 Enterprise mode +# +# This code requires firmware version 1.3.0, or newer, running +# on the ESP32 WiFi co-processor. The latest firmware, and wiring +# info if you are using something other than a PyPortal, can be found +# in the Adafruit Learning System: +# https://learn.adafruit.com/adding-a-wifi-co-processor-to-circuitpython-esp8266-esp32/firmware-files#esp32-only-spi-firmware-3-8 + +import re import time import board import busio @@ -6,6 +15,14 @@ from adafruit_esp32spi import adafruit_esp32spi import adafruit_esp32spi.adafruit_esp32spi_requests as requests +# Version number comparison code. Credit to gnud on stackoverflow +# (https://stackoverflow.com/a/1714190), swapping out cmp() to +# support Python 3.x and thus, CircuitPython +def version_compare(version1, version2): + def normalize(v): + return [int(x) for x in re.sub(r'(\.0+)*$','', v).split(".")] + return (normalize(version1) > normalize(version2)) - (normalize(version1) < normalize(version2)) + print("ESP32 SPI WPA2 Enterprise test") # For running on the PyPortal, use this block @@ -14,9 +31,7 @@ esp32_reset = DigitalInOut(board.ESP_RESET) # For a board that doesn't have the ESP pin definitions, use this block and -# set the pins as needed. To connect your board to an ESP32 HUZZAH, here -# are the pin-outs on the HUZZAH32: -# https://learn.adafruit.com/adding-a-wifi-co-processor-to-circuitpython-esp8266-esp32/firmware-files#esp32-only-spi-firmware-3-8 +# set the pins as needed. #esp32_cs = DigitalInOut(board.D8) #esp32_ready = DigitalInOut(board.D5) #esp32_reset = DigitalInOut(board.D7) @@ -28,10 +43,21 @@ if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: print("ESP32 found and in idle mode") -print("Firmware vers.", esp.firmware_version) + +# Get the ESP32 fw version number, remove trailing byte off the returned bytearray +# and then convert it to a string for prettier printing and later comparison +firmware_version = ''.join([chr(b) for b in esp.firmware_version[:-1]]) +print("Firmware vers.", firmware_version) + print("MAC addr:", [hex(i) for i in esp.MAC_address]) +# WPA2 Enterprise support was added in fw ver 1.3.0. Check that the ESP32 +# is running at least that version, otherwise, bail out +assert version_compare(firmware_version, "1.3.0") >= 0, "Inforrect ESP32 firmware version detected. v1.3.0 or greater required" + # Set up the SSID you would like to connect to +# Note that we need to call wifi_set_network prior +# to calling wifi_set_enable. esp.wifi_set_network(b'YOUR_SSID_HERE') # If your WPA2 Enterprise network requires an anonymous From d9324b12cf5cd8d3e76dc3cb2727072fceea186d Mon Sep 17 00:00:00 2001 From: Dustin Mollo Date: Sat, 6 Apr 2019 14:18:02 -0700 Subject: [PATCH 4/4] Fixed line length lynt issue --- examples/esp32spi_wpa2ent_simpletest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/esp32spi_wpa2ent_simpletest.py b/examples/esp32spi_wpa2ent_simpletest.py index 78ba1dd..d8d2a14 100644 --- a/examples/esp32spi_wpa2ent_simpletest.py +++ b/examples/esp32spi_wpa2ent_simpletest.py @@ -53,7 +53,8 @@ def normalize(v): # WPA2 Enterprise support was added in fw ver 1.3.0. Check that the ESP32 # is running at least that version, otherwise, bail out -assert version_compare(firmware_version, "1.3.0") >= 0, "Inforrect ESP32 firmware version detected. v1.3.0 or greater required" +assert version_compare(firmware_version, "1.3.0") >= 0, ( + "Incorrect ESP32 firmware version; >= 1.3.0 required.") # Set up the SSID you would like to connect to # Note that we need to call wifi_set_network prior