smartPOC-tx/src/webserver.cpp
2025-03-30 15:15:54 +02:00

426 lines
No EOL
15 KiB
C++

#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "main.h"
extern const uint8_t data_index_html_start[] asm("_binary_data_index_html_start");
extern const uint8_t data_index_html_end[] asm("_binary_data_index_html_end");
extern const uint8_t data_script_js_start[] asm("_binary_data_script_js_start");
extern const uint8_t data_script_js_end[] asm("_binary_data_script_js_end");
extern const uint8_t data_style_css_start[] asm("_binary_data_style_css_start");
extern const uint8_t data_style_css_end[] asm("_binary_data_style_css_end");
AsyncWebServer server(80);
// static AsyncWebSocket ws("/ws");
// static AsyncEventSource events("/events");
//
void handleNotFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
//
// void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
// if (type == WS_EVT_CONNECT) {
// // client connected
// info("ws[%s][%u] connect\n", server->url(), client->id());
// // String str = get_settings();
// // client->printf("%s", str.c_str());
// client->ping();
// } else if (type == WS_EVT_DISCONNECT) {
// // client disconnected
// info("ws[%s][%u] disconnect: %u\n", server->url(), client->id());
// } else if (type == WS_EVT_ERROR) {
// // error was received from the other end
// info("ws[%s][%u] error(%u): %s\n", server->url(), client->id(),
// *((uint16_t *)arg), (char *)data);
// } else if (type == WS_EVT_PONG) {
// // pong message was received (in response to a ping request maybe)
// info("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char *)data : "");
// } else if (type == WS_EVT_DATA) {
// // data packet
// AwsFrameInfo *info = (AwsFrameInfo *)arg;
// if (info->final && info->index == 0 && info->len == len) {
// // the whole message is in a single frame and we got all of it's
// // data info("ws[%s][%u] %s-message[%llu]: ", server->url(),
// // client->id(), (info->opcode == WS_TEXT) ? "text" : "binary",
// // info->len);
// if (info->opcode == WS_TEXT) {
// data[len] = 0;
// info("data: %s\n", (char *)data);
// // parse_cmd((char *)data, client);
// }
// }
// }
// }
//
static void redirectHomeResponse(AsyncWebServerRequest *request, String location) {
AsyncWebServerResponse *response = request->beginResponse(303, "text/plain", "");
response->addHeader("Location", location);
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
}
//
static void insertPage(AsyncWebServerRequest *request) {
uint32_t address = 0;
int ric = -1;
int fun = 0;
String message;
//
if (request->hasArg("text")) {
message = request->arg("text");
message = txHandleUmlauts(message);
}
if (request->hasArg("ric")) {
ric = request->arg("ric").toInt();
address = ric + 0;
}
if (request->hasArg("fun")) {
fun = request->arg("fun").toInt();
}
Serial.printf("RIC: %d -> %d MSG: %s\n\n", ric, address, message);
if (ric > 0) {
char *messageText = new char[message.length() + 1]{};
message.toCharArray(messageText, message.length() + 1);
// messageText[ message.length() ] = 0x20;
txControllerInsert(address, fun + 0, messageText);
delete []messageText;
if (request->hasArg("addtx")) {
txControllerBatchStart();
}
}
redirectHomeResponse(request, "/");
}
//
static void triggerTimeBeacon(AsyncWebServerRequest *request) {
broadcastTriggerTimeBeacon();
redirectHomeResponse(request, "/#time");
}
static void transmit(AsyncWebServerRequest *request) {
txControllerBatchStart();
redirectHomeResponse(request, "/");
}
static void clearQueue(AsyncWebServerRequest *request) {
redirectHomeResponse(request, "/");
}
static void resetConfigReboot(AsyncWebServerRequest *request) {
redirectHomeResponse(request, "/");
create_default_config();
esp_cpu_reset(1);
esp_cpu_reset(0);
}
static void justReboot(AsyncWebServerRequest *request) {
redirectHomeResponse(request, "/");
esp_cpu_reset(1);
esp_cpu_reset(0);
}
//
static void setAPCfg(AsyncWebServerRequest *request) {
String ssid, pass;
//
if (request->hasArg("ssid")) ssid = request->arg("ssid");
if (request->hasArg("pass")) pass = request->arg("pass");
cfg_startTransaction();
cfg_adjust("ap_ssid", ssid);
cfg_adjust("ap_pass", pass);
cfg_write();
redirectHomeResponse(request, "/#wifi");
}
static void setWifi1Cfg(AsyncWebServerRequest *request) {
String ssid, pass;
//
if (request->hasArg("ssid")) ssid = request->arg("ssid");
if (request->hasArg("pass")) pass = request->arg("pass");
cfg_startTransaction();
cfg_adjust("wifi1_ssid", ssid);
cfg_adjust("wifi1_pass", pass);
cfg_write();
redirectHomeResponse(request, "/#wifi");
}
static void setWifi2Cfg(AsyncWebServerRequest *request) {
String ssid, pass;
//
if (request->hasArg("ssid")) ssid = request->arg("ssid");
if (request->hasArg("pass")) pass = request->arg("pass");
cfg_startTransaction();
cfg_adjust("wifi2_ssid", ssid);
cfg_adjust("wifi2_pass", pass);
cfg_write();
redirectHomeResponse(request, "/#wifi");
}
//
static void setTransmitterCfg(AsyncWebServerRequest *request) {
float tx_freq, tx_dev;
int tx_power, tx_baud;
bool tx_empty_queue, pocsag_german;
//
cfg_startTransaction();
if (request->hasArg("tx_freq")) {
tx_freq = request->arg("tx_freq").toFloat();
cfg_adjust("tx_freq", tx_freq);
}
if (request->hasArg("tx_baud")) {
tx_baud = request->arg("tx_baud").toInt();
cfg_adjust("tx_baud", tx_baud);
}
if (request->hasArg("tx_dev")) {
tx_dev = request->arg("tx_dev").toFloat();
cfg_adjust("tx_dev", tx_dev);
}
if (request->hasArg("tx_power")) {
tx_power = request->arg("tx_power").toInt();
cfg_adjust("tx_power", tx_power);
}
if (request->hasArg("tx_empty_queue")) {
tx_empty_queue = request->arg("tx_empty_queue").equals("on");
cfg_adjust("tx_empty_queue", tx_empty_queue);
} else {
cfg_adjust("tx_empty_queue", false);
}
if (request->hasArg("pocsag_german")) {
pocsag_german = request->arg("pocsag_german").equals("on");
cfg_adjust("pocsag_german", pocsag_german);
} else {
cfg_adjust("pocsag_german", false);
}
cfg_write();
redirectHomeResponse(request, "/#config");
}
static void setMQTTCfg(AsyncWebServerRequest *request) {
String mqtt_host, mqtt_user, mqtt_pass, mqtt_topic;
int mqtt_port;
//
cfg_startTransaction();
if (request->hasArg("mqtt_host")) {
mqtt_host = request->arg("mqtt_host");
cfg_adjust("mqtt_host", mqtt_host);
}
if (request->hasArg("mqtt_topic")) {
mqtt_topic = request->arg("mqtt_topic");
cfg_adjust("mqtt_topic", mqtt_topic);
}
if (request->hasArg("mqtt_user")) {
mqtt_user = request->arg("mqtt_user");
cfg_adjust("mqtt_user", mqtt_user);
}
if (request->hasArg("mqtt_pass")) {
mqtt_pass = request->arg("mqtt_pass");
cfg_adjust("mqtt_pass", mqtt_pass);
}
if (request->hasArg("mqtt_port")) {
mqtt_port = request->arg("mqtt_port").toInt();
cfg_adjust("mqtt_port", mqtt_port);
}
cfg_write();
redirectHomeResponse(request, "/#config");
}
//
static void setDWDMoWaS(AsyncWebServerRequest *request) {
int broadcast_ric, broadcast_fun;
bool dwd_enable, mowas_enable;
int dwd_interval, mowas_interval;
int dwd_fun, mowas_fun;
String dwd_region, mowas_region;
cfg_startTransaction();
//broadcast
if (request->hasArg("broadcast_ric")) {
broadcast_ric = request->arg("broadcast_ric").toFloat();
cfg_adjust("broadcast_ric", broadcast_ric);
}
if (request->hasArg("broadcast_fun")) {
broadcast_fun = request->arg("broadcast_fun").toInt();
cfg_adjust("broadcast_fun", broadcast_fun);
}
// dwd
if (request->hasArg("dwd_enable")) {
dwd_enable = request->arg("dwd_enable").equals("on");
cfg_adjust("dwd_enable", dwd_enable);
} else {
cfg_adjust("dwd_enable", false);
}
if (request->hasArg("dwd_interval")) {
dwd_interval = request->arg("dwd_interval").toInt();
cfg_adjust("dwd_interval", dwd_interval);
}
if (request->hasArg("dwd_fun")) {
dwd_fun = request->arg("dwd_fun").toInt();
cfg_adjust("dwd_fun", dwd_fun);
}
if (request->hasArg("dwd_region")) {
dwd_region = request->arg("dwd_region");
cfg_adjust("dwd_region", dwd_region);
}
// mowas
if (request->hasArg("mowas_enable")) {
mowas_enable = request->arg("mowas_enable").equals("on");
cfg_adjust("mowas_enable", mowas_enable);
} else {
cfg_adjust("mowas_enable", false);
}
if (request->hasArg("mowas_interval")) {
mowas_interval = request->arg("mowas_interval").toInt();
cfg_adjust("mowas_interval", mowas_interval);
}
if (request->hasArg("mowas_fun")) {
mowas_fun = request->arg("mowas_fun").toInt();
cfg_adjust("mowas_fun", mowas_fun);
}
if (request->hasArg("mowas_region")) {
mowas_region = request->arg("mowas_region");
cfg_adjust("mowas_region", mowas_region);
}
cfg_write();
redirectHomeResponse(request, "/#dwdmowas");
}
//
static void setTimebeacon(AsyncWebServerRequest *request) {
int time_ric, time_fun;
bool time_enable;
int time_interval, time_mode;
String time_zone;
cfg_startTransaction();
if (request->hasArg(CFG_TIME_RIC)) {
time_ric = request->arg(CFG_TIME_RIC).toFloat();
cfg_adjust(CFG_TIME_RIC, time_ric);
}
if (request->hasArg("time_fun")) {
time_fun = request->arg("time_fun").toInt();
cfg_adjust("time_fun", time_fun);
}
if (request->hasArg("time_enable")) {
time_enable = request->arg("time_enable").equals("on");
cfg_adjust("time_enable", time_enable);
} else {
cfg_adjust("time_enable", false);
}
if (request->hasArg("time_interval")) {
time_interval = request->arg("time_interval").toInt();
cfg_adjust("time_interval", time_interval);
}
if (request->hasArg("time_mode")) {
time_mode = request->arg("time_mode").toInt();
cfg_adjust("time_mode", time_mode);
}
if (request->hasArg("time_zone")) {
time_zone = request->arg("time_zone");
cfg_adjust("time_zone", time_zone);
}
cfg_write();
redirectHomeResponse(request, "/#timebeacon");
}
static void setIdlebeacon(AsyncWebServerRequest *request) {
bool idle_enable;
int idle_interval, idle_mode;
cfg_startTransaction();
if (request->hasArg("idle_enable")) {
idle_enable = request->arg("idle_enable").equals("on");
cfg_adjust("idle_enable", idle_enable);
} else {
cfg_adjust("idle_enable", false);
}
if (request->hasArg("idle_interval")) {
idle_interval = request->arg("idle_interval").toInt();
cfg_adjust("idle_interval", idle_interval);
}
if (request->hasArg("idle_mode")) {
idle_mode = request->arg("idle_mode").toInt();
cfg_adjust("idle_mode", idle_mode);
}
cfg_write();
redirectHomeResponse(request, "/#idle");
}
//
static void setDevCfg(AsyncWebServerRequest *request) {
int oled_timeout;
//
cfg_startTransaction();
if (request->hasArg("oled_timeout")) {
oled_timeout = request->arg("oled_timeout").toInt();
cfg_adjust("oled_timeout", oled_timeout);
}
if (request->hasArg("device_name")) {
String device_name = request->arg("device_name");
cfg_adjust("device_name", device_name);
}
cfg_write();
redirectHomeResponse(request, "/#config");
}
//
void webserver_setup() {
// ws.onEvent(onEvent);
// server.addHandler(&ws);
// // attach AsyncEventSource
// server.addHandler(&events);
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
AsyncWebServerResponse *response = request->beginResponse_P(
200, "text/html", data_index_html_start,
data_index_html_end - data_index_html_start - 1);
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
});
server.on("/script.js", HTTP_GET, [](AsyncWebServerRequest *request)
{
AsyncWebServerResponse *response = request->beginResponse_P(
200, "application/javascript", data_script_js_start,
data_script_js_end - data_script_js_start - 1);
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
});
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request)
{
AsyncWebServerResponse *response = request->beginResponse_P(
200, "text/css", data_style_css_start,
data_style_css_end - data_style_css_start - 1);
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
});
server.on("/config.json", HTTP_GET, [](AsyncWebServerRequest *request) {
String output = cfg_tostring();
AsyncWebServerResponse *response =
request->beginResponse(200, "application/json", output);
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
});
server.on("/contacts.json", HTTP_GET, [](AsyncWebServerRequest *request) {
String output = contacts_tostring();
AsyncWebServerResponse *response =
request->beginResponse(200, "application/json", output);
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
});
server.on("/contacts.json", HTTP_POST, [](AsyncWebServerRequest * request){
if (request->hasParam("body", true)) { // This is important, otherwise the sketch will crash if there is no body
contacts_write(request->getParam("body", true)->value());
request->send(200, "text/plain", "ok\n");
} else {
Serial.println("No body?!");
request->send(200, "text/plain", "No body?!\n");
}
});
server.on("/setap", setAPCfg);
server.on("/setwifi1", setWifi1Cfg);
server.on("/setwifi2", setWifi2Cfg);
server.on("/settransmitter", setTransmitterCfg);
server.on("/setmqtt", setMQTTCfg);
server.on("/setdwdmowas", setDWDMoWaS);
server.on("/settimebeacon", setTimebeacon);
server.on("/setidlebeacon", setIdlebeacon);
server.on("/setdev", setDevCfg);
server.on("/page", insertPage);
server.on("/trigger-time", triggerTimeBeacon);
server.on("/transmit", transmit);
server.on("/clear", clearQueue);
server.on("/rstcfgrbt", resetConfigReboot);
server.on("/reboot", justReboot);
server.onNotFound(handleNotFound);
server.begin();
}