RoboidControl-cpp/Arduino/ArduinoUtils.cpp
2025-03-07 11:47:45 +01:00

218 lines
5.7 KiB
C++

#include "ArduinoUtils.h"
#if defined(ARDUINO)
#include <Arduino.h>
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266httpUpdate.h>
#include <HTTPClient.h>
#elif defined(ESP32)
#include <HTTPClient.h>
#include <HTTPUpdate.h>
#include <WiFi.h>
#elif defined(UNO_R4)
#include <WiFi.h>
#endif
const char* hotspotSSID = "Roboid";
const char* hotspotPassword = "alchemy7000";
#if ESP32
// Flash storage
#include "Preferences.h"
#define PREFERENCES_NAMESPACE "roboidControl"
Preferences wifiPreferences;
#define STORAGE_KEY_WIFI "rc/wifi"
struct WifiCredentials {
char ssid[32] = "\0";
char password[32] = "\0";
} credentials;
#define STORAGE_KEY_NSS "rc/nss"
struct NssServer {
char ipAddress[16] = "127.0.0.1\0";
unsigned short port = 7681;
} nssServer;
#endif
bool StartWifi(const char* wifiSsid,
const char* wifiPassword,
bool hotspotFallback) {
#if !defined(HAS_WIFI)
return false;
#else
#if defined(UNO_R4) || defined(ARDUINO_ARCH_RP2040)
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("WiFi not present, WiFiSync is disabled");
return false;
}
#endif
#if ESP32
printf("Connecting to WiFi %s\n", wifiSsid);
#else
Serial.print("Connecting to WiFi ");
Serial.println(wifiSsid);
#endif
// Connect to Wifi
WiFi.begin(wifiSsid, wifiPassword);
uint32_t notConnectedCounter = 0;
bool connected = false;
bool hotSpotEnabled = false;
while (WiFi.status() != WL_CONNECTED && !hotSpotEnabled) {
#if ESP32
printf(".");
#else
Serial.print(".");
#endif
delay(500);
notConnectedCounter++;
if (notConnectedCounter > 20 && hotspotFallback) {
#if ESP32
printf("\nCould not connect to home network.\n");
#else
Serial.println();
Serial.println("Could not connect to home network");
#endif
WiFi.disconnect();
if (hotspotFallback) {
#if ESP32
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_AP);
IPAddress wifiMyIp(192, 168, 4, 1);
WiFi.softAPConfig(wifiMyIp, wifiMyIp, IPAddress(255, 255, 255, 0));
WiFi.softAP(hotspotSSID, hotspotPassword);
#elif UNO_R4 || ARDUINO_ARCH_RP2040
WiFi.beginAP(hotspotSSID);
#endif
printf("Setup WiFi hotspot...\n");
// printf("ssid = %s, password = %s\n", hotspotSSID, hotspotPassword);
#if ARDUINO_ARCH_RP2040
String ipAddress = WiFi.localIP().toString();
#else
String ipAddress = WiFi.softAPIP().toString();
#endif
char buf[20];
ipAddress.toCharArray(buf, 20);
printf("IP address: %s\n", buf);
hotSpotEnabled = true;
}
}
}
connected = notConnectedCounter <= 20;
if (connected) {
char buf[20];
String ipAddress = WiFi.localIP().toString();
ipAddress.toCharArray(buf, 20);
#if ESP32 || ESP8266
printf("\nWifi connected, IP address: %s\n", buf);
#else
Serial.println();
Serial.println("Wifi connected");
#endif
#if ESP32
printf("Checking credentials in flash\n");
wifiPreferences.begin(PREFERENCES_NAMESPACE);
wifiPreferences.getBytes(STORAGE_KEY_WIFI, &credentials,
sizeof(credentials));
if (strcmp(wifiSsid, credentials.ssid) != 0 ||
strcmp(wifiPassword, credentials.password) != 0) {
printf("Updating credentials in flash...");
const int ssidLen = strlen(wifiSsid);
if (ssidLen < 32) {
memcpy(credentials.ssid, wifiSsid, ssidLen);
credentials.ssid[ssidLen] = '\0';
}
const int pwdLen = strlen(wifiPassword);
if (pwdLen < 32) {
memcpy(credentials.password, wifiPassword, pwdLen);
credentials.password[pwdLen] = '\0';
}
wifiPreferences.putBytes(STORAGE_KEY_WIFI, &credentials,
sizeof(credentials));
printf(" completed.\n");
}
wifiPreferences.end();
#endif
}
return (!hotSpotEnabled);
#endif
}
void CheckFirmware(String url, String FIRMWARE_NAME, int FIRMWARE_VERSION) {
#if !defined(HAS_WIFI)
return;
#else
#if defined(UNO_R4) // Uno R4 Wifi does not support this kind of firmware
// update (as far as I know)
return;
#else
Serial.println("Checking for firmware updates.");
WiFiClient client;
HTTPClient httpClient;
String versionURL = url + FIRMWARE_NAME + ".version";
httpClient.begin(client, versionURL);
int httpCode = httpClient.GET();
if (httpCode == 200) {
String newFWVersion = httpClient.getString();
Serial.print("Current firmware version: ");
Serial.println(FIRMWARE_VERSION);
Serial.print("Available firmware version: ");
Serial.println(newFWVersion);
int newVersion = newFWVersion.toInt();
if (newVersion > FIRMWARE_VERSION) {
Serial.println("Preparing to update firmware.");
String firmwareURL = url + FIRMWARE_NAME + ".bin";
#if defined(ESP32)
t_httpUpdate_return ret = httpUpdate.update(client, firmwareURL);
#else
t_httpUpdate_return ret = ESPhttpUpdate.update(client, firmwareURL);
#endif
switch (ret) {
case HTTP_UPDATE_FAILED:
#if defined(ESP32)
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s",
httpUpdate.getLastError(),
httpUpdate.getLastErrorString().c_str());
#else
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s",
ESPhttpUpdate.getLastError(),
ESPhttpUpdate.getLastErrorString().c_str());
#endif
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
break;
}
} else {
Serial.println("No Firmware update necessary.");
}
} else {
Serial.print("Http Error: ");
Serial.println(httpCode);
}
#endif
#endif
}
#endif