mirror of
https://github.com/justcallmekoko/ESP32Marauder.git
synced 2026-07-28 14:47:16 -07:00
+188
-189
File diff suppressed because it is too large
Load Diff
@@ -218,7 +218,7 @@ class MenuFunctions
|
||||
void drawGraph(int16_t *values);
|
||||
void drawGraphSmall(uint8_t *values);
|
||||
void renderGraphUI(uint8_t scan_mode = 0);
|
||||
void addNodes(Menu* menu, const char* name, uint8_t color, Menu* child, int place, std::function<void()> callable, bool selected = false);
|
||||
void addNodes(Menu* menu, const char* name, uint8_t color, int place, std::function<void()> callable, bool selected = false);
|
||||
void battery(bool initial = false);
|
||||
void battery2(bool initial = false);
|
||||
const char* callSetting(const char* key);
|
||||
|
||||
@@ -9867,6 +9867,282 @@ uint16_t WiFiScan::rssiToColor(int8_t rssi) {
|
||||
return TFT_RED;
|
||||
}
|
||||
|
||||
// Upload one log file to WDG Wars.
|
||||
// Mirrors backendUpload() but uses X-API-Key auth and wdgwars.pl endpoint.
|
||||
/*bool WiFiScan::wdgwarsUpload(String filePath) {
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("WDG Upload...", true);
|
||||
delay(100);
|
||||
|
||||
if (!SD.exists(filePath)) {
|
||||
//display.drawCenteredText(filePath + " not found", true);
|
||||
Serial.println("[WDG] File not found: " + filePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
String apiKey = settings_obj.loadSetting<String>(WDG_KEY_NAME);
|
||||
if (apiKey.isEmpty()) {
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("No WDG API key", true);
|
||||
Serial.println("[WDG] No WDG Wars API key configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
File fileToUpload = SD.open(filePath);
|
||||
if (!fileToUpload) {
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("Could not open file", true);
|
||||
Serial.println("[WDG] Could not open: " + filePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build multipart body
|
||||
String boundary = "----ESP32BOUNDARY";
|
||||
String part1 = "--" + boundary + "\r\n";
|
||||
part1 += "Content-Disposition: form-data; name=\"file\"; filename=\"" +
|
||||
filePath + "\"\r\n";
|
||||
part1 += "Content-Type: application/octet-stream\r\n\r\n";
|
||||
String part2 = "\r\n--" + boundary + "--\r\n";
|
||||
int totalLength = part1.length() + fileToUpload.size() + part2.length();
|
||||
|
||||
Serial.println("[WDG] File size: " + String(fileToUpload.size()));
|
||||
Serial.println("[WDG] Total length: " + String(totalLength));
|
||||
|
||||
client->setInsecure();
|
||||
if (!client->connect("wdgwars.pl", 443)) {
|
||||
fileToUpload.close();
|
||||
client->stop();
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("WDG connect fail", true);
|
||||
Serial.println("[WDG] Failed to connect to wdgwars.pl");
|
||||
return false;
|
||||
}
|
||||
|
||||
// HTTP request
|
||||
client->println("POST /api/v2/upload-csv HTTP/1.1");
|
||||
client->println("Host: wdgwars.pl");
|
||||
client->println("User-Agent: ESP32Uploader/1.0");
|
||||
client->println("Accept: application/json");
|
||||
client->println("X-API-Key: " + apiKey);
|
||||
client->println("Content-Type: multipart/form-data; boundary=" + boundary);
|
||||
client->print("Content-Length: ");
|
||||
client->println(totalLength);
|
||||
client->println();
|
||||
|
||||
// Send body
|
||||
client->print(part1);
|
||||
|
||||
const size_t CHUNK = 4096;
|
||||
uint8_t buf[CHUNK];
|
||||
size_t totalSent = 0;
|
||||
uint8_t pct = 0;
|
||||
String pctStr;
|
||||
|
||||
while (fileToUpload.available()) {
|
||||
size_t n = fileToUpload.read(buf, CHUNK);
|
||||
totalSent += n;
|
||||
client->write(buf, n);
|
||||
pct = (totalSent * 100) / fileToUpload.size();
|
||||
//display.tft->drawRect(0, (TFT_HEIGHT / 3) * 2, TFT_WIDTH, TFT_HEIGHT - (TFT_HEIGHT / 3) * 2, ST77XX_BLACK);
|
||||
//display.tft->setCursor(0, (TFT_HEIGHT / 3) * 2);
|
||||
pctStr = String(pct) + "%";
|
||||
//display.drawCenteredText(pctStr, false);
|
||||
}
|
||||
|
||||
client->print(part2);
|
||||
fileToUpload.close();
|
||||
|
||||
Serial.println("[WDG] Bytes sent: " + String(totalSent));
|
||||
|
||||
// Read response
|
||||
String response;
|
||||
unsigned long t = millis();
|
||||
while (millis() - t < 5000) {
|
||||
while (client->available()) {
|
||||
char c = client->read();
|
||||
response += c;
|
||||
}
|
||||
if (!client->connected() && !client->available())
|
||||
break;
|
||||
}
|
||||
client->stop();
|
||||
|
||||
// Capture first 200 chars of response for log viewer
|
||||
String respTrunc = response.length() > 200 ? response.substring(0, 200) : response;
|
||||
Serial.println("[WDG] Response: " + respTrunc);
|
||||
|
||||
// WDG Wars returns 200 on success
|
||||
bool ok = response.indexOf("202 Accepted") >= 0 ||
|
||||
response.indexOf("\"ok\":true") >= 0;
|
||||
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText(ok ? "WDG OK" : "WDG Failed", true);
|
||||
delay(1000);
|
||||
|
||||
return ok;
|
||||
}*/
|
||||
|
||||
// Upload one log file to Wigle
|
||||
/*bool WiFiScan::wigleUpload(String filePath) {
|
||||
//server.begin();
|
||||
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("Wigle Upload...", true);
|
||||
|
||||
delay(100);
|
||||
|
||||
if (!SD.exists(filePath)) {
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText(filePath + " not found", true);
|
||||
Serial.println("File does not exist: " + filePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
File fileToUpload = SD.open(filePath);
|
||||
if (!fileToUpload) {
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("Could not open file", true);
|
||||
Serial.println("Could not open file: " + filePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load credentials
|
||||
String username = settings_obj.loadSetting<String>("wu");
|
||||
String token = settings_obj.loadSetting<String>("wt");
|
||||
if (username.isEmpty() || token.isEmpty()) {
|
||||
fileToUpload.close();
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("No wigle creds", true);
|
||||
Serial.println("Missing wigle credentials");
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.println("Username: " + username);
|
||||
Serial.println("Token: " + token);
|
||||
|
||||
String boundary = "----ESP32BOUNDARY";
|
||||
String contentType = "multipart/form-data; boundary=" + boundary;
|
||||
|
||||
// Build parts
|
||||
String part1 = "--" + boundary + "\r\n";
|
||||
part1 += "Content-Disposition: form-data; name=\"file\"; filename=\"" + filePath + "\"\r\n";
|
||||
part1 += "Content-Type: application/octet-stream\r\n\r\n";
|
||||
|
||||
String part2 = "\r\n--" + boundary + "\r\n";
|
||||
part2 += "Content-Disposition: form-data; name=\"donate\"\r\n\r\non\r\n";
|
||||
|
||||
String part3 = "--" + boundary + "--\r\n";
|
||||
|
||||
int totalLength = part1.length() + fileToUpload.size() + part2.length() + part3.length();
|
||||
|
||||
Serial.println("part1.length(): " + String(part1.length()));
|
||||
Serial.println("fileToUpload.size(): " + String(fileToUpload.size()));
|
||||
Serial.println("part2.length(): " + String(part2.length()));
|
||||
Serial.println("part3.length(): " + String(part3.length()));
|
||||
Serial.println("Total Content-Length: " + String(totalLength));
|
||||
|
||||
Serial.print("File size: ");
|
||||
Serial.println(fileToUpload.size());
|
||||
|
||||
// Connect manually via WiFiClientSecure
|
||||
//WiFiClientSecure *client = new WiFiClientSecure();
|
||||
//client.stop();
|
||||
client->setInsecure();
|
||||
|
||||
if (!client->connect("api.wigle.net", 443)) {
|
||||
fileToUpload.close();
|
||||
//delete client;
|
||||
client->stop();
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText("Could not connect", true);
|
||||
Serial.println("Failed to connected to api.wigle.net");
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.println("Connected");
|
||||
|
||||
// Compose headers
|
||||
String auth = base64Encode(username + ":" + token);
|
||||
|
||||
Serial.println("Finished encoding");
|
||||
|
||||
client->println("POST /api/v2/file/upload HTTP/1.1");
|
||||
client->println("Host: api.wigle.net");
|
||||
client->println("User-Agent: ESP32Uploader/1.0");
|
||||
client->println("Accept: application/json");
|
||||
client->println("Authorization: Basic " + auth);
|
||||
client->println("Content-Type: " + contentType);
|
||||
client->print("Content-Length: ");
|
||||
client->println(totalLength);
|
||||
client->println();
|
||||
delay(100);
|
||||
|
||||
Serial.println("Finished sending header");
|
||||
|
||||
// Send body
|
||||
client->print(part1);
|
||||
const size_t BUFFER_SIZE = 4096; // 1KB at a time
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
|
||||
Serial.println("Finished sending part1");
|
||||
|
||||
uint8_t percent_sent = 0;
|
||||
|
||||
String display_percent = "";
|
||||
|
||||
size_t totalBytesSent = 0;
|
||||
while (fileToUpload.available()) {
|
||||
size_t bytesRead = fileToUpload.read(buffer, BUFFER_SIZE);
|
||||
totalBytesSent += bytesRead;
|
||||
Serial.print("Writing ");
|
||||
Serial.print(totalBytesSent);
|
||||
Serial.println(" bytes...");
|
||||
percent_sent = (totalBytesSent * 100) / fileToUpload.size();
|
||||
//display.tft->drawRect(0, (TFT_HEIGHT / 3) * 2, TFT_WIDTH, TFT_HEIGHT, ST77XX_BLACK);
|
||||
//display.tft->setCursor(0, (TFT_HEIGHT / 3) * 2);
|
||||
display_percent = (String)percent_sent + "%";
|
||||
//display.drawCenteredText(display_percent, false);
|
||||
client->write(buffer, bytesRead);
|
||||
}
|
||||
|
||||
Serial.println("Uploaded file bytes: " + String(totalBytesSent));
|
||||
|
||||
client->print(part2);
|
||||
client->print(part3);
|
||||
|
||||
Serial.println("Finished sending part2 and part3");
|
||||
|
||||
fileToUpload.close();
|
||||
|
||||
|
||||
// Read response
|
||||
String response;
|
||||
unsigned long timeout = millis();
|
||||
while (millis() - timeout < 5000) {
|
||||
while (client->available()) {
|
||||
char c = client->read();
|
||||
response += c;
|
||||
}
|
||||
}
|
||||
|
||||
if (millis() - timeout > 5000)
|
||||
Serial.println("Timeout reached");
|
||||
if (!client->connected())
|
||||
Serial.println("Client disconnected");
|
||||
|
||||
client->stop();
|
||||
|
||||
String respTrunc = response.length() > 200 ? response.substring(0, 200) : response;
|
||||
Serial.println("[WIGLE] Response: " + respTrunc);
|
||||
|
||||
bool ok = response.indexOf("200 OK") >= 0;
|
||||
|
||||
//display.clearScreen();
|
||||
//display.drawCenteredText(ok ? "WIGLE OK" : "WIGLE Failed", true);
|
||||
|
||||
return ok;
|
||||
}*/
|
||||
|
||||
// Function for updating scan status
|
||||
void WiFiScan::main(uint32_t currentTime)
|
||||
{
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
#include "LedInterface.h"
|
||||
#endif
|
||||
|
||||
//#include <WiFiClientSecure.h>
|
||||
//#include "mbedtls/sha256.h"
|
||||
|
||||
#define bad_list_length 3
|
||||
|
||||
#define OTA_UPDATE 100
|
||||
@@ -300,6 +303,8 @@ class WiFiScan
|
||||
// Settings
|
||||
uint mac_history_cursor = 0;
|
||||
uint8_t channel_hop_delay = 1;
|
||||
|
||||
//WiFiClientSecure *client = new WiFiClientSecure();
|
||||
|
||||
int x_pos; //position along the graph x axis
|
||||
float y_pos_x; //current graph y axis position of X value
|
||||
@@ -585,6 +590,9 @@ class WiFiScan
|
||||
NimBLEAdvertisementData GetUniversalAdvertisementData(EBLEPayloadType type);
|
||||
#endif
|
||||
|
||||
bool wigleUpload(String filePath);
|
||||
bool wdgwarsUpload(String filePath);
|
||||
|
||||
void throwThatShitInACircle();
|
||||
void displayTargetFilter();
|
||||
void displayTransmitRate();
|
||||
|
||||
@@ -2711,6 +2711,11 @@
|
||||
#undef HAS_MAX1704X
|
||||
#undef HAS_AXP192
|
||||
|
||||
#elif defined(HAS_IP5306)
|
||||
#undef HAS_AXP2101
|
||||
#undef HAS_MAX1704X
|
||||
#undef HAS_AXP192
|
||||
|
||||
#elif defined(HAS_AXP192)
|
||||
#undef HAS_AXP2101
|
||||
#undef HAS_IP5306
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
extern Display display_obj;
|
||||
#endif
|
||||
|
||||
#define WDG_KEY_NAME "wdg_key" // WDG Wars API key (String)
|
||||
|
||||
class Settings {
|
||||
|
||||
private:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "configs.h"
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
#include "mbedtls/base64.h"
|
||||
|
||||
struct mac_addr {
|
||||
unsigned char bytes[6];
|
||||
@@ -256,4 +257,12 @@ inline uint16_t getNextPort(uint16_t port) {
|
||||
return port + 1;
|
||||
}
|
||||
|
||||
String base64Encode(const String& input) {
|
||||
size_t outputLen;
|
||||
unsigned char output[256];
|
||||
mbedtls_base64_encode(output, sizeof(output), &outputLen,
|
||||
(const unsigned char*)input.c_str(), input.length());
|
||||
return String((char*)output).substring(0, outputLen);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$configsPath = Join-Path $repoRoot "esp32_marauder/configs.h"
|
||||
$configs = Get-Content -LiteralPath $configsPath -Raw
|
||||
|
||||
function Assert-Match {
|
||||
param(
|
||||
[string]$Text,
|
||||
[string]$Pattern,
|
||||
[string]$Message
|
||||
)
|
||||
|
||||
if ($Text -notmatch $Pattern) {
|
||||
throw $Message
|
||||
}
|
||||
}
|
||||
|
||||
function Get-MatchOrFail {
|
||||
param(
|
||||
[string]$Text,
|
||||
[string]$Pattern,
|
||||
[string]$Message
|
||||
)
|
||||
|
||||
$match = [regex]::Match($Text, $Pattern, [System.Text.RegularExpressions.RegexOptions]::Singleline)
|
||||
|
||||
if (-not $match.Success) {
|
||||
throw $Message
|
||||
}
|
||||
|
||||
return $match
|
||||
}
|
||||
|
||||
Assert-Match `
|
||||
-Text $configs `
|
||||
-Pattern "(?s)#if defined\(MARAUDER_V6\) \|\| defined\(MARAUDER_V6_1\).*?#define HAS_BATTERY.*?#define HAS_IP5306" `
|
||||
-Message "MARAUDER_V6/MARAUDER_V6_1 must keep IP5306 battery support enabled."
|
||||
|
||||
$cleanupMatch = Get-MatchOrFail `
|
||||
-Text $configs `
|
||||
-Pattern "(?s)// If we know what we have, we can delete what we're not using(?<cleanup>.*?)#endif\s+// HAS_BATTERY" `
|
||||
-Message "Could not find battery driver cleanup section."
|
||||
|
||||
$cleanup = $cleanupMatch.Groups["cleanup"].Value
|
||||
|
||||
$ip5306Match = Get-MatchOrFail `
|
||||
-Text $cleanup `
|
||||
-Pattern "(?s)#elif defined\(HAS_IP5306\)(?<ip5306Branch>.*?)(?=\r?\n\s*#elif|\r?\n\s*#else|\r?\n\s*#endif)" `
|
||||
-Message "HAS_IP5306 must have an explicit cleanup branch before the generic fallback."
|
||||
|
||||
$ip5306Branch = $ip5306Match.Groups["ip5306Branch"].Value
|
||||
|
||||
Assert-Match `
|
||||
-Text $ip5306Branch `
|
||||
-Pattern "#undef HAS_AXP2101" `
|
||||
-Message "HAS_IP5306 cleanup must disable HAS_AXP2101."
|
||||
|
||||
Assert-Match `
|
||||
-Text $ip5306Branch `
|
||||
-Pattern "#undef HAS_MAX1704X" `
|
||||
-Message "HAS_IP5306 cleanup must disable HAS_MAX1704X."
|
||||
|
||||
Assert-Match `
|
||||
-Text $ip5306Branch `
|
||||
-Pattern "#undef HAS_AXP192" `
|
||||
-Message "HAS_IP5306 cleanup must disable HAS_AXP192."
|
||||
|
||||
if ($ip5306Branch -match "#undef HAS_IP5306") {
|
||||
throw "HAS_IP5306 cleanup must preserve HAS_IP5306 for v6/v6.1 battery support."
|
||||
}
|
||||
|
||||
Write-Host "Battery driver macro checks passed."
|
||||
Reference in New Issue
Block a user