Stairs/src/server/settings.cpp

249 lines
5.7 KiB
C++

/*
* Stairs
* Copyright 2017 (c) Mark van Renswoude
*
* https://git.x2software.net/pub/Stairs
*/
#include "./settings.h"
#include <ArduinoJson.h>
#include <IPAddress.h>
#include <ESP8266WiFi.h>
#include <EspSaveCrash.h>
#include "./shared.h"
#include "../assets/version.h"
#include "../config.h"
#include "../debug.h"
#include "../global.h"
#include "../settings/connection.h"
extern "C" {
#include <user_interface.h>
}
bool clearedResetReason = false;
void handleStatus(AsyncWebServerRequest *request)
{
_dln("API :: status");
DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(6));
JsonObject& root = jsonBuffer.createObject();
root["systemID"] = String(ESP.getChipId(), HEX);
root["version"] = String(VersionFullSemVer);
if (ntpClient != nullptr && hasTimezone)
{
root["time"] = ntpClient->getEpochTime();
root["timeOffset"] = timezoneOffset;
}
else
{
root["time"] = false;
root["timeOffset"] = 0;
}
root["resetReason"] = clearedResetReason ? 0 : ESP.getResetInfoPtr()->reason;
root["stackTrace"] = SaveCrash.count() > 0;
AsyncResponseStream *response = request->beginResponseStream("application/json");
root.printTo(*response);
request->send(response);
}
void handleConnectionStatus(AsyncWebServerRequest *request)
{
_dln("API :: connection status");
WiFiMode_t mode = WiFi.getMode();
DynamicJsonBuffer jsonBuffer((2 * JSON_OBJECT_SIZE(2)) + JSON_OBJECT_SIZE(3));
JsonObject& root = jsonBuffer.createObject();
JsonObject& ap = root.createNestedObject("ap");
ap["enabled"] = (mode == WIFI_AP || mode == WIFI_AP_STA);
ap["ip"] = WiFi.softAPIP().toString();
JsonObject& station = root.createNestedObject("station");
station["enabled"] = (mode == WIFI_STA || mode == WIFI_AP_STA);
station["status"] = (uint8_t)WiFi.status();
station["ip"] = WiFi.localIP().toString();
AsyncResponseStream *response = request->beginResponseStream("application/json");
root.printTo(*response);
request->send(response);
}
void handleGetConnection(AsyncWebServerRequest *request)
{
_dln("API :: get connection");
AsyncResponseStream *response = request->beginResponseStream("application/json");
connectionSettings->toJson(*response);
request->send(response);
}
void handlePostConnection(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
{
_dln("API :: post connection");
bool changed;
if (connectionSettings->fromJson((char*)data, &changed))
{
connectionSettings->write();
if (changed)
connectionSettingsChanged = true;
request->send(200);
}
else
request->send(400);
}
void handleGetSystem(AsyncWebServerRequest *request)
{
_dln("API :: get system");
AsyncResponseStream *response = request->beginResponseStream("application/json");
systemSettings->toJson(*response);
request->send(response);
}
void handlePostSystem(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
{
_dln("API :: post system");
bool changed;
if (systemSettings->fromJson((char*)data, &changed))
{
systemSettings->write();
if (changed)
systemSettingsChanged = true;
request->send(200);
}
else
request->send(400);
}
void handleGetSteps(AsyncWebServerRequest *request)
{
_dln("API :: get steps");
AsyncResponseStream *response = request->beginResponseStream("application/json");
stepsSettings->toJson(*response);
request->send(response);
}
void handlePostSteps(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
{
_dln("API :: post steps");
bool changed;
if (stepsSettings->fromJson((char*)data, &changed))
{
stepsSettings->write();
if (changed)
stepsSettingsChanged = true;
request->send(200);
}
else
request->send(400);
}
void handleGetStackTrace(AsyncWebServerRequest *request)
{
_dln("API :: get stack trace");
if (SaveCrash.count() == 0)
{
request->send(404);
return;
}
AsyncResponseStream *response = request->beginResponseStream("application/octet-stream");
response->addHeader("Content-Disposition", "attachment; filename=\"stacktrace.txt\"");
SaveCrash.print(*response);
request->send(response);
}
void handleDeleteStackTrace(AsyncWebServerRequest *request)
{
_dln("API :: delete stack trace");
clearedResetReason = true;
SaveCrash.clear();
request->send(200);
}
#ifdef EnableCrashAPI
#pragma "!!! Crash API is enabled on this build !!!"
void handleCrashException(AsyncWebServerRequest *request)
{
_dln("API :: crash exception");
int* i = nullptr;
*i = 42;
}
void handleCrashSoftWDT(AsyncWebServerRequest *request)
{
_dln("API :: crash soft WDT");
while (true);
}
void handleCrashWDT(AsyncWebServerRequest *request)
{
_dln("API :: crash WDT");
ESP.wdtDisable();
while (true);
}
#endif
void registerSettingsRoutes(AsyncWebServer* server)
{
server->on("/api/status", HTTP_GET, handleStatus);
server->on("/api/connection/status", HTTP_GET, handleConnectionStatus);
server->on("/api/connection", HTTP_GET, handleGetConnection);
server->on("/api/connection", HTTP_POST, devNullRequest, devNullFileUpload, handlePostConnection);
server->on("/api/system", HTTP_GET, handleGetSystem);
server->on("/api/system", HTTP_POST, devNullRequest, devNullFileUpload, handlePostSystem);
server->on("/api/steps", HTTP_GET, handleGetSteps);
server->on("/api/steps", HTTP_POST, devNullRequest, devNullFileUpload, handlePostSteps);
server->on("/api/stacktrace/get", HTTP_GET, handleGetStackTrace);
server->on("/api/stacktrace/delete", HTTP_GET, handleDeleteStackTrace);
#ifdef EnableCrashAPI
server->on("/api/crash/exception", HTTP_GET, handleCrashException);
server->on("/api/crash/softwdt", HTTP_GET, handleCrashSoftWDT);
server->on("/api/crash/wdt", HTTP_GET, handleCrashWDT);
#endif
}