diff --git a/.travis.yml b/.travis.yml index 2cca18ba..acfbccce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,6 +31,7 @@ script: - buildExampleSketch ConnectNoEncryption - buildExampleSketch ConnectWithWEP - buildExampleSketch ConnectWithWPA + - buildExampleSketch ConnectWithWPA2Enterprise - buildExampleSketch ScanNetworks - buildExampleSketch ScanNetworksAdvanced - buildExampleSketch SimpleWebServerWiFi diff --git a/examples/ConnectWithWPA2Enterprise/ConnectWithWPA2Enterprise.ino b/examples/ConnectWithWPA2Enterprise/ConnectWithWPA2Enterprise.ino new file mode 100644 index 00000000..77644e89 --- /dev/null +++ b/examples/ConnectWithWPA2Enterprise/ConnectWithWPA2Enterprise.ino @@ -0,0 +1,111 @@ +/* + This example connects to an WPA2 Enterprise WiFi network. + Then it prints the MAC address of the WiFi module, + the IP address obtained, and other network details. + + Based on ConnectWithWPA.ino by dlf (Metodo2 srl) and Tom Igoe +*/ +#include +#include + +#include "arduino_secrets.h" +///////please enter your sensitive data in the Secret tab/arduino_secrets.h +char ssid[] = SECRET_SSID; // your WPA2 enterprise network SSID (name) +char user[] = SECRET_USER; // your WPA2 enterprise username +char pass[] = SECRET_PASS; // your WPA2 enterprise password +int status = WL_IDLE_STATUS; // the Wifi radio's status + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + // attempt to connect to Wifi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to WPA SSID: "); + Serial.println(ssid); + // Connect to WPA2 enterprise network: + // - You can optionally provide additional identity and CA cert (string) parameters: + // WiFi.beginEnterprise(ssid, user, pass, identity, caCert) + // . if your network requires them. + status = WiFi.beginEnterprise(ssid, user, pass); + + // wait 10 seconds for connection: + delay(10000); + } + + // you're connected now, so print out the data: + Serial.print("You're connected to the network"); + printCurrentNet(); + printWifiData(); + +} + +void loop() { + // check the network connection once every 10 seconds: + delay(10000); + printCurrentNet(); +} + +void printWifiData() { + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print your MAC address: + byte mac[6]; + WiFi.macAddress(mac); + Serial.print("MAC address: "); + printMacAddress(mac); +} + +void printCurrentNet() { + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print the MAC address of the router you're attached to: + byte bssid[6]; + WiFi.BSSID(bssid); + Serial.print("BSSID: "); + printMacAddress(bssid); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.println(rssi); + + // print the encryption type: + byte encryption = WiFi.encryptionType(); + Serial.print("Encryption Type:"); + Serial.println(encryption, HEX); + Serial.println(); +} + +void printMacAddress(byte mac[]) { + for (int i = 5; i >= 0; i--) { + if (mac[i] < 16) { + Serial.print("0"); + } + Serial.print(mac[i], HEX); + if (i > 0) { + Serial.print(":"); + } + } + Serial.println(); +} diff --git a/examples/ConnectWithWPA2Enterprise/arduino_secrets.h b/examples/ConnectWithWPA2Enterprise/arduino_secrets.h new file mode 100644 index 00000000..d1310bbd --- /dev/null +++ b/examples/ConnectWithWPA2Enterprise/arduino_secrets.h @@ -0,0 +1,3 @@ +#define SECRET_SSID "" +#define SECRET_USER "" +#define SECRET_PASS "" diff --git a/keywords.txt b/keywords.txt index f217431b..2e1f9c68 100644 --- a/keywords.txt +++ b/keywords.txt @@ -48,6 +48,7 @@ remoteIP KEYWORD2 remotePort KEYWORD2 beginAP KEYWORD2 +beginEnterprise KEYWORD2 setHostname KEYWORD2 end KEYWORD2 getTime KEYWORD2 diff --git a/src/WiFi.cpp b/src/WiFi.cpp index e4a34dd4..ed5bae02 100644 --- a/src/WiFi.cpp +++ b/src/WiFi.cpp @@ -156,6 +156,37 @@ uint8_t WiFiClass::beginAP(const char *ssid, const char* passphrase, uint8_t cha return status; } +uint8_t WiFiClass::beginEnterprise(const char* ssid, const char* username, const char* password) +{ + return beginEnterprise(ssid, username, password, ""); +} + +uint8_t WiFiClass::beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity) +{ + return beginEnterprise(ssid, username, password, identity, ""); +} + +uint8_t WiFiClass::beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity, const char* ca) +{ + uint8_t status = WL_IDLE_STATUS; + + // set passphrase + if (WiFiDrv::wifiSetEnterprise(0 /*PEAP/MSCHAPv2*/, ssid, strlen(ssid), username, strlen(username), password, strlen(password), identity, strlen(identity), ca, strlen(ca) + 1)!= WL_FAILURE) + { + for (unsigned long start = millis(); (millis() - start) < _timeout;) + { + delay(WL_DELAY_START_CONNECTION); + status = WiFiDrv::getConnectionStatus(); + if ((status != WL_IDLE_STATUS) && (status != WL_NO_SSID_AVAIL) && (status != WL_SCAN_COMPLETED)) { + break; + } + } + } else { + status = WL_CONNECT_FAILED; + } + return status; +} + void WiFiClass::config(IPAddress local_ip) { WiFiDrv::config(1, (uint32_t)local_ip, 0, 0); diff --git a/src/WiFi.h b/src/WiFi.h index 3bb5db60..d88541e8 100644 --- a/src/WiFi.h +++ b/src/WiFi.h @@ -80,6 +80,10 @@ class WiFiClass uint8_t beginAP(const char *ssid, const char* passphrase); uint8_t beginAP(const char *ssid, const char* passphrase, uint8_t channel); + uint8_t beginEnterprise(const char* ssid, const char* username, const char* password); + uint8_t beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity); + uint8_t beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity, const char* ca); + /* Change Ip configuration settings disabling the dhcp client * * param local_ip: Static ip configuration diff --git a/src/utility/wifi_drv.cpp b/src/utility/wifi_drv.cpp index 3575d797..3b7618ec 100644 --- a/src/utility/wifi_drv.cpp +++ b/src/utility/wifi_drv.cpp @@ -921,6 +921,42 @@ int8_t WiFiDrv::wifiSetApPassphrase(const char* ssid, uint8_t ssid_len, const ch return _data; } +int8_t WiFiDrv::wifiSetEnterprise(uint8_t eapType, const char* ssid, uint8_t ssid_len, const char *username, const uint8_t username_len, const char *password, const uint8_t password_len, const char *identity, const uint8_t identity_len, const char* ca_cert, uint16_t ca_cert_len) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(SET_ENT_CMD, PARAM_NUMS_6); + SpiDrv::sendBuffer(&eapType, sizeof(eapType)); + SpiDrv::sendBuffer((uint8_t*)ssid, ssid_len); + SpiDrv::sendBuffer((uint8_t*)username, username_len); + SpiDrv::sendBuffer((uint8_t*)password, password_len); + SpiDrv::sendBuffer((uint8_t*)identity, identity_len); + SpiDrv::sendBuffer((uint8_t*)ca_cert, ca_cert_len, LAST_PARAM); + + // pad to multiple of 4 + int commandSize = 15 + sizeof(eapType) + ssid_len + username_len + password_len + identity_len + ca_cert_len; + while (commandSize % 4) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(SET_ENT_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); + return _data; +} + int16_t WiFiDrv::ping(uint32_t ipAddress, uint8_t ttl) { WAIT_FOR_SLAVE_SELECT(); diff --git a/src/utility/wifi_drv.h b/src/utility/wifi_drv.h index d9bfeff2..6985b624 100644 --- a/src/utility/wifi_drv.h +++ b/src/utility/wifi_drv.h @@ -277,6 +277,13 @@ class WiFiDrv static int8_t wifiSetApNetwork(const char* ssid, uint8_t ssid_len, uint8_t channel); static int8_t wifiSetApPassphrase(const char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len, uint8_t channel); + static int8_t wifiSetEnterprise(uint8_t eapType, + const char* ssid, uint8_t ssid_len, + const char *username, const uint8_t username_len, + const char *password, const uint8_t password_len, + const char *identity, const uint8_t identity_len, + const char* ca_cert, uint16_t ca_cert_len); + static int16_t ping(uint32_t ipAddress, uint8_t ttl); diff --git a/src/utility/wifi_spi.h b/src/utility/wifi_spi.h index 7402e434..e2d6a005 100644 --- a/src/utility/wifi_spi.h +++ b/src/utility/wifi_spi.h @@ -92,6 +92,7 @@ enum { GET_SOCKET_CMD = 0x3F, // All command with DATA_FLAG 0x40 send a 16bit Len + SET_ENT_CMD = 0x40, SEND_DATA_TCP_CMD = 0x44, GET_DATABUF_TCP_CMD = 0x45, @@ -126,6 +127,7 @@ enum numParams{ PARAM_NUMS_3, PARAM_NUMS_4, PARAM_NUMS_5, + PARAM_NUMS_6, MAX_PARAM_NUMS };