|
|
|
|
@ -10,6 +10,7 @@
|
|
|
|
|
#include <Sonde.h>
|
|
|
|
|
#include <Scanner.h>
|
|
|
|
|
#include <aprs.h>
|
|
|
|
|
#include "version.h"
|
|
|
|
|
|
|
|
|
|
// UNCOMMENT one of the constructor lines below
|
|
|
|
|
U8X8_SSD1306_128X64_NONAME_SW_I2C *u8x8 = NULL; // initialize later after reading config file
|
|
|
|
|
@ -32,6 +33,9 @@ int ledPin = 1;
|
|
|
|
|
// Stores LED state
|
|
|
|
|
String ledState;
|
|
|
|
|
|
|
|
|
|
// timestamp when spectrum display was activated
|
|
|
|
|
static unsigned long specTimer;
|
|
|
|
|
|
|
|
|
|
// Replaces placeholder with LED state value
|
|
|
|
|
String processor(const String& var) {
|
|
|
|
|
Serial.println(var);
|
|
|
|
|
@ -45,6 +49,12 @@ String processor(const String& var){
|
|
|
|
|
Serial.print(ledState);
|
|
|
|
|
return ledState;
|
|
|
|
|
}
|
|
|
|
|
if (var == "VERSION_NAME") {
|
|
|
|
|
return String(version_name);
|
|
|
|
|
}
|
|
|
|
|
if (var == "VERSION_ID") {
|
|
|
|
|
return String(version_id);
|
|
|
|
|
}
|
|
|
|
|
return String();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -54,7 +64,9 @@ const String sondeTypeSelect(int activeType) {
|
|
|
|
|
sts += "<option value=\"";
|
|
|
|
|
sts += sondeTypeStr[i];
|
|
|
|
|
sts += "\"";
|
|
|
|
|
if(activeType==i) { sts += " selected"; }
|
|
|
|
|
if (activeType == i) {
|
|
|
|
|
sts += " selected";
|
|
|
|
|
}
|
|
|
|
|
sts += ">";
|
|
|
|
|
sts += sondeTypeStr[i];
|
|
|
|
|
sts += "</option>";
|
|
|
|
|
@ -66,7 +78,8 @@ const String sondeTypeSelect(int activeType) {
|
|
|
|
|
//trying to work around
|
|
|
|
|
//"assertion "heap != NULL && "free() target pointer is outside heap areas"" failed:"
|
|
|
|
|
// which happens if request->send is called in createQRGForm!?!??
|
|
|
|
|
char message[10240];
|
|
|
|
|
char message[10240 * 4]; //needs to be large enough for all forms (not checked in code)
|
|
|
|
|
// QRG form is currently about 24kb with 100 entries
|
|
|
|
|
|
|
|
|
|
///////////////////////// Functions for Reading / Writing QRG list from/to qrg.txt
|
|
|
|
|
|
|
|
|
|
@ -77,10 +90,12 @@ void setupChannelList() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int i = 0;
|
|
|
|
|
char launchsite[17];
|
|
|
|
|
sonde.clearSonde();
|
|
|
|
|
Serial.println("Reading channel config:");
|
|
|
|
|
while (file.available()) {
|
|
|
|
|
String line = file.readStringUntil('\n');
|
|
|
|
|
String sitename;
|
|
|
|
|
if (!file.available()) break;
|
|
|
|
|
if (line[0] == '#') continue;
|
|
|
|
|
char *space = strchr(line.c_str(), ' ');
|
|
|
|
|
@ -88,29 +103,48 @@ void setupChannelList() {
|
|
|
|
|
*space = 0;
|
|
|
|
|
float freq = atof(line.c_str());
|
|
|
|
|
SondeType type;
|
|
|
|
|
if(space[1]=='4') { type=STYPE_RS41; }
|
|
|
|
|
else if (space[1]=='9') { type=STYPE_DFM09; }
|
|
|
|
|
else if (space[1]=='6') { type=STYPE_DFM06; }
|
|
|
|
|
if (space[1] == '4') {
|
|
|
|
|
type = STYPE_RS41;
|
|
|
|
|
}
|
|
|
|
|
else if (space[1] == '9') {
|
|
|
|
|
type = STYPE_DFM09;
|
|
|
|
|
}
|
|
|
|
|
else if (space[1] == '6') {
|
|
|
|
|
type = STYPE_DFM06;
|
|
|
|
|
}
|
|
|
|
|
else continue;
|
|
|
|
|
int active = space[3] == '+' ? 1 : 0;
|
|
|
|
|
char *launchsite = strchr(line.c_str(), ' ');
|
|
|
|
|
Serial.printf("Add %f - type %d (on/off: %d)- Site: \n",freq,type,active,launchsite);
|
|
|
|
|
if (space[4] == ' ') {
|
|
|
|
|
sitename = line.substring(12) + " "; // Don't change start of substr(12) !!!!
|
|
|
|
|
int str_len = sitename.length() + 1;
|
|
|
|
|
sitename.toCharArray(launchsite, 17);
|
|
|
|
|
|
|
|
|
|
if (sonde.config.debug == 1) {
|
|
|
|
|
Serial.printf("Add %f - sondetype: %d (on/off: %d) - site #%d - name: %s\n ", freq, type, active, i, launchsite);
|
|
|
|
|
//Serial.println(sitename);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sonde.addSonde(freq, type, active, launchsite);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
file.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *createQRGForm() {
|
|
|
|
|
char *ptr = message;
|
|
|
|
|
strcpy(ptr,"<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"></head><body><form action=\"qrg.html\" method=\"post\"><table><tr><th>ID</th><th>Active</th><th>Freq</th><th>Mode</th></tr>");
|
|
|
|
|
strcpy(ptr, "<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"></head><body><form action=\"qrg.html\" method=\"post\"><table><tr><th>ID</th><th>Active</th><th>Freq</th><th>Launchsite</th><th>Mode</th></tr>");
|
|
|
|
|
for (int i = 0; i < sonde.config.maxsonde; i++) {
|
|
|
|
|
String s = sondeTypeSelect(i >= sonde.nSonde ? 2 : sonde.sondeList[i].type);
|
|
|
|
|
String site = sonde.sondeList[i].launchsite;
|
|
|
|
|
sprintf(ptr + strlen(ptr), "<tr><td>%d</td><td><input name=\"A%d\" type=\"checkbox\" %s/></td>"
|
|
|
|
|
"<td><input name=\"F%d\" type=\"text\" value=\"%3.3f\"></td>"
|
|
|
|
|
"<td><input name=\"S%d\" type=\"text\" value=\"%s\"></td>"
|
|
|
|
|
"<td><select name=\"T%d\">%s</select></td>",
|
|
|
|
|
i + 1,
|
|
|
|
|
i + 1, (i < sonde.nSonde && sonde.sondeList[i].active) ? "checked" : "",
|
|
|
|
|
i + 1, i >= sonde.nSonde ? 400.000 : sonde.sondeList[i].freq,
|
|
|
|
|
i + 1, i >= sonde.nSonde ? " " : sonde.sondeList[i].launchsite,
|
|
|
|
|
i + 1, s.c_str());
|
|
|
|
|
}
|
|
|
|
|
strcat(ptr, "</table><input type=\"submit\" value=\"Update\"/></form></body></html>");
|
|
|
|
|
@ -121,8 +155,8 @@ const char *handleQRGPost(AsyncWebServerRequest *request) {
|
|
|
|
|
char label[10];
|
|
|
|
|
// parameters: a_i, f_1, t_i (active/frequency/type)
|
|
|
|
|
#if 1
|
|
|
|
|
File f = SPIFFS.open("/qrg.txt", "w");
|
|
|
|
|
if(!f) {
|
|
|
|
|
File file = SPIFFS.open("/qrg.txt", "w");
|
|
|
|
|
if (!file) {
|
|
|
|
|
Serial.println("Error while opening '/qrg.txt' for writing");
|
|
|
|
|
return "Error while opening '/qrg.txt' for writing";
|
|
|
|
|
}
|
|
|
|
|
@ -131,7 +165,8 @@ const char *handleQRGPost(AsyncWebServerRequest *request) {
|
|
|
|
|
#if 0
|
|
|
|
|
int params = request->params();
|
|
|
|
|
for (int i = 0; i < params; i++) {
|
|
|
|
|
Serial.println(request->getParam(i)->name().c_str());
|
|
|
|
|
String pname = request->getParam(i)->name();
|
|
|
|
|
Serial.println(pname.c_str());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
for (int i = 1; i <= sonde.config.maxsonde; i++) {
|
|
|
|
|
@ -139,20 +174,27 @@ const char *handleQRGPost(AsyncWebServerRequest *request) {
|
|
|
|
|
AsyncWebParameter *active = request->getParam(label, true);
|
|
|
|
|
snprintf(label, 10, "F%d", i);
|
|
|
|
|
AsyncWebParameter *freq = request->getParam(label, true);
|
|
|
|
|
snprintf(label, 10, "S%d", i);
|
|
|
|
|
AsyncWebParameter *launchsite = request->getParam(label, true);
|
|
|
|
|
if (!freq) continue;
|
|
|
|
|
snprintf(label, 10, "T%d", i);
|
|
|
|
|
AsyncWebParameter *type = request->getParam(label, true);
|
|
|
|
|
if (!type) continue;
|
|
|
|
|
const char *fstr = freq->value().c_str();
|
|
|
|
|
const char *tstr = type->value().c_str();
|
|
|
|
|
Serial.printf("Processing a=%s, f=%s, t=%s\n", active?"YES":"NO", fstr, tstr);
|
|
|
|
|
String fstring = freq->value();
|
|
|
|
|
String tstring = type->value();
|
|
|
|
|
String sstring = launchsite->value();
|
|
|
|
|
const char *fstr = fstring.c_str();
|
|
|
|
|
const char *tstr = tstring.c_str();
|
|
|
|
|
const char *sstr = sstring.c_str();
|
|
|
|
|
Serial.printf("Processing a=%s, f=%s, t=%s, site=%s\n", active ? "YES" : "NO", fstr, tstr, sstr);
|
|
|
|
|
char typech = (tstr[2] == '4' ? '4' : tstr[3]); // Ugly TODO
|
|
|
|
|
f.printf("%3.3f %c %c\n", atof(fstr), typech, active?'+':'-');
|
|
|
|
|
file.printf("%3.3f %c %c %s\n", atof(fstr), typech, active ? '+' : '-', sstr);
|
|
|
|
|
}
|
|
|
|
|
f.close();
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
Serial.println("Channel setup finished");
|
|
|
|
|
Serial.println();
|
|
|
|
|
|
|
|
|
|
delay(500);
|
|
|
|
|
setupChannelList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -161,7 +203,10 @@ const char *handleQRGPost(AsyncWebServerRequest *request) {
|
|
|
|
|
|
|
|
|
|
#define MAX_WIFI 10
|
|
|
|
|
int nNetworks;
|
|
|
|
|
struct { String id; String pw; } networks[MAX_WIFI];
|
|
|
|
|
struct {
|
|
|
|
|
String id;
|
|
|
|
|
String pw;
|
|
|
|
|
} networks[MAX_WIFI];
|
|
|
|
|
|
|
|
|
|
// FIXME: For now, we don't uspport wifi networks that contain newline or null characters
|
|
|
|
|
// ... would require a more sophisicated file format (currently one line SSID; one line Password
|
|
|
|
|
@ -182,7 +227,11 @@ void setupWifiList() {
|
|
|
|
|
}
|
|
|
|
|
nNetworks = i;
|
|
|
|
|
Serial.print(i); Serial.println(" networks in networks.txt\n");
|
|
|
|
|
for(int j=0; j<i; j++) { Serial.print(networks[j].id); Serial.print(": "); Serial.println(networks[j].pw); }
|
|
|
|
|
for (int j = 0; j < i; j++) {
|
|
|
|
|
Serial.print(networks[j].id);
|
|
|
|
|
Serial.print(": ");
|
|
|
|
|
Serial.println(networks[j].pw);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -216,7 +265,8 @@ const char *handleWIFIPost(AsyncWebServerRequest *request) {
|
|
|
|
|
#if 0
|
|
|
|
|
int params = request->params();
|
|
|
|
|
for (int i = 0; i < params; i++) {
|
|
|
|
|
Serial.println(request->getParam(i)->name().c_str());
|
|
|
|
|
String param = request->getParam(i)->name();
|
|
|
|
|
Serial.println(param.c_str());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
for (int i = 1; i <= MAX_WIFI; i++) {
|
|
|
|
|
@ -226,8 +276,10 @@ const char *handleWIFIPost(AsyncWebServerRequest *request) {
|
|
|
|
|
snprintf(label, 10, "P%d", i);
|
|
|
|
|
AsyncWebParameter *pw = request->getParam(label, true);
|
|
|
|
|
if (!pw) continue;
|
|
|
|
|
const char *sstr = ssid->value().c_str();
|
|
|
|
|
const char *pstr = pw->value().c_str();
|
|
|
|
|
String sstring = ssid->value();
|
|
|
|
|
String pstring = pw->value();
|
|
|
|
|
const char *sstr = sstring.c_str();
|
|
|
|
|
const char *pstr = pstring.c_str();
|
|
|
|
|
if (strlen(sstr) == 0) continue;
|
|
|
|
|
Serial.printf("Processing S=%s, P=%s\n", sstr, pstr);
|
|
|
|
|
f.printf("%s\n%s\n", sstr, pstr);
|
|
|
|
|
@ -279,33 +331,51 @@ void setupConfigData() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct st_configitems {
|
|
|
|
|
const char *name;
|
|
|
|
|
const char *label;
|
|
|
|
|
int type; // 0: numeric; i>0 string of length i; -1: separator; -2: type selector
|
|
|
|
|
void *data;
|
|
|
|
|
};
|
|
|
|
|
#define N_CONFIG 20
|
|
|
|
|
struct st_configitems config_list[N_CONFIG] = {
|
|
|
|
|
{"ShowSpectrum (s)", 0, &sonde.config.spectrum},
|
|
|
|
|
{"Startfreq (MHz)", 0, &sonde.config.startfreq},
|
|
|
|
|
{"Bandwidth (kHz)", 0, &sonde.config.channelbw},
|
|
|
|
|
{"---", -1, NULL},
|
|
|
|
|
{"Call", 8, sonde.config.call},
|
|
|
|
|
{"Passcode", 8, sonde.config.passcode},
|
|
|
|
|
{"---", -1, NULL},
|
|
|
|
|
{"AXUDP active", -3, &sonde.config.udpfeed.active},
|
|
|
|
|
{"AXUDP Host", 63, sonde.config.udpfeed.host},
|
|
|
|
|
{"AXUDP Port", 0, &sonde.config.udpfeed.port},
|
|
|
|
|
{"DFM ID Format", -2, &sonde.config.udpfeed.idformat},
|
|
|
|
|
{"Rate limit", 0, &sonde.config.udpfeed.highrate},
|
|
|
|
|
{"---", -1, NULL},
|
|
|
|
|
{"APRS TCP active", -3, &sonde.config.tcpfeed.active},
|
|
|
|
|
{"ARPS TCP Host", 63, sonde.config.tcpfeed.host},
|
|
|
|
|
{"APRS TCP Port", 0, &sonde.config.tcpfeed.port},
|
|
|
|
|
{"DFM ID Format", -2, &sonde.config.tcpfeed.idformat},
|
|
|
|
|
{"Rate limit", 0, &sonde.config.tcpfeed.highrate},
|
|
|
|
|
{"---", -1, NULL},
|
|
|
|
|
{"Spectrum noise floor", 0, &sonde.config.noisefloor}
|
|
|
|
|
|
|
|
|
|
struct st_configitems config_list[] = {
|
|
|
|
|
/* General config settings */
|
|
|
|
|
{"wifi", "Wifi mode (0/1/2/3)", 0, &sonde.config.wifi},
|
|
|
|
|
{"debug", "Debug mode (0/1)", 0, &sonde.config.debug},
|
|
|
|
|
{"maxsonde", "Maxsonde (requires reboot?)", 0, &sonde.config.maxsonde},
|
|
|
|
|
/* Spectrum display settings */
|
|
|
|
|
{"spectrum", "ShowSpectrum (s)", 0, &sonde.config.spectrum},
|
|
|
|
|
{"startfreq", "Startfreq (MHz)", 0, &sonde.config.startfreq},
|
|
|
|
|
{"channelbw", "Bandwidth (kHz)", 0, &sonde.config.channelbw},
|
|
|
|
|
{"timer", "Spectrum Timer", 0, &sonde.config.timer},
|
|
|
|
|
{"marker", "Spectrum MHz marker", 0, &sonde.config.marker},
|
|
|
|
|
{"noisefloor", "Sepctrum noisefloor", 0, &sonde.config.noisefloor},
|
|
|
|
|
{"---", "---", -1, NULL},
|
|
|
|
|
/* APRS settings */
|
|
|
|
|
{"call", "Call", 8, sonde.config.call},
|
|
|
|
|
{"passcode", "Passcode", 8, sonde.config.passcode},
|
|
|
|
|
{"---", "---", -1, NULL},
|
|
|
|
|
/* AXUDP settings */
|
|
|
|
|
{"axudp.active", "AXUDP active", -3, &sonde.config.udpfeed.active},
|
|
|
|
|
{"axudp.host", "AXUDP Host", 63, sonde.config.udpfeed.host},
|
|
|
|
|
{"axudp.port", "AXUDP Port", 0, &sonde.config.udpfeed.port},
|
|
|
|
|
{"axudp.idformat", "DFM ID Format", -2, &sonde.config.udpfeed.idformat},
|
|
|
|
|
{"axudp.highrate", "Rate limit", 0, &sonde.config.udpfeed.highrate},
|
|
|
|
|
{"---", "---", -1, NULL},
|
|
|
|
|
/* APRS TCP settings, current not used */
|
|
|
|
|
{"tcp.active", "APRS TCP active", -3, &sonde.config.tcpfeed.active},
|
|
|
|
|
{"tcp.host", "ARPS TCP Host", 63, sonde.config.tcpfeed.host},
|
|
|
|
|
{"tcp.port", "APRS TCP Port", 0, &sonde.config.tcpfeed.port},
|
|
|
|
|
{"tcp.idformat", "DFM ID Format", -2, &sonde.config.tcpfeed.idformat},
|
|
|
|
|
{"tcp.highrate", "Rate limit", 0, &sonde.config.tcpfeed.highrate},
|
|
|
|
|
{"---", "---", -1, NULL},
|
|
|
|
|
/* Hardware dependeing settings */
|
|
|
|
|
{"oled_sda", "OLED SDA (needs reboot)", 0, &sonde.config.oled_sda},
|
|
|
|
|
{"oled_scl", "OLED SCL (needs reboot)", 0, &sonde.config.oled_scl},
|
|
|
|
|
{"oled_rst", "OLED RST (needs reboot)", 0, &sonde.config.oled_rst},
|
|
|
|
|
{"button_pin", "Button input port (needs reboot)", 0, &sonde.config.button_pin},
|
|
|
|
|
{"led_pout", "LED output port (needs reboot)", 0, &sonde.config.led_pout},
|
|
|
|
|
};
|
|
|
|
|
const static int N_CONFIG = (sizeof(config_list) / sizeof(struct st_configitems));
|
|
|
|
|
|
|
|
|
|
void addConfigStringEntry(char *ptr, int idx, const char *label, int len, char *field) {
|
|
|
|
|
sprintf(ptr + strlen(ptr), "<tr><td>%s</td><td><input name=\"CFG%d\" type=\"text\" value=\"%s\"/></td></tr>\n",
|
|
|
|
|
@ -348,14 +418,50 @@ const char *createConfigForm() {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
strcat(ptr,"</table><input type=\"submit\" value=\"Update not yet implemented\"></input></form></body></html>");
|
|
|
|
|
strcat(ptr, "</table><input type=\"submit\" value=\"Update\"></input></form></body></html>");
|
|
|
|
|
return message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char *handleConfigPost(AsyncWebServerRequest *request) {
|
|
|
|
|
char label[10];
|
|
|
|
|
// parameters: a_i, f_1, t_i (active/frequency/type)
|
|
|
|
|
#if 1
|
|
|
|
|
File f = SPIFFS.open("/config.txt", "w");
|
|
|
|
|
if (!f) {
|
|
|
|
|
Serial.println("Error while opening '/config.txt' for writing");
|
|
|
|
|
return "Error while opening '/config.txt' for writing";
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
Serial.println("Handling post request");
|
|
|
|
|
#if 1
|
|
|
|
|
int params = request->params();
|
|
|
|
|
for (int i = 0; i < params; i++) {
|
|
|
|
|
String param = request->getParam(i)->name();
|
|
|
|
|
Serial.println(param.c_str());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
for (int i = 0; i < params; i++) {
|
|
|
|
|
String strlabel = request->getParam(i)->name();
|
|
|
|
|
const char *label = strlabel.c_str();
|
|
|
|
|
if (strncmp(label, "CFG", 3) != 0) continue;
|
|
|
|
|
int idx = atoi(label + 3);
|
|
|
|
|
Serial.printf("idx is %d\n", idx);
|
|
|
|
|
if (config_list[idx].type == -1) continue; // skip separator entries, should not happen
|
|
|
|
|
AsyncWebParameter *value = request->getParam(label, true);
|
|
|
|
|
if (!value) continue;
|
|
|
|
|
String strvalue = value->value();
|
|
|
|
|
Serial.printf("Processing %s=%s\n", config_list[idx].name, strvalue.c_str());
|
|
|
|
|
f.printf("%s=%s\n", config_list[idx].name, strvalue.c_str());
|
|
|
|
|
}
|
|
|
|
|
f.close();
|
|
|
|
|
setupConfigData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* PARAM_MESSAGE = "message";
|
|
|
|
|
void SetupAsyncServer() {
|
|
|
|
|
server.reset();
|
|
|
|
|
// Route for root / web page
|
|
|
|
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
|
|
|
|
|
request->send(SPIFFS, "/index.html", String(), false, processor);
|
|
|
|
|
@ -388,7 +494,10 @@ void SetupAsyncServer() {
|
|
|
|
|
server.on("/config.html", HTTP_GET, [](AsyncWebServerRequest * request) {
|
|
|
|
|
request->send(200, "text/html", createConfigForm());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
server.on("/config.html", HTTP_POST, [](AsyncWebServerRequest * request) {
|
|
|
|
|
handleConfigPost(request);
|
|
|
|
|
request->send(200, "text/html", createConfigForm());
|
|
|
|
|
});
|
|
|
|
|
server.on("/status.html", HTTP_GET, [](AsyncWebServerRequest * request) {
|
|
|
|
|
request->send(200, "text/html", createStatusForm());
|
|
|
|
|
});
|
|
|
|
|
@ -408,6 +517,34 @@ void SetupAsyncServer() {
|
|
|
|
|
server.begin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int fetchWifiIndex(const char *id) {
|
|
|
|
|
for (int i = 0; i < nNetworks; i++) {
|
|
|
|
|
if (strcmp(id, networks[i].id.c_str()) == 0) {
|
|
|
|
|
Serial.printf("Match for %s at %d\n", id, i);
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
Serial.printf("No match: '%s' vs '%s'\n", id, networks[i].id.c_str());
|
|
|
|
|
const char *cfgid = networks[i].id.c_str();
|
|
|
|
|
int len = strlen(cfgid);
|
|
|
|
|
if (strlen(id) > len) len = strlen(id);
|
|
|
|
|
Serial.print("SSID: ");
|
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
|
Serial.printf("%02x ", id[i]);
|
|
|
|
|
} Serial.println("");
|
|
|
|
|
Serial.print("Conf: ");
|
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
|
Serial.printf("%02x ", cfgid[i]);
|
|
|
|
|
} Serial.println("");
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *fetchWifiSSID(int i) {
|
|
|
|
|
return networks[i].id.c_str();
|
|
|
|
|
}
|
|
|
|
|
const char *fetchWifiPw(int i) {
|
|
|
|
|
return networks[i].pw.c_str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *fetchWifiPw(const char *id) {
|
|
|
|
|
for (int i = 0; i < nNetworks; i++) {
|
|
|
|
|
@ -445,8 +582,12 @@ void IRAM_ATTR buttonISR() {
|
|
|
|
|
} else { //Button up
|
|
|
|
|
unsigned int elapsed = millis() - button1.press_ts;
|
|
|
|
|
if (elapsed > 1500) {
|
|
|
|
|
if(elapsed<4000) { button1.pressed=KP_MID; }
|
|
|
|
|
else { button1.pressed=KP_LONG; }
|
|
|
|
|
if (elapsed < 4000) {
|
|
|
|
|
button1.pressed = KP_MID;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
button1.pressed = KP_LONG;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (button1.doublepress) button1.pressed = KP_DOUBLE;
|
|
|
|
|
else button1.pressed = KP_SHORT;
|
|
|
|
|
@ -470,6 +611,11 @@ void setup()
|
|
|
|
|
char buf[12];
|
|
|
|
|
// Open serial communications and wait for port to open:
|
|
|
|
|
Serial.begin(115200);
|
|
|
|
|
for (int i = 0; i < 39; i++) {
|
|
|
|
|
int v = gpio_get_level((gpio_num_t)i);
|
|
|
|
|
Serial.printf("%d:%d ", i, v);
|
|
|
|
|
}
|
|
|
|
|
Serial.println("");
|
|
|
|
|
pinMode(LORA_LED, OUTPUT);
|
|
|
|
|
|
|
|
|
|
aprs_gencrctab();
|
|
|
|
|
@ -490,9 +636,11 @@ void setup()
|
|
|
|
|
u8x8->clear();
|
|
|
|
|
|
|
|
|
|
u8x8->setFont(u8x8_font_7x14_1x2_r);
|
|
|
|
|
u8x8->drawString(1, 1, "RDZ_TTGO_SONDE");
|
|
|
|
|
u8x8->drawString(2, 3, " V0.1e");
|
|
|
|
|
u8x8->drawString(1, 5, "Mods by DL2MF");
|
|
|
|
|
u8x8->drawString(8 - strlen(version_name) / 2, 1, version_name);
|
|
|
|
|
u8x8->drawString(8 - strlen(version_id) / 2, 3, version_id);
|
|
|
|
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
|
|
|
|
u8x8->drawString(0, 5, "by Hansi, DL9RDZ");
|
|
|
|
|
u8x8->drawString(1, 6, "Mods by DL2MF");
|
|
|
|
|
delay(3000);
|
|
|
|
|
|
|
|
|
|
sonde.clearDisplay();
|
|
|
|
|
@ -501,7 +649,7 @@ void setup()
|
|
|
|
|
button1.pin = sonde.config.button_pin;
|
|
|
|
|
|
|
|
|
|
// == show initial values from config.txt ========================= //
|
|
|
|
|
if (sonde.config.debug == 1) {
|
|
|
|
|
if (sonde.config.debug == 2) {
|
|
|
|
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
|
|
|
|
u8x8->drawString(0, 0, "Config:");
|
|
|
|
|
|
|
|
|
|
@ -591,14 +739,20 @@ void setup()
|
|
|
|
|
// == setup default channel list if qrg.txt read fails =========== //
|
|
|
|
|
|
|
|
|
|
sonde.setup();
|
|
|
|
|
|
|
|
|
|
WiFi.onEvent(WiFiEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum MainState { ST_DECODER, ST_SCANNER, ST_SPECTRUM, ST_WIFISCAN };
|
|
|
|
|
|
|
|
|
|
static MainState mainState = ST_WIFISCAN;
|
|
|
|
|
static MainState mainState = ST_WIFISCAN; // ST_WIFISCAN;
|
|
|
|
|
|
|
|
|
|
void enterMode(int mode) {
|
|
|
|
|
mainState = (MainState)mode;
|
|
|
|
|
if (mainState == ST_SPECTRUM) {
|
|
|
|
|
sonde.clearDisplay();
|
|
|
|
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
|
|
|
|
specTimer = millis();
|
|
|
|
|
}
|
|
|
|
|
sonde.clearDisplay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -671,7 +825,11 @@ void loopScanner() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void loopSpectrum() {
|
|
|
|
|
int marker = 0;
|
|
|
|
|
char buf[10];
|
|
|
|
|
|
|
|
|
|
switch (getKeyPress()) {
|
|
|
|
|
case KP_SHORT: /* move selection of peak, TODO */
|
|
|
|
|
sonde.nextConfig(); // TODO: Should be set specific frequency
|
|
|
|
|
@ -684,25 +842,9 @@ void loopSpectrum() {
|
|
|
|
|
case KP_DOUBLE: /* ignore */ break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scanner.scan();
|
|
|
|
|
scanner.plotResult();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void startSpectrumDisplay() {
|
|
|
|
|
int marker=0;
|
|
|
|
|
char buf[5];
|
|
|
|
|
|
|
|
|
|
sonde.clearDisplay();
|
|
|
|
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
|
|
|
|
u8x8->drawString(0, 0, "Spectrum Scan...");
|
|
|
|
|
delay(500);
|
|
|
|
|
|
|
|
|
|
enterMode(ST_SPECTRUM);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < sonde.config.spectrum; i++) {
|
|
|
|
|
scanner.scan();
|
|
|
|
|
scanner.plotResult();
|
|
|
|
|
|
|
|
|
|
if (sonde.config.marker != 0) {
|
|
|
|
|
itoa((sonde.config.startfreq), buf, 10);
|
|
|
|
|
u8x8->drawString(0, 1, buf);
|
|
|
|
|
@ -710,17 +852,27 @@ void startSpectrumDisplay() {
|
|
|
|
|
itoa((sonde.config.startfreq + 6), buf, 10);
|
|
|
|
|
u8x8->drawString(13, 1, buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sonde.config.timer != 0) {
|
|
|
|
|
itoa((sonde.config.spectrum - i), buf, 10);
|
|
|
|
|
if (sonde.config.timer) {
|
|
|
|
|
int remaining = sonde.config.spectrum - (millis() - specTimer) / 1000;
|
|
|
|
|
itoa(remaining, buf, 10);
|
|
|
|
|
Serial.printf("timer:%d config.spectrum:%d specTimer:%ld millis:%ld remaining:%d\n", sonde.config.timer, sonde.config.spectrum, specTimer, millis(), remaining);
|
|
|
|
|
if (sonde.config.marker != 0) {
|
|
|
|
|
marker = 1;
|
|
|
|
|
}
|
|
|
|
|
u8x8->drawString(0, 1 + marker, buf);
|
|
|
|
|
u8x8->drawString(2, 1 + marker, "Sec.");
|
|
|
|
|
if (remaining <= 0) {
|
|
|
|
|
enterMode(ST_SCANNER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delay(1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void startSpectrumDisplay() {
|
|
|
|
|
sonde.clearDisplay();
|
|
|
|
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
|
|
|
|
u8x8->drawString(0, 0, "Spectrum Scan...");
|
|
|
|
|
delay(500);
|
|
|
|
|
enterMode(ST_SPECTRUM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String translateEncryptionType(wifi_auth_mode_t encryptionType) {
|
|
|
|
|
@ -740,49 +892,263 @@ String translateEncryptionType(wifi_auth_mode_t encryptionType) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//wifi event handler
|
|
|
|
|
void WiFiEvent(WiFiEvent_t event){
|
|
|
|
|
switch(event) {
|
|
|
|
|
case SYSTEM_EVENT_STA_GOT_IP:
|
|
|
|
|
//When connected set
|
|
|
|
|
Serial.print("WiFi connected! IP address: ");
|
|
|
|
|
Serial.println(WiFi.localIP());
|
|
|
|
|
//initializes the UDP state
|
|
|
|
|
//This initializes the transfer buffer
|
|
|
|
|
void enableNetwork(bool enable) {
|
|
|
|
|
if (enable) {
|
|
|
|
|
SetupAsyncServer();
|
|
|
|
|
udp.begin(WiFi.localIP(), LOCALUDPPORT);
|
|
|
|
|
connected = true;
|
|
|
|
|
} else {
|
|
|
|
|
connected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum t_wifi_state { WIFI_DISABLED, WIFI_SCAN, WIFI_CONNECT, WIFI_CONNECTED, WIFI_APMODE };
|
|
|
|
|
|
|
|
|
|
static t_wifi_state wifi_state = WIFI_DISABLED;
|
|
|
|
|
|
|
|
|
|
// Events used only for debug output right now
|
|
|
|
|
void WiFiEvent(WiFiEvent_t event)
|
|
|
|
|
{
|
|
|
|
|
Serial.printf("[WiFi-event] event: %d\n", event);
|
|
|
|
|
|
|
|
|
|
switch (event) {
|
|
|
|
|
case SYSTEM_EVENT_WIFI_READY:
|
|
|
|
|
Serial.println("WiFi interface ready");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_SCAN_DONE:
|
|
|
|
|
Serial.println("Completed scan for access points");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_START:
|
|
|
|
|
Serial.println("WiFi client started");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_STOP:
|
|
|
|
|
Serial.println("WiFi clients stopped");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_CONNECTED:
|
|
|
|
|
Serial.println("Connected to access point");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
|
|
|
|
Serial.println("WiFi lost connection");
|
|
|
|
|
connected = false;
|
|
|
|
|
Serial.println("Disconnected from WiFi access point");
|
|
|
|
|
if (wifi_state == WIFI_CONNECT) {
|
|
|
|
|
// If we get a disconnect event while waiting for connection (as I do sometimes with my FritzBox),
|
|
|
|
|
// just start from scratch with WiFi scan
|
|
|
|
|
wifi_state = WIFI_DISABLED;
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
|
|
|
|
|
Serial.println("Authentication mode of access point has changed");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_GOT_IP:
|
|
|
|
|
Serial.print("Obtained IP address: ");
|
|
|
|
|
Serial.println(WiFi.localIP());
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_LOST_IP:
|
|
|
|
|
Serial.println("Lost IP address and IP address is reset to 0");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
|
|
|
|
|
Serial.println("WiFi Protected Setup (WPS): succeeded in enrollee mode");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_WPS_ER_FAILED:
|
|
|
|
|
Serial.println("WiFi Protected Setup (WPS): failed in enrollee mode");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
|
|
|
|
|
Serial.println("WiFi Protected Setup (WPS): timeout in enrollee mode");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_STA_WPS_ER_PIN:
|
|
|
|
|
Serial.println("WiFi Protected Setup (WPS): pin code in enrollee mode");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_AP_START:
|
|
|
|
|
Serial.println("WiFi access point started");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_AP_STOP:
|
|
|
|
|
Serial.println("WiFi access point stopped");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_AP_STACONNECTED:
|
|
|
|
|
Serial.println("Client connected");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_AP_STADISCONNECTED:
|
|
|
|
|
Serial.println("Client disconnected");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_AP_STAIPASSIGNED:
|
|
|
|
|
Serial.println("Assigned IP address to client");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_AP_PROBEREQRECVED:
|
|
|
|
|
Serial.println("Received probe request");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_GOT_IP6:
|
|
|
|
|
Serial.println("IPv6 is preferred");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_ETH_START:
|
|
|
|
|
Serial.println("Ethernet started");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_ETH_STOP:
|
|
|
|
|
Serial.println("Ethernet stopped");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_ETH_CONNECTED:
|
|
|
|
|
Serial.println("Ethernet connected");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
|
|
|
|
Serial.println("Ethernet disconnected");
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_EVENT_ETH_GOT_IP:
|
|
|
|
|
Serial.println("Obtained IP address");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char* _scan[2]={"/","\\"};
|
|
|
|
|
|
|
|
|
|
int wifiConnect(int16_t res) {
|
|
|
|
|
Serial.printf("WLAN scan result: found %d networks\n", res);
|
|
|
|
|
|
|
|
|
|
// pick best network
|
|
|
|
|
int bestEntry = -1;
|
|
|
|
|
int bestRSSI = INT_MIN;
|
|
|
|
|
uint8_t bestBSSID[6];
|
|
|
|
|
int32_t bestChannel = 0;
|
|
|
|
|
|
|
|
|
|
for (int8_t i = 0; i < res; i++) {
|
|
|
|
|
String ssid_scan;
|
|
|
|
|
int32_t rssi_scan;
|
|
|
|
|
uint8_t sec_scan;
|
|
|
|
|
uint8_t* BSSID_scan;
|
|
|
|
|
int32_t chan_scan;
|
|
|
|
|
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
|
|
|
|
|
int networkEntry = fetchWifiIndex(ssid_scan.c_str());
|
|
|
|
|
if (networkEntry < 0) continue;
|
|
|
|
|
if (rssi_scan <= bestRSSI) continue;
|
|
|
|
|
bestEntry = networkEntry;
|
|
|
|
|
bestRSSI = rssi_scan;
|
|
|
|
|
bestChannel = chan_scan;
|
|
|
|
|
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
|
|
|
|
|
}
|
|
|
|
|
WiFi.scanDelete();
|
|
|
|
|
if (bestEntry >= 0) {
|
|
|
|
|
Serial.printf("WiFi Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s PW %s Channel: %d (RSSI %d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], fetchWifiSSID(bestEntry), fetchWifiPw(bestEntry), bestChannel, bestRSSI);
|
|
|
|
|
WiFi.begin(fetchWifiSSID(bestEntry), fetchWifiPw(bestEntry), bestChannel, bestBSSID);
|
|
|
|
|
wifi_state = WIFI_CONNECT;
|
|
|
|
|
} else {
|
|
|
|
|
// rescan
|
|
|
|
|
// wifiStart();
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
wifi_state = WIFI_DISABLED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int wifi_cto;
|
|
|
|
|
|
|
|
|
|
void loopWifiBackground() {
|
|
|
|
|
Serial.printf("WifiBackground: state %d\n", wifi_state);
|
|
|
|
|
// handle Wifi station mode in background
|
|
|
|
|
if (sonde.config.wifi == 0 || sonde.config.wifi == 2) return; // nothing to do if disabled or access point mode
|
|
|
|
|
|
|
|
|
|
if (wifi_state == WIFI_DISABLED) { // stopped => start can
|
|
|
|
|
wifi_state = WIFI_SCAN;
|
|
|
|
|
Serial.println("WLAN start scan");
|
|
|
|
|
WiFi.scanNetworks(true); // scan in async mode
|
|
|
|
|
} else if (wifi_state == WIFI_SCAN) {
|
|
|
|
|
int16_t res = WiFi.scanComplete();
|
|
|
|
|
if (res == 0 || res == WIFI_SCAN_FAILED) {
|
|
|
|
|
// retry
|
|
|
|
|
Serial.println("WLAN restart scan");
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
wifi_state = WIFI_DISABLED;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (res == WIFI_SCAN_RUNNING) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Scan finished, try to connect
|
|
|
|
|
wifiConnect(res);
|
|
|
|
|
wifi_cto = 0;
|
|
|
|
|
} else if (wifi_state == WIFI_CONNECT) {
|
|
|
|
|
wifi_cto++;
|
|
|
|
|
if (WiFi.isConnected()) {
|
|
|
|
|
wifi_state = WIFI_CONNECTED;
|
|
|
|
|
// update IP in display
|
|
|
|
|
String localIPstr = WiFi.localIP().toString();
|
|
|
|
|
sonde.setIP(localIPstr.c_str(), false);
|
|
|
|
|
sonde.updateDisplayIP();
|
|
|
|
|
enableNetwork(true);
|
|
|
|
|
}
|
|
|
|
|
if (wifi_cto > 20) { // failed, restart scanning
|
|
|
|
|
wifi_state = WIFI_DISABLED;
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
}
|
|
|
|
|
} else if (wifi_state == WIFI_CONNECTED) {
|
|
|
|
|
if (!WiFi.isConnected()) {
|
|
|
|
|
sonde.clearIP();
|
|
|
|
|
sonde.updateDisplayIP();
|
|
|
|
|
wifi_state = WIFI_DISABLED; // restart scan
|
|
|
|
|
enableNetwork(false);
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void startAP() {
|
|
|
|
|
Serial.println("Activating access point mode");
|
|
|
|
|
wifi_state = WIFI_APMODE;
|
|
|
|
|
WiFi.softAP(networks[0].id.c_str(), networks[0].pw.c_str());
|
|
|
|
|
IPAddress myIP = WiFi.softAPIP();
|
|
|
|
|
String myIPstr = myIP.toString();
|
|
|
|
|
sonde.setIP(myIPstr.c_str(), true);
|
|
|
|
|
sonde.updateDisplayIP();
|
|
|
|
|
SetupAsyncServer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void initialMode() {
|
|
|
|
|
if (sonde.config.spectrum != 0) { // enable Spectrum in config.txt: spectrum=number_of_seconds
|
|
|
|
|
startSpectrumDisplay();
|
|
|
|
|
//done in startSpectrumScan(): enterMode(ST_SPECTRUM);
|
|
|
|
|
} else {
|
|
|
|
|
enterMode(ST_SCANNER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wifi modes
|
|
|
|
|
// 0: disabled. directly start initial mode (spectrum or scanner)
|
|
|
|
|
// 1: station mode in background. directly start initial mode (spectrum or scanner)
|
|
|
|
|
// 2: access point mode in background. directly start initial mode (spectrum or scanner)
|
|
|
|
|
// 3: traditional sync. WifiScan. Tries to connect to a network, in case of failure activates AP.
|
|
|
|
|
// Mode 3 shows more debug information on serial port and display.
|
|
|
|
|
#define MAXWIFIDELAY 20
|
|
|
|
|
static const char* _scan[2] = {"/", "\\"};
|
|
|
|
|
void loopWifiScan() {
|
|
|
|
|
if (sonde.config.wifi == 0) { // no Wifi
|
|
|
|
|
wifi_state = WIFI_DISABLED;
|
|
|
|
|
initialMode();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (sonde.config.wifi == 1) { // station mode, setup in background
|
|
|
|
|
wifi_state = WIFI_DISABLED; // will start scanning in wifiLoopBackgroiund
|
|
|
|
|
initialMode();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (sonde.config.wifi == 2) { // AP mode, setup in background
|
|
|
|
|
startAP();
|
|
|
|
|
initialMode();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// wifi==3 => original mode with non-async wifi setup
|
|
|
|
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
|
|
|
|
if (sonde.config.wifi != 0) {
|
|
|
|
|
u8x8->drawString(0, 0, "WiFi Scan...");
|
|
|
|
|
}
|
|
|
|
|
else if (sonde.config.wifiap != 0) {
|
|
|
|
|
u8x8->drawString(0,0,"WiFi AP-Mode:");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int line = 0;
|
|
|
|
|
int cnt = 0;
|
|
|
|
|
int marker = 0;
|
|
|
|
|
char buf[5];
|
|
|
|
|
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
WiFi.mode(WIFI_STA);
|
|
|
|
|
const char *id, *pw, *wifipw;
|
|
|
|
|
char idstr[64]="test";
|
|
|
|
|
|
|
|
|
|
if (sonde.config.wifi != 0) {
|
|
|
|
|
int index = -1;
|
|
|
|
|
int n = WiFi.scanNetworks();
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
Serial.print("Network name: ");
|
|
|
|
|
Serial.println(WiFi.SSID(i));
|
|
|
|
|
u8x8->drawString(0,1+line,WiFi.SSID(i).c_str());
|
|
|
|
|
String ssid = WiFi.SSID(i);
|
|
|
|
|
Serial.println(ssid);
|
|
|
|
|
u8x8->drawString(0, 1 + line, ssid.c_str());
|
|
|
|
|
line = (line + 1) % 5;
|
|
|
|
|
Serial.print("Signal strength: ");
|
|
|
|
|
Serial.println(WiFi.RSSI(i));
|
|
|
|
|
@ -792,79 +1158,70 @@ void loopWifiScan() {
|
|
|
|
|
String encryptionTypeDescription = translateEncryptionType(WiFi.encryptionType(i));
|
|
|
|
|
Serial.println(encryptionTypeDescription);
|
|
|
|
|
Serial.println("-----------------------");
|
|
|
|
|
id=WiFi.SSID(i).c_str();
|
|
|
|
|
pw=fetchWifiPw(id);
|
|
|
|
|
if(pw) {
|
|
|
|
|
strncpy(idstr, id, 63);
|
|
|
|
|
wifipw = pw;
|
|
|
|
|
int curidx = fetchWifiIndex(ssid.c_str());
|
|
|
|
|
if (curidx >= 0 && index == -1) {
|
|
|
|
|
index = curidx;
|
|
|
|
|
Serial.printf("Match found at scan entry %d, config network %d\n", i, index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!wifipw) { wifipw="test"; }
|
|
|
|
|
Serial.print("Connecting to: "); Serial.println(idstr);
|
|
|
|
|
if (index >= 0) { // some network was found
|
|
|
|
|
Serial.print("Connecting to: "); Serial.print(fetchWifiSSID(index));
|
|
|
|
|
Serial.print(" with password "); Serial.println(fetchWifiPw(index));
|
|
|
|
|
|
|
|
|
|
u8x8->drawString(0, 6, "Conn:");
|
|
|
|
|
u8x8->drawString(6,6, idstr);
|
|
|
|
|
//register event handler
|
|
|
|
|
WiFi.onEvent(WiFiEvent);
|
|
|
|
|
|
|
|
|
|
WiFi.begin(idstr, wifipw);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(WiFi.status() != WL_CONNECTED) {
|
|
|
|
|
u8x8->drawString(6, 6, fetchWifiSSID(index));
|
|
|
|
|
WiFi.begin(fetchWifiSSID(index), fetchWifiPw(index));
|
|
|
|
|
while (WiFi.status() != WL_CONNECTED && cnt < MAXWIFIDELAY) {
|
|
|
|
|
delay(500);
|
|
|
|
|
Serial.print(".");
|
|
|
|
|
if (cnt == 5) {
|
|
|
|
|
// my FritzBox needs this for reconnecting
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
delay(500);
|
|
|
|
|
WiFi.begin(fetchWifiSSID(index), fetchWifiPw(index));
|
|
|
|
|
Serial.print("Reconnecting to: "); Serial.print(fetchWifiSSID(index));
|
|
|
|
|
Serial.print(" with password "); Serial.println(fetchWifiPw(index));
|
|
|
|
|
delay(500);
|
|
|
|
|
}
|
|
|
|
|
u8x8->drawString(15, 7, _scan[cnt & 1]);
|
|
|
|
|
cnt++;
|
|
|
|
|
#if 0
|
|
|
|
|
if(cnt==4) {
|
|
|
|
|
WiFi.disconnect(true); // retry, for my buggy FritzBox
|
|
|
|
|
WiFi.onEvent(WiFiEvent);
|
|
|
|
|
WiFi.begin(idstr, wifipw);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if(cnt==15) {
|
|
|
|
|
}
|
|
|
|
|
if (index < 0 || cnt >= MAXWIFIDELAY) { // no network found, or connect not successful
|
|
|
|
|
WiFi.disconnect(true);
|
|
|
|
|
|
|
|
|
|
if (sonde.config.wifiap != 0) { // enable WiFi AP mode in config.txt: wifi=1
|
|
|
|
|
delay(1000);
|
|
|
|
|
WiFi.softAP(networks[0].id.c_str(),networks[0].pw.c_str());
|
|
|
|
|
startAP();
|
|
|
|
|
IPAddress myIP = WiFi.softAPIP();
|
|
|
|
|
Serial.print("AP IP address: ");
|
|
|
|
|
Serial.println(myIP);
|
|
|
|
|
u8x8->drawString(0, 6, "AP: ");
|
|
|
|
|
u8x8->drawString(6, 6, networks[0].id.c_str());
|
|
|
|
|
sonde.setIP(myIP.toString().c_str(), true);
|
|
|
|
|
sonde.updateDisplayIP();
|
|
|
|
|
SetupAsyncServer();
|
|
|
|
|
delay(3000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sonde.config.spectrum != 0) { // enable Spectrum in config.txt: spectrum=number_of_seconds
|
|
|
|
|
startSpectrumDisplay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enterMode(ST_SCANNER);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
Serial.println("");
|
|
|
|
|
Serial.println("WiFi connected");
|
|
|
|
|
Serial.println("IP address: ");
|
|
|
|
|
Serial.println(WiFi.localIP());
|
|
|
|
|
sonde.setIP(WiFi.localIP().toString().c_str(), false);
|
|
|
|
|
String localIPstr = WiFi.localIP().toString();
|
|
|
|
|
Serial.println(localIPstr);
|
|
|
|
|
sonde.setIP(localIPstr.c_str(), false);
|
|
|
|
|
sonde.updateDisplayIP();
|
|
|
|
|
wifi_state = WIFI_CONNECTED;
|
|
|
|
|
delay(3000);
|
|
|
|
|
}
|
|
|
|
|
SetupAsyncServer();
|
|
|
|
|
delay(2000);
|
|
|
|
|
initialMode();
|
|
|
|
|
|
|
|
|
|
if (sonde.config.spectrum != 0) { // enable Spectrum in config.txt: spectrum=number_of_seconds
|
|
|
|
|
startSpectrumDisplay();
|
|
|
|
|
}
|
|
|
|
|
//startSpectrumDisplay();
|
|
|
|
|
enterMode(ST_SPECTRUM);
|
|
|
|
|
} else {
|
|
|
|
|
enterMode(ST_SCANNER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
Serial.println("Running main loop");
|
|
|
|
|
Serial.print("Running main loop. free heap:");
|
|
|
|
|
Serial.println(ESP.getFreeHeap());
|
|
|
|
|
switch (mainState) {
|
|
|
|
|
case ST_DECODER: loopDecoder(); break;
|
|
|
|
|
case ST_SCANNER: loopScanner(); break;
|
|
|
|
|
@ -880,4 +1237,5 @@ void loop() {
|
|
|
|
|
Serial.print(" LNA Gain: "),
|
|
|
|
|
Serial.println(gain);
|
|
|
|
|
#endif
|
|
|
|
|
loopWifiBackground();
|
|
|
|
|
}
|
|
|
|
|
|