From 8df2383d9c3541ca3140fec453fde989c5c15555 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Sun, 30 Jan 2022 16:56:05 +0100
Subject: [PATCH] Add api endpoints and form loader
---
data/script.js | 134 +++++++++++++++++++++-
data/script.js.gz | Bin 1266 -> 2352 bytes
include/lv_conf_v7.h | 2 +-
src/hasp_gui.cpp | 10 +-
src/log/hasp_debug.cpp | 4 +-
src/sys/svc/hasp_http.cpp | 226 +++++++++++++++++++-------------------
6 files changed, 255 insertions(+), 121 deletions(-)
diff --git a/data/script.js b/data/script.js
index 0b00a6e0..ba803b3c 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1,133 @@
-function aref(e){setTimeout(function(){ref("")},1e3*e)}function ref(e){var o=(new Date).getTime();return document.getElementById("bmp").src="?a="+e+"&q="+o,!1}function about(){document.getElementById("doc").innerHTML='
openHASP Copyright© 2019-2021 Francis Van RoieMIT LicensePermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Based on the previous work of the following open source developers:
HASwitchPlate Copyright© 2019 Allen Derusha allen @derusha.orgMIT License
LVGL Copyright© 2021 LVGL KftMIT License
zi Font Engine Copyright© 2020-2021 Francis Van RoieMIT License
TFT_eSPI Library Copyright© 2020 Bodmer (https://github.com/Bodmer) All rights reserved.FreeBSD License
includes parts from the Adafruit_GFX library Copyright© 2012 Adafruit Industries. All rights reservedBSD License
ArduinoJson Copyright© 2014-2021 Benoit BLANCHONMIT License
PubSubClient Copyright© 2008-2015 Nicholas O'LearyMIT License
ArduinoLog Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, dhylands, Josha blemasle, mfalkviddMIT License
QR Code generator Copyright© Project NayukiMIT License
SimpleFTPServer Copyright© 2017 Renzo Mischianti www.mischianti.org All right reserved.MIT License
AceButton Copyright© 2018 Brian T. ParkMIT License
'}
\ No newline at end of file
+function aref(e) { setTimeout(function() { ref("") }, 1e3 * e) }
+
+function ref(e) { var o = (new Date).getTime(); return document.getElementById("bmp").src = "?a=" + e + "&q=" + o, !1 }
+
+function about() { document.getElementById("doc").innerHTML = 'openHASP Copyright© 2019-2021 Francis Van RoieMIT LicensePermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Based on the previous work of the following open source developers:
HASwitchPlate Copyright© 2019 Allen Derusha allen @derusha.orgMIT License
LVGL Copyright© 2021 LVGL KftMIT License
zi Font Engine Copyright© 2020-2021 Francis Van RoieMIT License
TFT_eSPI Library Copyright© 2020 Bodmer (https://github.com/Bodmer) All rights reserved.FreeBSD License
includes parts from the Adafruit_GFX library Copyright© 2012 Adafruit Industries. All rights reservedBSD License
ArduinoJson Copyright© 2014-2021 Benoit BLANCHONMIT License
PubSubClient Copyright© 2008-2015 Nicholas O'LearyMIT License
ArduinoLog Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, dhylands, Josha blemasle, mfalkviddMIT License
QR Code generator Copyright© Project NayukiMIT License
SimpleFTPServer Copyright© 2017 Renzo Mischianti www.mischianti.org All right reserved.MIT License
AceButton Copyright© 2018 Brian T. ParkMIT License
' }
+
+function handleSubmit(event) {
+ event.preventDefault();
+ const data = new FormData(event.target);
+ const value = Object.fromEntries(data.entries());
+ console.log({ value });
+}
+
+function info() {
+ console.log(this.response);
+ data = JSON.parse(this.response);
+ console.log(data);
+ var table = "";
+ for (let header in data) { table += `${header} `; for (let key in data[header]) { table += `${key}: ${data[header][key]} `; } }
+ table += "
";
+ document.getElementById("info").innerHTML = table;
+}
+
+function loader(method, uri, func) {
+ window.addEventListener("load", function() {
+ var rq = new XMLHttpRequest();
+ rq.addEventListener("load", func);
+ rq.open(method, uri);
+ rq.send();
+ })
+}
+
+function fill() {
+ data = JSON.parse(this.response);
+ form = document.forms.item(0);
+ populate(form, data);
+}
+
+function filler(method, uri) {
+ window.addEventListener("load", function() {
+ var rq = new XMLHttpRequest();
+ rq.addEventListener("load", fill);
+ rq.open(method, uri);
+ rq.send();
+ })
+}
+
+function filler2(method, uri) {
+ var rq = new XMLHttpRequest();
+ rq.addEventListener("load", fill);
+ rq.open(method, uri);
+ rq.send();
+}
+
+/** https://github.com/dannyvankooten/populate.js
+ * Populate form fields from a JSON object.
+ *
+ * @param form object The form element containing your input fields.
+ * @param data array JSON data to populate the fields with.
+ * @param basename string Optional basename which is added to `name` attributes
+ */
+function populate(form, data, basename) {
+ for (var key in data) {
+ if (!data.hasOwnProperty(key)) {
+ continue;
+ }
+
+ var name = key;
+ var value = data[key];
+
+ if ('undefined' === typeof value) {
+ value = '';
+ }
+
+ if (null === value) {
+ value = '';
+ }
+
+ // handle array name attributes
+ if (typeof(basename) !== "undefined") {
+ name = basename + "[" + key + "]";
+ }
+
+ if (value.constructor === Array) {
+ name += '[]';
+ } else if (typeof value == "object") {
+ populate(form, value, name);
+ continue;
+ }
+
+ // only proceed if element is set
+ var element = form.elements.namedItem(name);
+ if (!element) {
+ continue;
+ }
+
+ var type = element.type || element[0].type;
+
+ switch (type) {
+ default: element.value = value;
+ break;
+
+ case 'radio':
+ var values = value.constructor === Array ? value : [value];
+ for (var j = 0; j < element.length; j++) {
+ element[j].checked = values.indexOf(Number(element[j].value)) > -1;
+ }
+ break;
+
+ case 'checkbox':
+ var values = value.constructor === Array ? value : [value];
+ element.checked = values.indexOf(Number(element.value)) > -1;
+ break;
+
+ case 'select-multiple':
+ var values = value.constructor === Array ? value : [value];
+ for (var k = 0; k < element.options.length; k++) {
+ element.options[k].selected = (values.indexOf(element.options[k].value) > -1);
+ }
+ break;
+
+ case 'select':
+ case 'select-one':
+ element.value = value.toString() || value;
+ break;
+
+ case 'date':
+ element.value = new Date(value).toISOString().split('T')[0];
+ break;
+ }
+
+ }
+};
\ No newline at end of file
diff --git a/data/script.js.gz b/data/script.js.gz
index a093c05f52ff4dd95520121c40001ac5abe21497..732b8f5cb08e647b66efc65822be57ce0f7f1288 100644
GIT binary patch
literal 2352
zcmV-03D5Q)iwFpR)AeBj0CQtfEdYI6Y1S!r+EMiBj8p#Nbi6tx^PwBsI0eYKKB
z#Y|;MmE;^SjAkXSM8*`CSuU-rssDT5E)VOljJPd|8ji)?nR#_qlzlGwa8480
zD(+b{mYkCq)5vFX!YxvQSTv`Y%LE2us8|pM(S#Uj_gYi=fJwwy&Cnnyd&H7Ni~rZa7iql~jB)&ynprMDU!e)ZatWuUqW0!;k)xuC?1Ux~q
zi}B@JO6cMsg1kn?^UN31C0$+WF(?J6+}L;mH8Vax@R7ofQ6Gyi6f-0Tmys9foRWjQ
zZv)7|p&JfaP63L9Lc}Hx(}uY0Z6Qj0h6IK@uN$1B%4{JgsbfeK+8>|=v5?y7TCR2x
z#F<0=PIK_4)^o`1Q@7W7?KYeSRcd{#D;B+R2WOp&0YRfzYY*O0r%AQ;JNm_KH!O1A
zc6(00Pn{mQ=iQd;V9#xzwk{fO`z6(3*Y1F@E@%tTL5JY5fO4I_20M3pr)OB!>Tb&&
zytAn34%!;C3D6pKYrTPcdeN%&sC&`tcKQz7Hvrpq+sz)lIOk4#V7qN>k@FhQ)IY1W
zTESr8c&DB2yPo^Q$&-9ccrddtZ?A*a(;%{{lMQ9G}_bc|I8C_Si^
z!M!cew0WtFTCzkvs5NSd)A+N!M6=LdP1nQ;|
zA`Q4Byt_K$I@10px3qv3^xJcYc3
zqN=Y{oE+@#PB75Yp*<4Q-AuHti&P9WOhGPhxMv&RP04w^-&pdG-{2&F&oK*_gww13&nXkOSrp8A~iWmpw5Q>W6)cB=ghI<6?jByXO{0&D-bS
zTIBij5VIPZuY@N35QjfYLXLB3%);xN!1FeR^(!Wl@HkC)#3fTgZi=oeg*j2$Y@S{R
zo8bDvG!A)l(CzE~$%j&<9*_PIbRHxlKhVbn&1N%uS}ygwddG=7nr=z@{#f*Y`nftz55s6gK2w1&-n>=2E0^)%x-a!jDbeZ#_(L%m}TZ(F}(PGsJWss^%ozSv$g6Ct-lF{ysa
z&2P1EIfoz`3w=XeH`1rOjnc;0<2h;(^s9cSZR2fE_^R4EjyB2n%@tTNa1a=kBlC1p
z$z@}KxfF6mK4+N8h|G9HY`MwKF}*)hI6agH2VoMk=y)IRyz=k|`s=_c`|6Y{Uw9U!GO$Ps%XZ@Q^u)|&p66&{wQ%#~5iBa&5*Mce>5c$JljO&o
zns3irXG+CA{xRi=rf{hTorjTEboD8|80(5S;gMIsgQ%;y;vOIBFds!jbb1Q4veJ5;
z*n#5H>RzD}i#XL6hpHA@RIqj3`*NlK4>d+m|9XwN++R!ca{_)$u$u!dgDhLH`{W5E
zPpF%>$@COxJoNIL1~W7ukqt&DX9hom7i?_G^~i}+m4n-h
zD28uLN;Wsnvb7Q=dGvKBw=>@nmyCxDDX}T1L`m(c6YFZT@J=xEab2JwA(SusuJ&H<
zzbB^huZoEV+`a47eYCYoKy+zQ)85R)gnT)Wtu*rZ7?)#ji;j;m_2w}bp@Sr-NVatPZj
z|NOI9U+!I*ttBES=DTQC&o!T3b`v}(5eovE&z15GC1=;zTM3(?VOx@Uf!I1&7OlN)
z36LLP3H_9}`+zRZ!_`UzOC#h1!1fODaa2Yh@@S%b?CtDisjmN&wfb;nk955@2QNx||gJ~!LtR3DdD0*sM*
zIt8VIIOP9HdUr=k#)s<#J_vKNB_%JeH}hiE=JNW=&eAa@tFF}S9&MwMm2LZA&9{vTqKs!Vk82|t})R<5J
literal 1266
zcmVvZ0CQtfEdYI6X6Rcm+BKoI>aBOeqr(pukI(Ey=DLlTqJ
z$0yGw8OYj@jk}w2(Bpr1Hau#z^c)UkcV_O~xicB&O_gabDqs@lUF`i*s1v?K(dh2Z
z*6sZ=#!jdA+j@kL?_=-xK5QFx$s~w3-3nJQW*U3_#RjI^do58nvVvS>%@QkZEKZ5$
zakzH#ZYN#VonBwb>`mt_d((M<4?1^$(66xWJi5xmQes3z4#JRuV0cxboF+5x&Arp&
z@j%pAP3<^5J)*-%)N9EXg}$57(`z_6e)RI;$??e}m`GM-T)`(+K_oby9;I?Ha})4*
zhLxgoJvglgA<89J%FrR_0wtzvSWv9S+=9781TlxKU~+*LXaTHRLyb~VfJimt6|WY+
zz@#^xx*!-O=6b~>l5-ABDUoqTczeBATmGDvsJgm9=)~KAPOr_8BP)SdU~D@Rthg>n
zFOaCT&K&OqS
zOGTF(rL4A$BM=f4mZibqsHoU${5D=%7;%WfR--oasu0U-zDDXf4G<;8HYOLKM4R(F
zW}0qV_qixbu`y(67!{D>RyWLz
z%IvS2q~V}6wVzW9Y9US1|7z{;NK74wgGut)jvR1f2&3SWJ9fs%0CWqAbqL
z@sqym(-k@3R~TV>pU%9);Is>k1ALh4LjXTHOhl!@sTRD#TcC~)?A8Og$t3xPap=;0
zDw$m0h73cI(>{W3p>?fZ9UU!bp*3kg6U(EGsb@smEi{P=@{uPA$SUI()E`
z#Flx(EAgIo<1O>>WTW#CD?#aop6!pOfqzKmuu0=49hDp_eHirk#X~}V3O>&YQ8ER=
zT~-VA+CwV*0Q8QoCln8`?_LO(mPK(eAKa}+1XPo7(}
zYQ8*wY(ZYEOWM`s`CgczPfJ`fRiXvUIV&$Nd7dAl^^rD`$PpG;p=4UfL+nB++J6+E
zt(yye2rlN!y2MEm#-@Mrwo)O&>ZgDiS6RW$-vq2ytNwC-H1F!wOk9oWL4h+IHd^00
c4KH9Q2^^9>giK!C1a=320 || TFT_WIDTH>=480
+#if TFT_HEIGHT>=480 || TFT_WIDTH>=480
#ifndef HASP_FONT_1
#define HASP_FONT_1 robotocondensed_regular_16_latin1 /* 5% Width */
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 61c03126..8e40b9ba 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -482,10 +482,10 @@ bool guiGetConfig(const JsonObject& settings)
settings[FPSTR(FP_GUI_ROTATION)] = gui_settings.rotation;
if(gui_settings.show_pointer != settings[FPSTR(FP_GUI_POINTER)].as()) changed = true;
- settings[FPSTR(FP_GUI_POINTER)] = gui_settings.show_pointer;
+ settings[FPSTR(FP_GUI_POINTER)] = (uint8_t)gui_settings.show_pointer;
if(gui_settings.invert_display != settings[FPSTR(FP_GUI_INVERT)].as()) changed = true;
- settings[FPSTR(FP_GUI_INVERT)] = gui_settings.invert_display;
+ settings[FPSTR(FP_GUI_INVERT)] = (uint8_t)gui_settings.invert_display;
/* Check CalData array has changed */
JsonArray array = settings[FPSTR(FP_GUI_CALIBRATION)].as();
@@ -545,8 +545,10 @@ bool guiSetConfig(const JsonObject& settings)
changed |= configSet(gui_settings.backlight_pin, settings[FPSTR(FP_GUI_BACKLIGHTPIN)], F("guiBacklightPin"));
changed |= configSet(guiSleepTime1, settings[FPSTR(FP_GUI_IDLEPERIOD1)], F("guiSleepTime1"));
changed |= configSet(guiSleepTime2, settings[FPSTR(FP_GUI_IDLEPERIOD2)], F("guiSleepTime2"));
- changed |= configSet(gui_settings.rotation, settings[FPSTR(FP_GUI_ROTATION)], F("gui_settings.rotation"));
- changed |= configSet(gui_settings.invert_display, settings[FPSTR(FP_GUI_INVERT)], F("guiInvertDisplay"));
+ changed |=
+ configSet(gui_settings.rotation, settings[FPSTR(FP_GUI_ROTATION)], F("gui_settings.rotation"));
+ changed |=
+ configSet(gui_settings.invert_display, settings[FPSTR(FP_GUI_INVERT)], F("guiInvertDisplay"));
hasp_set_sleep_time(guiSleepTime1, guiSleepTime2);
diff --git a/src/log/hasp_debug.cpp b/src/log/hasp_debug.cpp
index 8d7aca39..ba76afdd 100644
--- a/src/log/hasp_debug.cpp
+++ b/src/log/hasp_debug.cpp
@@ -139,8 +139,8 @@ bool debugGetConfig(const JsonObject& settings)
{
bool changed = false;
- if(debugAnsiCodes != settings[FPSTR(FP_DEBUG_ANSI)].as()) changed = true;
- settings[FPSTR(FP_DEBUG_ANSI)] = debugAnsiCodes;
+ if(debugAnsiCodes != settings[FPSTR(FP_DEBUG_ANSI)]) changed = true;
+ settings[FPSTR(FP_DEBUG_ANSI)] = (uint8_t)debugAnsiCodes;
if(debugSerialBaud != settings[FPSTR(FP_CONFIG_BAUD)].as()) changed = true;
settings[FPSTR(FP_CONFIG_BAUD)] = debugSerialBaud;
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index 612afcc3..14038270 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -322,8 +322,8 @@ bool saveConfig()
#endif
} else if(save == String(PSTR("gui"))) {
- settings[FPSTR(FP_GUI_POINTER)] = webServer.hasArg(PSTR("cur"));
- settings[FPSTR(FP_GUI_INVERT)] = webServer.hasArg(PSTR("inv"));
+ settings[FPSTR(FP_GUI_POINTER)] = webServer.hasArg(PSTR("cursor"));
+ settings[FPSTR(FP_GUI_INVERT)] = webServer.hasArg(PSTR("invert"));
updated = guiSetConfig(settings.as());
} else if(save == String(PSTR("debug"))) {
@@ -461,7 +461,7 @@ static void webHandleScreenshot()
////////////////////////////////////////////////////////////////////////////////////////////////////
static void add_json(String& data, JsonDocument& doc)
{
- char buffer[512];
+ char buffer[800];
size_t len = serializeJson(doc, buffer, sizeof(buffer));
if(doc.isNull()) return; // empty document
@@ -475,37 +475,77 @@ static void webHandleApi()
{ // http://plate01/about
if(!httpIsAuthenticated(F("api"))) return;
+ DynamicJsonDocument doc(800);
+ String contentType = getContentType(F(".json"));
String endpoint((char*)0);
endpoint = webServer.pathArg(0);
if(!strcasecmp_P(endpoint.c_str(), PSTR("info"))) {
- String htmldata((char*)0);
- htmldata.reserve(HTTP_PAGE_SIZE);
- DynamicJsonDocument doc(512);
-
- htmldata = "{";
+ String jsondata((char*)0);
+ jsondata.reserve(HTTP_PAGE_SIZE);
+ jsondata = "{";
hasp_get_info(doc);
- add_json(htmldata, doc);
+ add_json(jsondata, doc);
#if HASP_USE_MQTT > 0
mqtt_get_info(doc);
- add_json(htmldata, doc);
+ add_json(jsondata, doc);
#endif
network_get_info(doc);
- add_json(htmldata, doc);
+ add_json(jsondata, doc);
haspDevice.get_info(doc);
- add_json(htmldata, doc);
+ add_json(jsondata, doc);
- htmldata[htmldata.length() - 1] = '}'; // Replace last comma with a bracket
+ jsondata[jsondata.length() - 1] = '}'; // Replace last comma with a bracket
- String contentType = getContentType(F(".json"));
- webServer.send(200, contentType, htmldata);
+ webServer.send(200, contentType, jsondata);
+
+ } else {
+ webServer.send(400, contentType, "Bad Request");
}
}
+static void webHandleApiConfig()
+{ // http://plate01/about
+ if(!httpIsAuthenticated(F("api"))) return;
+
+ DynamicJsonDocument doc(800);
+ String contentType = getContentType(F(".json"));
+ String endpoint((char*)0);
+ endpoint = webServer.pathArg(0);
+
+ JsonObject settings = doc.to(); // Settings are invalid, force creation of an empty JsonObject
+
+ if(!strcasecmp_P(endpoint.c_str(), PSTR("wifi"))) {
+ wifiGetConfig(settings);
+ } else if(!strcasecmp_P(endpoint.c_str(), PSTR("mqtt"))) {
+ mqttGetConfig(settings);
+ } else if(!strcasecmp_P(endpoint.c_str(), PSTR("http"))) {
+ httpGetConfig(settings);
+ } else if(!strcasecmp_P(endpoint.c_str(), PSTR("gui"))) {
+ guiGetConfig(settings);
+ } else if(!strcasecmp_P(endpoint.c_str(), PSTR("debug"))) {
+ debugGetConfig(settings);
+ } else {
+ webServer.send(400, contentType, "Bad Request");
+ return;
+ }
+
+ if(!settings[FPSTR(FP_CONFIG_PASS)].isNull()) {
+ settings[FPSTR(FP_CONFIG_PASS)] = D_PASSWORD_MASK;
+ }
+
+ doc.shrinkToFit();
+ const size_t size = measureJson(doc) + 1;
+ char jsondata[size];
+ memset(jsondata, 0, size);
+ serializeJson(doc, jsondata, size);
+ webServer.send(200, contentType, jsondata);
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
static void webHandleAbout()
{ // http://plate01/about
@@ -518,39 +558,6 @@ static void webHandleAbout()
String httpMessage((char*)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
- /*
- httpMessage += F("
openHASP Copyright© 2019-2022 Francis Van Roie ");
- httpMessage += mitLicense;
- httpMessage += F("Based on the previous work of the following open source developers.
");
- httpMessage += F("
HASwitchPlate Copyright© 2019 Allen Derusha allen@derusha.org");
- httpMessage += mitLicense;
- httpMessage += F("
LVGL Copyright© 2021 LVGL Kft");
- httpMessage += mitLicense;
- httpMessage += F("
TFT_eSPI Library Copyright© 2020 Bodmer (https://github.com/Bodmer)
- All " "rights reserved.FreeBSD License
"); httpMessage += F("includes parts from the
- Adafruit_GFX library Copyright© 2012 Adafruit Industries. " "All rights reservedBSD
- License
"); httpMessage += F("
ArduinoJson Copyright© 2014-2021 Benoit BLANCHON");
- httpMessage += mitLicense;
- httpMessage += F("
PubSubClient Copyright© 2008-2015 Nicholas O'Leary");
- httpMessage += mitLicense;
- httpMessage += F("
FreeType Copyright© 1996-2002, 2006 David Turner, Robert Wilhelm, "
- "and Werner Lemberg.FreeType License");
- httpMessage +=
- F("
ArduinoLog Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, "
- "dhylands, Josha blemasle, mfalkvidd");
- httpMessage += mitLicense;
- #if HASP_USE_SYSLOG > 0
- // Replaced with WiFiUDP client
- // httpMessage += F("
Syslog Copyright© 2016 Martin Sloup");
- // httpMessage += mitLicense;
- #endif
- #if HASP_USE_QRCODE > 0
- httpMessage += F("
QR Code generator Copyright© Project Nayuki");
- httpMessage += mitLicense;
- #endif
- httpMessage += F("
AceButton Copyright© 2018 Brian T. Park");
- httpMessage += mitLicense;
- */
httpMessage += "
";
httpMessage += FPSTR(MAIN_MENU_BUTTON);
@@ -574,32 +581,7 @@ static void webHandleInfoJson()
htmldata += haspDevice.get_hostname();
htmldata += F(" ");
- htmldata += "
";
-
+ htmldata += "
";
htmldata += FPSTR(MAIN_MENU_BUTTON);
webSendHeader(haspDevice.get_hostname(), htmldata.length(), false);
@@ -844,8 +826,13 @@ static void handleFileUpload()
}
if(filename.length() < 32) {
fsUploadFile = HASP_FS.open(filename, "w");
- LOG_TRACE(TAG_HTTP, F("handleFileUpload Name: %s"), filename.c_str());
- haspProgressMsg(fsUploadFile.name());
+ if(!fsUploadFile || fsUploadFile.isDirectory()) {
+ LOG_WARNING(TAG_HTTP, F(D_FILE_SAVE_FAILED), filename.c_str());
+ fsUploadFile.close();
+ } else {
+ LOG_TRACE(TAG_HTTP, F("handleFileUpload Name: %s"), filename.c_str());
+ haspProgressMsg(fsUploadFile.name());
+ }
} else {
LOG_ERROR(TAG_HTTP, F("Filename %s is too long"), filename.c_str());
}
@@ -862,12 +849,15 @@ static void handleFileUpload()
if(fsUploadFile) {
LOG_INFO(TAG_HTTP, F("Uploaded %s (%u bytes)"), fsUploadFile.name(), upload->totalSize);
fsUploadFile.close();
+
+ // Redirect to /config/hasp page. This flushes the web buffer and frees the memory
+ webServer.sendHeader(String(F("Location")), String(F("/config/hasp")), true);
+ webServer.send_P(302, PSTR("text/plain"), "");
+ } else {
+ webServer.send_P(400, PSTR("text/plain"), "Bad Request");
}
haspProgressVal(255);
- // Redirect to /config/hasp page. This flushes the web buffer and frees the memory
- webServer.sendHeader(String(F("Location")), String(F("/config/hasp")), true);
- webServer.send_P(302, PSTR("text/plain"), "");
// httpReconnect();
}
}
@@ -1079,7 +1069,7 @@ static void webHandleMqttConfig()
httpMessage +=
F("
");
// Group Name
@@ -1087,7 +1077,7 @@ static void webHandleMqttConfig()
httpMessage +=
F("
");
// Broker
@@ -1095,14 +1085,14 @@ static void webHandleMqttConfig()
httpMessage += F("
");
// Mqtt Port
httpMessage += F("Port
");
httpMessage += F("
");
// Mqtt User
@@ -1110,7 +1100,7 @@ static void webHandleMqttConfig()
httpMessage += F("
");
// Mqtt Password
@@ -1118,7 +1108,7 @@ static void webHandleMqttConfig()
httpMessage += F("
");
// Submit & End Form
@@ -1126,6 +1116,8 @@ static void webHandleMqttConfig()
httpMessage += F("");
add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"));
+ httpMessage += "";
+
webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false);
webServer.sendContent(httpMessage);
}
@@ -1156,18 +1148,18 @@ static void webHandleGuiConfig()
httpMessage += F("Short Idle
");
httpMessage += F("
();
+ // httpMessage += settings[FPSTR(FP_GUI_IDLEPERIOD1)].as();
httpMessage += F("'>
");
// Long Idle
httpMessage += F("Long Idle
");
httpMessage += F("
();
+ // httpMessage += settings[FPSTR(FP_GUI_IDLEPERIOD2)].as();
httpMessage += F("'>
");
// Rotation
- int8_t rotation = settings[FPSTR(FP_GUI_ROTATION)].as();
+ int8_t rotation = -1; // settings[FPSTR(FP_GUI_ROTATION)].as();
httpMessage += F("Orientation
");
httpMessage += F("
");
httpMessage += getOption(0, F("0 degrees"), rotation);
@@ -1181,15 +1173,15 @@ static void webHandleGuiConfig()
httpMessage += F("
");
// Invert
- httpMessage += F("
");
- httpMessage += F("
()) httpMessage += F(" checked");
+ httpMessage += F("
");
+ httpMessage += F("
()) httpMessage += F(" checked");
httpMessage += F(">Invert Colors
");
// Cursor
- httpMessage += F("
");
- httpMessage += F("
()) httpMessage += F(" checked");
+ httpMessage += F("
");
+ httpMessage += F("
()) httpMessage += F(" checked");
httpMessage += F(">Show Pointer
");
// Backlight
@@ -1224,6 +1216,8 @@ static void webHandleGuiConfig()
add_form_button(httpMessage, F(D_HTTP_ANTIBURN), F("/config/gui?brn=1"));
add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"));
+ httpMessage += F("");
+
webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false);
webServer.sendContent(httpMessage);
}
@@ -1260,7 +1254,7 @@ static void webHandleWifiConfig()
httpMessage += F("
");
// Wifi Password
@@ -1268,9 +1262,9 @@ static void webHandleWifiConfig()
httpMessage += F("
");
// Submit & End Form
@@ -1283,6 +1277,8 @@ static void webHandleWifiConfig()
}
#endif
+ httpMessage += F("");
+
webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false);
webServer.sendContent(httpMessage);
}
@@ -1369,16 +1365,16 @@ static void webHandleHttpConfig()
httpMessage += F("
Username
");
httpMessage += F("
");
// Password
httpMessage += F("
Password
");
httpMessage += F("
");
// Submit & End Form
@@ -1386,6 +1382,7 @@ static void webHandleHttpConfig()
httpMessage += F("
");
httpMessage += F("
" D_HTTP_CONFIGURATION " ");
+ httpMessage += F("");
webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false);
webServer.sendContent(httpMessage);
@@ -1791,13 +1788,13 @@ static void webHandleDebugConfig()
httpMessage += F("
Telemetry Period
");
httpMessage += F("
();
+ // httpMessage += settings[FPSTR(FP_DEBUG_TELEPERIOD)].as();
httpMessage += F("'>
");
// Invert
httpMessage += F("
");
- httpMessage += F("
");
#if HASP_USE_SYSLOG > 0
@@ -1806,14 +1803,14 @@ static void webHandleDebugConfig()
httpMessage += F("
");
// Syslog Port
httpMessage += F("
Syslog Port
");
httpMessage += F("
();
+ // httpMessage += settings[FPSTR(FP_CONFIG_PORT)].as();
httpMessage += F("'>
");
// Syslog Facility
@@ -1829,9 +1826,9 @@ static void webHandleDebugConfig()
uint8_t proto = settings[FPSTR(FP_CONFIG_PROTOCOL)].as
();
httpMessage += F("");
#endif
@@ -1843,6 +1840,7 @@ static void webHandleDebugConfig()
// *******************************************************************
add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"));
+ httpMessage += F("");
webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false);
webServer.sendContent(httpMessage);
@@ -2301,7 +2299,8 @@ void httpSetup()
webServer.on(F("/vars.css"), webSendCssVars);
// webServer.on(F("/js"), webSendJavascript);
webServer.onNotFound(httpHandleNotFound);
- webServer.on(UriBraces(F("/api/{}")), webHandleApi);
+ webServer.on(UriBraces(F("/api/{}/")), webHandleApi);
+ webServer.on(UriBraces(F("/api/config/{}/")), webHandleApiConfig);
#if HASP_USE_WIFI > 0
// These two endpoints are needed in STA and AP mode
@@ -2474,16 +2473,17 @@ size_t httpClientWrite(const uint8_t* buf, size_t size)
size_t bytes_sent = 0;
while(bytes_sent < size) {
if(!webServer.client()) return bytes_sent;
- if(size - bytes_sent >= 2048) {
- bytes_sent += webServer.client().write(buf + bytes_sent, 2048);
+ if(size - bytes_sent >= 20480) {
+ bytes_sent += webServer.client().write(buf + bytes_sent, 20480); // 2048
+ delay(1); // Fixes the freeze
} else {
bytes_sent += webServer.client().write(buf + bytes_sent, size - bytes_sent);
+ return bytes_sent;
}
// Serial.println(bytes_sent);
// stm32_eth_scheduler(); // already in write
// webServer.client().flush();
- delay(1); // Fixes the freeze
}
return bytes_sent;
}