diff --git a/esp32-cam-webserver.ino b/esp32-cam-webserver.ino index 1ea9488..023f7a1 100644 --- a/esp32-cam-webserver.ino +++ b/esp32-cam-webserver.ino @@ -1,6 +1,7 @@ #include "esp_camera.h" #include #include +#include "src/parsebytes.h" /* This sketch is a extension/expansion/reork of the 'official' ESP32 Camera example * sketch from Expressif: @@ -30,12 +31,13 @@ // Primary config, or defaults. #if __has_include("myconfig.h") + struct station { const char ssid[65]; const char password[65]; const bool dhcp;}; // do no edit #include "myconfig.h" #else #warning "Using Defaults: Copy myconfig.sample.h to myconfig.h and edit that to use your own settings" #define WIFI_AP_ENABLE #define CAMERA_MODEL_AI_THINKER - struct station { const char ssid[64]; const char password[64]; const bool dhcp;} + struct station { const char ssid[65]; const char password[65]; const bool dhcp;} stationList[] = {{"ESP32-CAM-CONNECT","InsecurePassword", true}}; #endif @@ -211,13 +213,14 @@ void WifiSetup() { Serial.print("None"); } Serial.println(); - byte mac[6]; + byte mac[6] = {0,0,0,0,0,0}; WiFi.macAddress(mac); Serial.printf("MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); int bestStation = -1; long bestRSSI = -1024; - char bestBSSID[] = "00:00:00:00:00:00"; + char bestSSID[65] = ""; + uint8_t bestBSSID[6]; if (stationCount > firstStation) { // We have a list to scan Serial.printf("Scanning local Wifi Networks\n"); @@ -232,12 +235,15 @@ void WifiSetup() { Serial.printf("%3i : [%s] %s (%i)", i + 1, thisBSSID.c_str(), thisSSID.c_str(), thisRSSI); // Scan our list of known external stations for (int sta = firstStation; sta < stationCount; sta++) { - if (strcmp(stationList[sta].ssid, thisSSID.c_str()) == 0) { + if ((strcmp(stationList[sta].ssid, thisSSID.c_str()) == 0) || + (strcmp(stationList[sta].ssid, thisBSSID.c_str()) == 0)) { Serial.print(" - Known!"); // Chose the strongest RSSI seen if (thisRSSI > bestRSSI) { bestStation = sta; - strncpy(bestBSSID,thisBSSID.c_str(),17); + strncpy(bestSSID, thisSSID.c_str(), 64); + // Convert char bssid[] to a byte array + parseBytes(thisBSSID.c_str(), ':', bestBSSID, 6, 16); bestRSSI = thisRSSI; } } @@ -262,7 +268,10 @@ void WifiSetup() { Serial.println("AccessPoint mode selected in config"); } } else { - Serial.printf("Connecting to Wifi Network %d: [%s] %s \n", bestStation, bestBSSID, stationList[bestStation].ssid); + Serial.printf("Connecting to Wifi Network %d: [%02X:%02X:%02X:%02X:%02X:%02X] %s \n", + bestStation, bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], + bestBSSID[4], bestBSSID[5], bestSSID); + // Apply static settings if necesscary if (stationList[bestStation].dhcp == false) { #if defined(ST_IP) Serial.println("Applying static IP settings"); @@ -292,8 +301,8 @@ void WifiSetup() { WiFi.setHostname(HOSTNAME); #endif - // Initiate network connection request - WiFi.begin(stationList[bestStation].ssid, stationList[bestStation].password); + // Initiate network connection request (3rd argument, channel = 0 is 'auto') + WiFi.begin(bestSSID, stationList[bestStation].password, 0, bestBSSID); // Wait to connect, or timeout unsigned long start = millis(); diff --git a/myconfig.sample.h b/myconfig.sample.h index 88426fa..fed733a 100644 --- a/myconfig.sample.h +++ b/myconfig.sample.h @@ -5,39 +5,38 @@ */ -/* Give the camera a name for the web interface - * note: this is not the network hostname */ +/* Give the camera a name for the web interface */ #define CAM_NAME "ESP32 camera server" /* - * WiFi Settings - * - * Note the the use of commas as seperators in IP addresses! - - * Extend the stationList[] below with additional SSID+Password pairs. - * The first block defines /what/ the structure holds - * The second block is where our list of ssid/passwords live - -struct station { - const char ssid[64]; // - Do Not - const char password[64]; // - Edit - const bool dhcp; // - This -} station stationList[] = {{"ssid1", "pass1", true}, - {"ssid2", "pass2", true}, - {"ssid3", "pass3", false}}; - - * The first entry (ssid1, above) in the stationList[] is special, if WIFI_AP_ENABLE has been uncommented - * it will be used for the AccessPoint ssid and password. - * - * The 'dhcp' setting controls whether the station uses DHCP or static IP settings (if in doubt leave 'true') - * Note the use of nested braces '{' and '}' to group each entry, and commas ',' to seperate them. + * WiFi Settings + * + * For the simplest connection to an existing network + * just replace your ssid and password in the line below. */ -struct station { - const char ssid[64]; // Do Not - const char password[64]; // Edit These - const bool dhcp; // Lines.. -} stationList[] = {{"my_ssid","my_password", true}}; + +struct station stationList[] = {{"my_ssid","my_password", true}}; + +/* + * You can extend the stationList[] above with additional SSID+Password pairs + +struct station stationList[] = {{"ssid1", "pass1", true}, + {"ssid2", "pass2", true}, + {"ssid3", "pass3", false}}; + + * Note the use of nested braces '{' and '}' to group each entry, and commas ',' to seperate them. + * + * The first entry (ssid1, above) in the stationList is special, if WIFI_AP_ENABLE has been uncommented (below) + * it will be used for the AccessPoint ssid and password. See the comments there for more. + * + * The 'dhcp' setting controls whether the station uses DHCP or static IP settings; if in doubt leave 'true' + * + * You can also use a BSSID (eg: "2F:67:94:F5:BB:6A", a colon seperated mac address string) in place of + * the ssid to force connections to specific networks even when the ssid's collide, + */ + +/* Extended WiFi Settings */ /* * Hostname. Optional, uncomment and set if desired diff --git a/src/parsebytes.cpp b/src/parsebytes.cpp new file mode 100644 index 0000000..26709c4 --- /dev/null +++ b/src/parsebytes.cpp @@ -0,0 +1,16 @@ +/* + * From https://stackoverflow.com/a/35236734 +*/ + +#include + +void parseBytes(const char* str, char sep, byte* bytes, int maxBytes, int base) { + for (int i = 0; i < maxBytes; i++) { + bytes[i] = strtoul(str, NULL, base); // Convert byte + str = strchr(str, sep); // Find next separator + if (str == NULL || *str == '\0') { + break; // No more separators, exit + } + str++; // Point to next character after separator + } +} diff --git a/src/parsebytes.h b/src/parsebytes.h new file mode 100644 index 0000000..9168990 --- /dev/null +++ b/src/parsebytes.h @@ -0,0 +1 @@ +extern void parseBytes(const char* str, char sep, byte* bytes, int maxBytes, int base);