From cfaf1496dde6c053aa76096dd3ccd4fee5cabb41 Mon Sep 17 00:00:00 2001
From: Alessandro Ranellucci
Date: Fri, 27 Oct 2023 10:48:06 +0200
Subject: [PATCH 001/135] Allow long WiFi passwords in the GUI
---
src/hasp_oobe.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hasp_oobe.cpp b/src/hasp_oobe.cpp
index 291e3c47..f816afbd 100644
--- a/src/hasp_oobe.cpp
+++ b/src/hasp_oobe.cpp
@@ -213,7 +213,7 @@ static void oobeSetupSsid(void)
lv_obj_set_style_local_text_font(pwd_ta, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, defaultfont);
lv_textarea_set_text(pwd_ta, "");
- lv_textarea_set_max_length(pwd_ta, 32);
+ lv_textarea_set_max_length(pwd_ta, MAX_PASSWORD_LENGTH);
lv_textarea_set_pwd_mode(pwd_ta, true);
lv_textarea_set_one_line(pwd_ta, true);
lv_textarea_set_cursor_hidden(pwd_ta, true);
From 6cf4262f2356eaa686abe045ab01a5467a6963b1 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 27 Oct 2023 14:49:41 +0200
Subject: [PATCH 002/135] Update tools
---
.github/workflows/build.yaml | 3 +++
data/edit.htm | 2 +-
data/script.js | 2 +-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 3f8ea833..abcec923 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -85,6 +85,9 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio
+ - name: Install Setuptools
+ run: |
+ pip install --upgrade setuptools
- name: Enable ESP32 platforms from platformio_override-template.ini
run: |
sed 's/; user_setups\/esp32/user_setups\/esp32/g' platformio_override-template.ini > platformio_override.ini
diff --git a/data/edit.htm b/data/edit.htm
index 5811afc4..fd6b9350 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
+openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index f38d076c..c7b61782 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.24.2")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.31.0")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From a6cbcadffb248b7d4c8f4daec749dc99a3f16931 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 28 Nov 2023 16:09:15 +0100
Subject: [PATCH 003/135] Update to Tasmota Core 2023.11.01
---
user_setups/esp32/_esp32.ini | 3 ++-
user_setups/esp32c3/_esp32c3.ini | 7 +++----
user_setups/esp32s2/_esp32s2.ini | 4 ++--
user_setups/esp32s3/_esp32s3.ini | 7 +++----
4 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index 93d581ff..4969a65f 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -140,7 +140,8 @@ lib_deps =
extends = esp32
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
+; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
lib_ignore =
${esp32.lib_ignore}
diff --git a/user_setups/esp32c3/_esp32c3.ini b/user_setups/esp32c3/_esp32c3.ini
index 2053ab5d..29986468 100644
--- a/user_setups/esp32c3/_esp32c3.ini
+++ b/user_setups/esp32c3/_esp32c3.ini
@@ -16,7 +16,6 @@ no_ps_ram =
[arduino_esp32c3_v2]
extends = esp32c3
framework = arduino
-;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.01.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.07.00/platform-espressif32.zip
-;platform = espressif32@5.3.0
-
+; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
+; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
diff --git a/user_setups/esp32s2/_esp32s2.ini b/user_setups/esp32s2/_esp32s2.ini
index 82f1d9df..4b698887 100644
--- a/user_setups/esp32s2/_esp32s2.ini
+++ b/user_setups/esp32s2/_esp32s2.ini
@@ -75,7 +75,7 @@ fspi =
extends = esp32s2
framework = arduino
;platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.4.1/platform-espressif32-2.0.4.1.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.07.00/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
; =========================== SOLO ==============================================
@@ -83,7 +83,7 @@ platform = https://github.com/tasmota/platform-espressif32/releases/download/202
[arduino_esp32s2-solo_v2]
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.01.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.07.00/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
board_build.embed_files = ${esp32.board_build.embed_files}
board_build.filesystem = littlefs
; ----- crash reporter
diff --git a/user_setups/esp32s3/_esp32s3.ini b/user_setups/esp32s3/_esp32s3.ini
index ec88eb84..b5d517c0 100644
--- a/user_setups/esp32s3/_esp32s3.ini
+++ b/user_setups/esp32s3/_esp32s3.ini
@@ -15,7 +15,6 @@ no_ps_ram =
[arduino_esp32s3_v2]
extends = esp32s3
framework = arduino
-;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.01.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.07.00/platform-espressif32.zip
-;platform = espressif32@5.3.0
-
+; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
+; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
From 3fe34e17dfed6d2fd39e7217a58470d3eb33bd3a Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 28 Nov 2023 16:17:09 +0100
Subject: [PATCH 004/135] Fix esp_crt_bundle_set
---
src/mqtt/hasp_mqtt_esp.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mqtt/hasp_mqtt_esp.cpp b/src/mqtt/hasp_mqtt_esp.cpp
index 74488f85..f505002c 100644
--- a/src/mqtt/hasp_mqtt_esp.cpp
+++ b/src/mqtt/hasp_mqtt_esp.cpp
@@ -465,8 +465,8 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
void mqttSetup()
{
queue = xQueueCreate(64, sizeof(mqtt_message_t));
- //esp_crt_bundle_set(rootca_crt_bundle_start);
- arduino_esp_crt_bundle_set(rootca_crt_bundle_start);
+ esp_crt_bundle_set(rootca_crt_bundle_start, rootca_crt_bundle_end-rootca_crt_bundle_start);
+ //arduino_esp_crt_bundle_set(rootca_crt_bundle_start);
mqttStart();
}
From f32d78ee24b26352eda5dd2d058c029bb5aa2cf3 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 28 Nov 2023 16:17:38 +0100
Subject: [PATCH 005/135] update Adafruit STMPE610, TFT_eSPI and Arduino_GFX
---
platformio.ini | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/platformio.ini b/platformio.ini
index 3aa92a4b..2709870a 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -75,7 +75,7 @@ build_flags =
-D HASP_VER_MAJ=0
-D HASP_VER_MIN=7
;-D HASP_VER_REV=4
- -D HASP_VER_REV=0-rc8
+ -D HASP_VER_REV=0-rc9
;-D HASP_VER_REV=4-rc1
${override.build_flags}
@@ -108,12 +108,12 @@ lib_deps =
[arduinogfx]
lib_deps =
- ;moononournation/GFX Library for Arduino @ ^1.3.0
- git+https://github.com/moononournation/Arduino_GFX.git
+ moononournation/GFX Library for Arduino@1.4.0
+ ;git+https://github.com/moononournation/Arduino_GFX.git
[tft_espi]
lib_deps =
- bodmer/TFT_eSPI@2.5.0
+ bodmer/TFT_eSPI@2.5.34
;https://github.com/Bodmer/TFT_eSPI.git#master
[goodix]
@@ -130,4 +130,4 @@ lib_deps =
[stmpe610]
lib_deps =
- adafruit/Adafruit STMPE610@^1.1.4
\ No newline at end of file
+ adafruit/Adafruit STMPE610@^1.1.6
\ No newline at end of file
From 2228ca04cd3e9219ed2fb4d09f69f056a0a36e59 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 28 Nov 2023 17:56:36 +0100
Subject: [PATCH 006/135] update Tasmota Core 2023.10.03
---
user_setups/esp32/_esp32.ini | 2 +-
user_setups/esp32c3/_esp32c3.ini | 2 +-
user_setups/esp32s2/_esp32s2.ini | 4 ++--
user_setups/esp32s3/_esp32s3.ini | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index 4969a65f..5c17abc8 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -141,7 +141,7 @@ extends = esp32
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
lib_ignore =
${esp32.lib_ignore}
diff --git a/user_setups/esp32c3/_esp32c3.ini b/user_setups/esp32c3/_esp32c3.ini
index 29986468..fcf2fbff 100644
--- a/user_setups/esp32c3/_esp32c3.ini
+++ b/user_setups/esp32c3/_esp32c3.ini
@@ -18,4 +18,4 @@ extends = esp32c3
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
diff --git a/user_setups/esp32s2/_esp32s2.ini b/user_setups/esp32s2/_esp32s2.ini
index 4b698887..626e0b6e 100644
--- a/user_setups/esp32s2/_esp32s2.ini
+++ b/user_setups/esp32s2/_esp32s2.ini
@@ -75,7 +75,7 @@ fspi =
extends = esp32s2
framework = arduino
;platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.4.1/platform-espressif32-2.0.4.1.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
; =========================== SOLO ==============================================
@@ -83,7 +83,7 @@ platform = https://github.com/tasmota/platform-espressif32/releases/download/202
[arduino_esp32s2-solo_v2]
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.01.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
board_build.embed_files = ${esp32.board_build.embed_files}
board_build.filesystem = littlefs
; ----- crash reporter
diff --git a/user_setups/esp32s3/_esp32s3.ini b/user_setups/esp32s3/_esp32s3.ini
index b5d517c0..198975ba 100644
--- a/user_setups/esp32s3/_esp32s3.ini
+++ b/user_setups/esp32s3/_esp32s3.ini
@@ -17,4 +17,4 @@ extends = esp32s3
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
From 8d8fc0e976f06d1b4d805d20a39feb8a405d208c Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 28 Nov 2023 17:57:00 +0100
Subject: [PATCH 007/135] Revert esp_crt_bundle_set
---
src/mqtt/hasp_mqtt_esp.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mqtt/hasp_mqtt_esp.cpp b/src/mqtt/hasp_mqtt_esp.cpp
index f505002c..0b1c42ea 100644
--- a/src/mqtt/hasp_mqtt_esp.cpp
+++ b/src/mqtt/hasp_mqtt_esp.cpp
@@ -465,8 +465,8 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
void mqttSetup()
{
queue = xQueueCreate(64, sizeof(mqtt_message_t));
- esp_crt_bundle_set(rootca_crt_bundle_start, rootca_crt_bundle_end-rootca_crt_bundle_start);
- //arduino_esp_crt_bundle_set(rootca_crt_bundle_start);
+ //esp_crt_bundle_set(rootca_crt_bundle_start, rootca_crt_bundle_end-rootca_crt_bundle_start);
+ arduino_esp_crt_bundle_set(rootca_crt_bundle_start);
mqttStart();
}
From b7283c94988f88b6c1afc779c371fdce7a2f8f35 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 28 Nov 2023 21:46:21 +0100
Subject: [PATCH 008/135] Revert Tasmota core 2023.07.00 on S2
---
user_setups/esp32s2/_esp32s2.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_setups/esp32s2/_esp32s2.ini b/user_setups/esp32s2/_esp32s2.ini
index 626e0b6e..f21817b8 100644
--- a/user_setups/esp32s2/_esp32s2.ini
+++ b/user_setups/esp32s2/_esp32s2.ini
@@ -75,7 +75,7 @@ fspi =
extends = esp32s2
framework = arduino
;platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.4.1/platform-espressif32-2.0.4.1.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.07.00/platform-espressif32.zip
; =========================== SOLO ==============================================
From e092b72a6b296167777b4762b458552bcd9c1b5c Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 29 Nov 2023 18:10:27 +0100
Subject: [PATCH 009/135] always run idle scripts when sleep state changes
---
src/hasp/hasp.cpp | 14 +++++++-------
src/hasp/hasp.h | 2 +-
src/hasp/hasp_dispatch.cpp | 9 +++------
3 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index 9187f4ad..ad9cc5fd 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -119,20 +119,17 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state()
if(sleepTimeLong > 0 && idle >= (sleepTimeShort + sleepTimeLong)) {
if(hasp_sleep_state != HASP_SLEEP_LONG) {
gui_hide_pointer(true);
- hasp_sleep_state = HASP_SLEEP_LONG;
- dispatch_idle_state(HASP_SLEEP_LONG);
+ hasp_set_sleep_state(HASP_SLEEP_LONG, TAG_MAIN);
}
} else if(sleepTimeShort > 0 && idle >= sleepTimeShort) {
if(hasp_sleep_state != HASP_SLEEP_SHORT) {
gui_hide_pointer(true);
- hasp_sleep_state = HASP_SLEEP_SHORT;
- dispatch_idle_state(HASP_SLEEP_SHORT);
+ hasp_set_sleep_state(HASP_SLEEP_SHORT, TAG_MAIN);
}
} else {
if(hasp_sleep_state != HASP_SLEEP_OFF) {
gui_hide_pointer(false);
- hasp_sleep_state = HASP_SLEEP_OFF;
- dispatch_idle_state(HASP_SLEEP_OFF);
+ hasp_set_sleep_state(HASP_SLEEP_OFF, TAG_MAIN);
}
}
}
@@ -147,18 +144,21 @@ uint8_t hasp_get_sleep_state()
return hasp_sleep_state;
}
-void hasp_set_sleep_state(uint8_t state)
+void hasp_set_sleep_state(uint8_t state, uint8_t source)
{
switch(state) {
case HASP_SLEEP_LONG:
hasp_set_sleep_offset(sleepTimeShort + sleepTimeLong);
+ dispatch_run_script(NULL, "L:/idle_long.cmd", source);
break;
case HASP_SLEEP_SHORT:
hasp_set_sleep_offset(sleepTimeShort);
+ dispatch_run_script(NULL, "L:/idle_short.cmd", source);
break;
case HASP_SLEEP_OFF:
hasp_set_sleep_offset(0);
// hasp_set_wakeup_touch(false);
+ dispatch_run_script(NULL, "L:/idle_off.cmd", source);
break;
default:
return;
diff --git a/src/hasp/hasp.h b/src/hasp/hasp.h
index 4b9b5217..cf30abed 100644
--- a/src/hasp/hasp.h
+++ b/src/hasp/hasp.h
@@ -79,7 +79,7 @@ lv_font_t* hasp_get_font(uint8_t fontid);
HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state();
void hasp_get_sleep_payload(uint8_t state, char* payload);
uint8_t hasp_get_sleep_state();
-void hasp_set_sleep_state(uint8_t state);
+void hasp_set_sleep_state(uint8_t state, uint8_t source);
void hasp_get_sleep_time(uint16_t& short_time, uint16_t& long_time);
void hasp_set_sleep_time(uint16_t short_time, uint16_t long_time);
void hasp_set_sleep_offset(uint32_t offset);
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 86ca9818..acbc9734 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -1356,14 +1356,11 @@ void dispatch_idle(const char*, const char* payload, uint8_t source)
if(payload && strlen(payload)) {
uint8_t state = HASP_SLEEP_LAST;
if(!strcmp_P(payload, "off")) {
- hasp_set_sleep_state(HASP_SLEEP_OFF);
- dispatch_run_script(NULL, "L:/idle_off.cmd", source);
+ hasp_set_sleep_state(HASP_SLEEP_OFF, source);
} else if(!strcmp_P(payload, "short")) {
- hasp_set_sleep_state(HASP_SLEEP_SHORT);
- dispatch_run_script(NULL, "L:/idle_short.cmd", source);
+ hasp_set_sleep_state(HASP_SLEEP_SHORT, source);
} else if(!strcmp_P(payload, "long")) {
- hasp_set_sleep_state(HASP_SLEEP_LONG);
- dispatch_run_script(NULL, "L:/idle_long.cmd", source);
+ hasp_set_sleep_state(HASP_SLEEP_LONG, source);
} else {
LOG_WARNING(TAG_MSGR, F("Invalid idle value %s"), payload);
return;
From 58970f485e3e688d795196b421e0067d80d3b945 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Fri, 1 Dec 2023 19:51:58 +0100
Subject: [PATCH 010/135] use one allocation size for DynamicJsonDocument
settings
The problem was detected in configSetup() - the configuration was read
only from EEPROM but not from SPI flash FS.
Cleanup things and use only one allocation size for both write and read
configuration operations.
---
src/hasp_config.cpp | 4 ++--
src/hasp_config.h | 2 ++
src/sys/svc/hasp_http.cpp | 4 ++--
src/sys/svc/hasp_http_async.cpp | 2 +-
4 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index 61811a83..9e3f5ce5 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -354,7 +354,7 @@ void configWrite()
settingsChanged = F(D_CONFIG_CHANGED);
/* Read Config File */
- DynamicJsonDocument doc(8 * 256);
+ DynamicJsonDocument doc(MAX_CONFIG_JSON_ALLOC_SIZE);
LOG_TRACE(TAG_CONF, F(D_FILE_LOADING), configFile.c_str());
configRead(doc, false);
LOG_INFO(TAG_CONF, F(D_FILE_LOADED), configFile.c_str());
@@ -515,7 +515,7 @@ void configWrite()
void configSetup()
{
- DynamicJsonDocument settings(1024 + 512);
+ DynamicJsonDocument settings(MAX_CONFIG_JSON_ALLOC_SIZE);
for(uint32_t i = 0; i < 2; i++) {
if(i == 0) {
diff --git a/src/hasp_config.h b/src/hasp_config.h
index 3e465a95..df547408 100644
--- a/src/hasp_config.h
+++ b/src/hasp_config.h
@@ -8,6 +8,8 @@
#include "hasplib.h"
+#define MAX_CONFIG_JSON_ALLOC_SIZE (2048)
+
/* ===== Default Event Processors ===== */
void configSetup(void);
void configLoop(void);
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index 046c3831..d9b12158 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -561,7 +561,7 @@ static void webHandleApi()
{ // http://plate01/api
if(!http_is_authenticated("api")) return;
- DynamicJsonDocument doc(2048);
+ DynamicJsonDocument doc(max(MAX_CONFIG_JSON_ALLOC_SIZE, 2048));
String contentType = http_get_content_type(F(".json"));
String endpoint((char*)0);
endpoint = webServer.pathArg(0);
@@ -1109,7 +1109,7 @@ static inline int handleFilesystemFile(String path)
configFile = FPSTR(FP_HASP_CONFIG_FILE);
if(path.endsWith(configFile.c_str())) { // "//config.json" is also a valid path!
- DynamicJsonDocument settings(2048);
+ DynamicJsonDocument settings(MAX_CONFIG_JSON_ALLOC_SIZE);
DeserializationError error = configParseFile(configFile, settings);
if(error) return 500; // Internal Server Error
diff --git a/src/sys/svc/hasp_http_async.cpp b/src/sys/svc/hasp_http_async.cpp
index 13d51d20..9232cf0d 100644
--- a/src/sys/svc/hasp_http_async.cpp
+++ b/src/sys/svc/hasp_http_async.cpp
@@ -934,7 +934,7 @@ int handleFileRead(AsyncWebServerRequest* request, String path)
if(!strncasecmp(file.name(), configFile.c_str(), configFile.length())) {
file.close();
- DynamicJsonDocument settings(8 * 256);
+ DynamicJsonDocument settings(MAX_CONFIG_JSON_ALLOC_SIZE);
DeserializationError error = configParseFile(configFile, settings);
if(error) return 500; // Internal Server Error
From 45dd1ed4382aa4a7cbc72b6dabb3cad958943a1b Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 29 Nov 2023 20:41:28 +0100
Subject: [PATCH 011/135] Add wireguard library from
https://github.com/ciniml/WireGuard-ESP32-Arduino
---
lib/WireGuard-ESP32/.gitignore | 1 +
lib/WireGuard-ESP32/LICENSE | 28 +
lib/WireGuard-ESP32/README.md | 57 +
lib/WireGuard-ESP32/library.properties | 10 +
lib/WireGuard-ESP32/src/WireGuard-ESP32.h | 17 +
lib/WireGuard-ESP32/src/WireGuard.cpp | 147 +++
lib/WireGuard-ESP32/src/crypto.c | 23 +
lib/WireGuard-ESP32/src/crypto.h | 102 ++
lib/WireGuard-ESP32/src/crypto/refc/blake2s.c | 156 +++
lib/WireGuard-ESP32/src/crypto/refc/blake2s.h | 39 +
.../src/crypto/refc/chacha20.c | 202 +++
.../src/crypto/refc/chacha20.h | 53 +
.../src/crypto/refc/chacha20poly1305.c | 193 +++
.../src/crypto/refc/chacha20poly1305.h | 50 +
.../src/crypto/refc/poly1305-donna-32.h | 220 ++++
.../src/crypto/refc/poly1305-donna.c | 41 +
.../src/crypto/refc/poly1305-donna.h | 16 +
.../src/crypto/refc/x25519-license.txt | 21 +
lib/WireGuard-ESP32/src/crypto/refc/x25519.c | 448 +++++++
lib/WireGuard-ESP32/src/crypto/refc/x25519.h | 129 ++
lib/WireGuard-ESP32/src/wireguard-platform.c | 68 +
lib/WireGuard-ESP32/src/wireguard-platform.h | 71 ++
lib/WireGuard-ESP32/src/wireguard.c | 1129 +++++++++++++++++
lib/WireGuard-ESP32/src/wireguard.h | 287 +++++
lib/WireGuard-ESP32/src/wireguardif.c | 1028 +++++++++++++++
lib/WireGuard-ESP32/src/wireguardif.h | 137 ++
26 files changed, 4673 insertions(+)
create mode 100644 lib/WireGuard-ESP32/.gitignore
create mode 100644 lib/WireGuard-ESP32/LICENSE
create mode 100644 lib/WireGuard-ESP32/README.md
create mode 100644 lib/WireGuard-ESP32/library.properties
create mode 100644 lib/WireGuard-ESP32/src/WireGuard-ESP32.h
create mode 100644 lib/WireGuard-ESP32/src/WireGuard.cpp
create mode 100644 lib/WireGuard-ESP32/src/crypto.c
create mode 100644 lib/WireGuard-ESP32/src/crypto.h
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/blake2s.c
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/blake2s.h
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/chacha20.c
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/chacha20.h
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.c
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.h
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna-32.h
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.c
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.h
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/x25519-license.txt
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/x25519.c
create mode 100644 lib/WireGuard-ESP32/src/crypto/refc/x25519.h
create mode 100644 lib/WireGuard-ESP32/src/wireguard-platform.c
create mode 100644 lib/WireGuard-ESP32/src/wireguard-platform.h
create mode 100644 lib/WireGuard-ESP32/src/wireguard.c
create mode 100644 lib/WireGuard-ESP32/src/wireguard.h
create mode 100644 lib/WireGuard-ESP32/src/wireguardif.c
create mode 100644 lib/WireGuard-ESP32/src/wireguardif.h
diff --git a/lib/WireGuard-ESP32/.gitignore b/lib/WireGuard-ESP32/.gitignore
new file mode 100644
index 00000000..c07a74de
--- /dev/null
+++ b/lib/WireGuard-ESP32/.gitignore
@@ -0,0 +1 @@
+build.sh
\ No newline at end of file
diff --git a/lib/WireGuard-ESP32/LICENSE b/lib/WireGuard-ESP32/LICENSE
new file mode 100644
index 00000000..3856ceb1
--- /dev/null
+++ b/lib/WireGuard-ESP32/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2021 Kenta Ida (fuga@fugafuga.org)
+Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+* Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ its contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Author: Daniel Hope
+
diff --git a/lib/WireGuard-ESP32/README.md b/lib/WireGuard-ESP32/README.md
new file mode 100644
index 00000000..25424faa
--- /dev/null
+++ b/lib/WireGuard-ESP32/README.md
@@ -0,0 +1,57 @@
+# WireGuard Implementation for ESP32 Arduino
+
+This is an implementation of the [WireGuard®](https://www.wireguard.com/) for ESP32 Arduino.
+
+Almost all of this code is based on the [WireGuard Implementation for lwIP](https://github.com/smartalock/wireguard-lwip), but some potion of the code is adjusted to build with ESP32 Arduino.
+
+## How to use
+
+1. Include `WireGuard-ESP32.h` at the early part of the sketch.
+
+```c++
+#include
+```
+
+2. Define the instance of the `WireGuard` class at module level.
+
+```c++
+static WireGuard wg;
+```
+
+3. Connect to WiFi AP by using `WiFi` class.
+
+```c++
+WiFi.begin(ssid, password);
+while( !WiFi.isConnected() ) {
+ delay(1000);
+}
+```
+
+4. Sync the system time via NTP.
+
+```c++
+configTime(9 * 60 * 60, 0, "ntp.jst.mfeed.ad.jp", "ntp.nict.jp", "time.google.com");
+```
+
+5. Start the WireGuard interface.
+
+```c++
+wg.begin(
+ local_ip, // IP address of the local interface
+ private_key, // Private key of the local interface
+ endpoint_address, // Address of the endpoint peer.
+ public_key, // Public key of the endpoint peer.
+ endpoint_port); // Port pf the endpoint peer.
+```
+
+You can see an example sketch `uptime_post.ino`, which connects SORACOM Arc WireGuard endpoint and post uptime to SORACOM Harvest via WireGuard connection.
+
+## License
+
+The original WireGuard implementation for lwIP is licensed under BSD 3 clause license so the code in this repository also licensed under the same license.
+
+Original license is below:
+
+The code is copyrighted under BSD 3 clause Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+
+See LICENSE for details
diff --git a/lib/WireGuard-ESP32/library.properties b/lib/WireGuard-ESP32/library.properties
new file mode 100644
index 00000000..d51576d6
--- /dev/null
+++ b/lib/WireGuard-ESP32/library.properties
@@ -0,0 +1,10 @@
+name=WireGuard-ESP32
+version=0.1.5
+author=Kenta Ida
+maintainer=Kenta Ida
+sentence=WireGuard implementation for Arduino ESP32
+paragraph=
+category=Communication
+url=https://github.com/ciniml/WireGuard-ESP32-Arduino
+includes=WireGuard-ESP32.h
+architectures=esp32,Inkplate
diff --git a/lib/WireGuard-ESP32/src/WireGuard-ESP32.h b/lib/WireGuard-ESP32/src/WireGuard-ESP32.h
new file mode 100644
index 00000000..b30c884a
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/WireGuard-ESP32.h
@@ -0,0 +1,17 @@
+/*
+ * WireGuard implementation for ESP32 Arduino by Kenta Ida (fuga@fugafuga.org)
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#pragma once
+#include
+
+class WireGuard
+{
+private:
+ bool _is_initialized = false;
+public:
+ bool begin(const IPAddress& localIP, const IPAddress& Subnet, const IPAddress& Gateway, const char* privateKey, const char* remotePeerAddress, const char* remotePeerPublicKey, uint16_t remotePeerPort);
+ bool begin(const IPAddress& localIP, const char* privateKey, const char* remotePeerAddress, const char* remotePeerPublicKey, uint16_t remotePeerPort);
+ void end();
+ bool is_initialized() const { return this->_is_initialized; }
+};
diff --git a/lib/WireGuard-ESP32/src/WireGuard.cpp b/lib/WireGuard-ESP32/src/WireGuard.cpp
new file mode 100644
index 00000000..ce69650e
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/WireGuard.cpp
@@ -0,0 +1,147 @@
+/*
+ * WireGuard implementation for ESP32 Arduino by Kenta Ida (fuga@fugafuga.org)
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "WireGuard-ESP32.h"
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "esp_system.h"
+
+#include "lwip/err.h"
+#include "lwip/sys.h"
+#include "lwip/ip.h"
+#include "lwip/netdb.h"
+
+#include "esp32-hal-log.h"
+
+extern "C" {
+#include "wireguardif.h"
+#include "wireguard-platform.h"
+}
+
+// Wireguard instance
+static struct netif wg_netif_struct = {0};
+static struct netif *wg_netif = NULL;
+static struct netif *previous_default_netif = NULL;
+static uint8_t wireguard_peer_index = WIREGUARDIF_INVALID_INDEX;
+
+#define TAG "[WireGuard] "
+
+bool WireGuard::begin(const IPAddress& localIP, const IPAddress& Subnet, const IPAddress& Gateway, const char* privateKey, const char* remotePeerAddress, const char* remotePeerPublicKey, uint16_t remotePeerPort) {
+ struct wireguardif_init_data wg;
+ struct wireguardif_peer peer;
+ ip_addr_t ipaddr = IPADDR4_INIT(static_cast(localIP));
+ ip_addr_t netmask = IPADDR4_INIT(static_cast(Subnet));
+ ip_addr_t gateway = IPADDR4_INIT(static_cast(Gateway));
+
+ assert(privateKey != NULL);
+ assert(remotePeerAddress != NULL);
+ assert(remotePeerPublicKey != NULL);
+ assert(remotePeerPort != 0);
+
+ // Setup the WireGuard device structure
+ wg.private_key = privateKey;
+ wg.listen_port = remotePeerPort;
+
+ wg.bind_netif = NULL;
+
+ // Initialise the first WireGuard peer structure
+ wireguardif_peer_init(&peer);
+ // If we know the endpoint's address can add here
+ bool success_get_endpoint_ip = false;
+ for(int retry = 0; retry < 5; retry++) {
+ ip_addr_t endpoint_ip = IPADDR4_INIT_BYTES(0, 0, 0, 0);
+ struct addrinfo *res = NULL;
+ struct addrinfo hint;
+ memset(&hint, 0, sizeof(hint));
+ memset(&endpoint_ip, 0, sizeof(endpoint_ip));
+ if( lwip_getaddrinfo(remotePeerAddress, NULL, &hint, &res) != 0 ) {
+ vTaskDelay(pdMS_TO_TICKS(2000));
+ continue;
+ }
+ success_get_endpoint_ip = true;
+ struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
+ inet_addr_to_ip4addr(ip_2_ip4(&endpoint_ip), &addr4);
+ lwip_freeaddrinfo(res);
+
+ peer.endpoint_ip = endpoint_ip;
+ log_i(TAG "%s is %3d.%3d.%3d.%3d"
+ , remotePeerAddress
+ , (endpoint_ip.u_addr.ip4.addr >> 0) & 0xff
+ , (endpoint_ip.u_addr.ip4.addr >> 8) & 0xff
+ , (endpoint_ip.u_addr.ip4.addr >> 16) & 0xff
+ , (endpoint_ip.u_addr.ip4.addr >> 24) & 0xff
+ );
+ break;
+ }
+ if( !success_get_endpoint_ip ) {
+ log_e(TAG "failed to get endpoint ip.");
+ return false;
+ }
+ // Register the new WireGuard network interface with lwIP
+ wg_netif = netif_add(&wg_netif_struct, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gateway), &wg, &wireguardif_init, &ip_input);
+ if( wg_netif == nullptr ) {
+ log_e(TAG "failed to initialize WG netif.");
+ return false;
+ }
+ // Mark the interface as administratively up, link up flag is set automatically when peer connects
+ netif_set_up(wg_netif);
+
+ peer.public_key = remotePeerPublicKey;
+ peer.preshared_key = NULL;
+ // Allow all IPs through tunnel
+ {
+ ip_addr_t allowed_ip = IPADDR4_INIT_BYTES(0, 0, 0, 0);
+ peer.allowed_ip = allowed_ip;
+ ip_addr_t allowed_mask = IPADDR4_INIT_BYTES(0, 0, 0, 0);
+ peer.allowed_mask = allowed_mask;
+ }
+
+ peer.endport_port = remotePeerPort;
+
+ // Initialize the platform
+ wireguard_platform_init();
+ // Register the new WireGuard peer with the netwok interface
+ wireguardif_add_peer(wg_netif, &peer, &wireguard_peer_index);
+ if ((wireguard_peer_index != WIREGUARDIF_INVALID_INDEX) && !ip_addr_isany(&peer.endpoint_ip)) {
+ // Start outbound connection to peer
+ log_i(TAG "connecting wireguard...");
+ wireguardif_connect(wg_netif, wireguard_peer_index);
+ // Save the current default interface for restoring when shutting down the WG interface.
+ previous_default_netif = netif_default;
+ // Set default interface to WG device.
+ netif_set_default(wg_netif);
+ }
+
+ this->_is_initialized = true;
+ return true;
+}
+
+bool WireGuard::begin(const IPAddress& localIP, const char* privateKey, const char* remotePeerAddress, const char* remotePeerPublicKey, uint16_t remotePeerPort) {
+ // Maintain compatiblity with old begin
+ auto subnet = IPAddress(255,255,255,255);
+ auto gateway = IPAddress(0,0,0,0);
+ return WireGuard::begin(localIP, subnet, gateway, privateKey, remotePeerAddress, remotePeerPublicKey, remotePeerPort);
+}
+
+void WireGuard::end() {
+ if( !this->_is_initialized ) return;
+
+ // Restore the default interface.
+ netif_set_default(previous_default_netif);
+ previous_default_netif = nullptr;
+ // Disconnect the WG interface.
+ wireguardif_disconnect(wg_netif, wireguard_peer_index);
+ // Remove peer from the WG interface
+ wireguardif_remove_peer(wg_netif, wireguard_peer_index);
+ wireguard_peer_index = WIREGUARDIF_INVALID_INDEX;
+ // Shutdown the wireguard interface.
+ wireguardif_shutdown(wg_netif);
+ // Remove the WG interface;
+ netif_remove(wg_netif);
+ wg_netif = nullptr;
+
+ this->_is_initialized = false;
+}
\ No newline at end of file
diff --git a/lib/WireGuard-ESP32/src/crypto.c b/lib/WireGuard-ESP32/src/crypto.c
new file mode 100644
index 00000000..3597b86b
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto.c
@@ -0,0 +1,23 @@
+#include "crypto.h"
+
+#include
+#include
+#include
+
+void crypto_zero(void *dest, size_t len) {
+ volatile uint8_t *p = (uint8_t *)dest;
+ while (len--) {
+ *p++ = 0;
+ }
+}
+
+bool crypto_equal(const void *a, const void *b, size_t size) {
+ uint8_t neq = 0;
+ while (size > 0) {
+ neq |= *(uint8_t *)a ^ *(uint8_t *)b;
+ a += 1;
+ b += 1;
+ size -= 1;
+ }
+ return (neq) ? false : true;
+}
diff --git a/lib/WireGuard-ESP32/src/crypto.h b/lib/WireGuard-ESP32/src/crypto.h
new file mode 100644
index 00000000..c5d640d5
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto.h
@@ -0,0 +1,102 @@
+#ifndef _CRYPTO_H_
+#define _CRYPTO_H_
+
+#include
+#include
+#include
+
+// BLAKE2S IMPLEMENTATION
+#include "crypto/refc/blake2s.h"
+#define wireguard_blake2s_ctx blake2s_ctx
+#define wireguard_blake2s_init(ctx,outlen,key,keylen) blake2s_init(ctx,outlen,key,keylen)
+#define wireguard_blake2s_update(ctx,in,inlen) blake2s_update(ctx,in,inlen)
+#define wireguard_blake2s_final(ctx,out) blake2s_final(ctx,out)
+#define wireguard_blake2s(out,outlen,key,keylen,in,inlen) blake2s(out,outlen,key,keylen,in,inlen)
+
+// X25519 IMPLEMENTATION
+#include "crypto/refc/x25519.h"
+#define wireguard_x25519(a,b,c) x25519(a,b,c,1)
+
+// CHACHA20POLY1305 IMPLEMENTATION
+#include "crypto/refc/chacha20poly1305.h"
+#define wireguard_aead_encrypt(dst,src,srclen,ad,adlen,nonce,key) chacha20poly1305_encrypt(dst,src,srclen,ad,adlen,nonce,key)
+#define wireguard_aead_decrypt(dst,src,srclen,ad,adlen,nonce,key) chacha20poly1305_decrypt(dst,src,srclen,ad,adlen,nonce,key)
+#define wireguard_xaead_encrypt(dst,src,srclen,ad,adlen,nonce,key) xchacha20poly1305_encrypt(dst,src,srclen,ad,adlen,nonce,key)
+#define wireguard_xaead_decrypt(dst,src,srclen,ad,adlen,nonce,key) xchacha20poly1305_decrypt(dst,src,srclen,ad,adlen,nonce,key)
+
+
+// Endian / unaligned helper macros
+#define U8C(v) (v##U)
+#define U32C(v) (v##U)
+
+#define U8V(v) ((uint8_t)(v) & U8C(0xFF))
+#define U32V(v) ((uint32_t)(v) & U32C(0xFFFFFFFF))
+
+#define U8TO32_LITTLE(p) \
+ (((uint32_t)((p)[0]) ) | \
+ ((uint32_t)((p)[1]) << 8) | \
+ ((uint32_t)((p)[2]) << 16) | \
+ ((uint32_t)((p)[3]) << 24))
+
+#define U8TO64_LITTLE(p) \
+ (((uint64_t)((p)[0]) ) | \
+ ((uint64_t)((p)[1]) << 8) | \
+ ((uint64_t)((p)[2]) << 16) | \
+ ((uint64_t)((p)[3]) << 24) | \
+ ((uint64_t)((p)[4]) << 32) | \
+ ((uint64_t)((p)[5]) << 40) | \
+ ((uint64_t)((p)[6]) << 48) | \
+ ((uint64_t)((p)[7]) << 56))
+
+#define U16TO8_BIG(p, v) \
+ do { \
+ (p)[1] = U8V((v) ); \
+ (p)[0] = U8V((v) >> 8); \
+ } while (0)
+
+#define U32TO8_LITTLE(p, v) \
+ do { \
+ (p)[0] = U8V((v) ); \
+ (p)[1] = U8V((v) >> 8); \
+ (p)[2] = U8V((v) >> 16); \
+ (p)[3] = U8V((v) >> 24); \
+ } while (0)
+
+#define U32TO8_BIG(p, v) \
+ do { \
+ (p)[3] = U8V((v) ); \
+ (p)[2] = U8V((v) >> 8); \
+ (p)[1] = U8V((v) >> 16); \
+ (p)[0] = U8V((v) >> 24); \
+ } while (0)
+
+#define U64TO8_LITTLE(p, v) \
+ do { \
+ (p)[0] = U8V((v) ); \
+ (p)[1] = U8V((v) >> 8); \
+ (p)[2] = U8V((v) >> 16); \
+ (p)[3] = U8V((v) >> 24); \
+ (p)[4] = U8V((v) >> 32); \
+ (p)[5] = U8V((v) >> 40); \
+ (p)[6] = U8V((v) >> 48); \
+ (p)[7] = U8V((v) >> 56); \
+} while (0)
+
+#define U64TO8_BIG(p, v) \
+ do { \
+ (p)[7] = U8V((v) ); \
+ (p)[6] = U8V((v) >> 8); \
+ (p)[5] = U8V((v) >> 16); \
+ (p)[4] = U8V((v) >> 24); \
+ (p)[3] = U8V((v) >> 32); \
+ (p)[2] = U8V((v) >> 40); \
+ (p)[1] = U8V((v) >> 48); \
+ (p)[0] = U8V((v) >> 56); \
+} while (0)
+
+
+void crypto_zero(void *dest, size_t len);
+bool crypto_equal(const void *a, const void *b, size_t size);
+
+#endif /* _CRYPTO_H_ */
+
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/blake2s.c b/lib/WireGuard-ESP32/src/crypto/refc/blake2s.c
new file mode 100644
index 00000000..ae5e14ca
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/blake2s.c
@@ -0,0 +1,156 @@
+// Taken from RFC7693 - https://tools.ietf.org/html/rfc7693
+
+#include "blake2s.h"
+#include "../../crypto.h"
+
+// Cyclic right rotation.
+
+#ifndef ROTR32
+#define ROTR32(x, y) (((x) >> (y)) ^ ((x) << (32 - (y))))
+#endif
+
+// Mixing function G.
+#define B2S_G(a, b, c, d, x, y) { \
+ v[a] = v[a] + v[b] + x; \
+ v[d] = ROTR32(v[d] ^ v[a], 16); \
+ v[c] = v[c] + v[d]; \
+ v[b] = ROTR32(v[b] ^ v[c], 12); \
+ v[a] = v[a] + v[b] + y; \
+ v[d] = ROTR32(v[d] ^ v[a], 8); \
+ v[c] = v[c] + v[d]; \
+ v[b] = ROTR32(v[b] ^ v[c], 7); }
+
+// Initialization Vector.
+static const uint32_t blake2s_iv[8] =
+{
+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
+};
+
+// Compression function. "last" flag indicates last block.
+static void blake2s_compress(blake2s_ctx *ctx, int last)
+{
+ const uint8_t sigma[10][16] = {
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }
+ };
+ int i;
+ uint32_t v[16], m[16];
+
+ for (i = 0; i < 8; i++) { // init work variables
+ v[i] = ctx->h[i];
+ v[i + 8] = blake2s_iv[i];
+ }
+
+ v[12] ^= ctx->t[0]; // low 32 bits of offset
+ v[13] ^= ctx->t[1]; // high 32 bits
+ if (last) // last block flag set ?
+ v[14] = ~v[14];
+ for (i = 0; i < 16; i++) // get little-endian words
+ m[i] = U8TO32_LITTLE(&ctx->b[4 * i]);
+
+ for (i = 0; i < 10; i++) { // ten rounds
+ B2S_G( 0, 4, 8, 12, m[sigma[i][ 0]], m[sigma[i][ 1]]);
+ B2S_G( 1, 5, 9, 13, m[sigma[i][ 2]], m[sigma[i][ 3]]);
+ B2S_G( 2, 6, 10, 14, m[sigma[i][ 4]], m[sigma[i][ 5]]);
+ B2S_G( 3, 7, 11, 15, m[sigma[i][ 6]], m[sigma[i][ 7]]);
+ B2S_G( 0, 5, 10, 15, m[sigma[i][ 8]], m[sigma[i][ 9]]);
+ B2S_G( 1, 6, 11, 12, m[sigma[i][10]], m[sigma[i][11]]);
+ B2S_G( 2, 7, 8, 13, m[sigma[i][12]], m[sigma[i][13]]);
+ B2S_G( 3, 4, 9, 14, m[sigma[i][14]], m[sigma[i][15]]);
+ }
+
+ for( i = 0; i < 8; ++i )
+ ctx->h[i] ^= v[i] ^ v[i + 8];
+}
+
+// Initialize the hashing context "ctx" with optional key "key".
+// 1 <= outlen <= 32 gives the digest size in bytes.
+// Secret key (also <= 32 bytes) is optional (keylen = 0).
+int blake2s_init(blake2s_ctx *ctx, size_t outlen,
+ const void *key, size_t keylen) // (keylen=0: no key)
+{
+ size_t i;
+
+ if (outlen == 0 || outlen > 32 || keylen > 32)
+ return -1; // illegal parameters
+
+ for (i = 0; i < 8; i++) // state, "param block"
+ ctx->h[i] = blake2s_iv[i];
+ ctx->h[0] ^= 0x01010000 ^ (keylen << 8) ^ outlen;
+
+ ctx->t[0] = 0; // input count low word
+ ctx->t[1] = 0; // input count high word
+ ctx->c = 0; // pointer within buffer
+ ctx->outlen = outlen;
+
+ for (i = keylen; i < 64; i++) // zero input block
+ ctx->b[i] = 0;
+ if (keylen > 0) {
+ blake2s_update(ctx, key, keylen);
+ ctx->c = 64; // at the end
+ }
+
+ return 0;
+}
+
+// Add "inlen" bytes from "in" into the hash.
+void blake2s_update(blake2s_ctx *ctx,
+ const void *in, size_t inlen) // data bytes
+{
+ size_t i;
+
+ for (i = 0; i < inlen; i++) {
+ if (ctx->c == 64) { // buffer full ?
+ ctx->t[0] += ctx->c; // add counters
+ if (ctx->t[0] < ctx->c) // carry overflow ?
+ ctx->t[1]++; // high word
+ blake2s_compress(ctx, 0); // compress (not last)
+ ctx->c = 0; // counter to zero
+ }
+ ctx->b[ctx->c++] = ((const uint8_t *) in)[i];
+ }
+}
+
+// Generate the message digest (size given in init).
+// Result placed in "out".
+void blake2s_final(blake2s_ctx *ctx, void *out)
+{
+ size_t i;
+
+ ctx->t[0] += ctx->c; // mark last block offset
+ if (ctx->t[0] < ctx->c) // carry overflow
+ ctx->t[1]++; // high word
+
+ while (ctx->c < 64) // fill up with zeros
+ ctx->b[ctx->c++] = 0;
+ blake2s_compress(ctx, 1); // final block flag = 1
+
+ // little endian convert and store
+ for (i = 0; i < ctx->outlen; i++) {
+ ((uint8_t *) out)[i] =
+ (ctx->h[i >> 2] >> (8 * (i & 3))) & 0xFF;
+ }
+}
+
+// Convenience function for all-in-one computation.
+int blake2s(void *out, size_t outlen,
+ const void *key, size_t keylen,
+ const void *in, size_t inlen)
+{
+ blake2s_ctx ctx;
+ if (blake2s_init(&ctx, outlen, key, keylen))
+ return -1;
+ blake2s_update(&ctx, in, inlen);
+ blake2s_final(&ctx, out);
+
+ return 0;
+}
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/blake2s.h b/lib/WireGuard-ESP32/src/crypto/refc/blake2s.h
new file mode 100644
index 00000000..4b056467
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/blake2s.h
@@ -0,0 +1,39 @@
+// Taken from RFC7693 - https://tools.ietf.org/html/rfc7693
+// BLAKE2s Hashing Context and API Prototypes
+#ifndef _BLAKE2S_H
+#define _BLAKE2S_H
+
+#define BLAKE2S_BLOCK_SIZE 64
+
+#include
+#include
+
+// state context
+typedef struct {
+ uint8_t b[64]; // input buffer
+ uint32_t h[8]; // chained state
+ uint32_t t[2]; // total number of bytes
+ size_t c; // pointer for b[]
+ size_t outlen; // digest size
+} blake2s_ctx;
+
+// Initialize the hashing context "ctx" with optional key "key".
+// 1 <= outlen <= 32 gives the digest size in bytes.
+// Secret key (also <= 32 bytes) is optional (keylen = 0).
+int blake2s_init(blake2s_ctx *ctx, size_t outlen,
+ const void *key, size_t keylen); // secret key
+
+// Add "inlen" bytes from "in" into the hash.
+void blake2s_update(blake2s_ctx *ctx, // context
+ const void *in, size_t inlen); // data to be hashed
+
+// Generate the message digest (size given in init).
+// Result placed in "out".
+void blake2s_final(blake2s_ctx *ctx, void *out);
+
+// All-in-one convenience function.
+int blake2s(void *out, size_t outlen, // return buffer for digest
+ const void *key, size_t keylen, // optional secret key
+ const void *in, size_t inlen); // data to be hashed
+
+#endif
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/chacha20.c b/lib/WireGuard-ESP32/src/crypto/refc/chacha20.c
new file mode 100644
index 00000000..52c4dd6e
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/chacha20.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+// RFC7539 implementation of ChaCha20 with modified nonce size for WireGuard
+// https://tools.ietf.org/html/rfc7539
+// Adapted from https://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/ref/chacha.c by D. J. Bernstein (Public Domain)
+// HChaCha20 is described here: https://tools.ietf.org/id/draft-arciszewski-xchacha-02.html
+
+#include "chacha20.h"
+
+#include
+#include
+#include "../../crypto.h"
+
+// 2.3. The ChaCha20 Block Function
+// The first four words (0-3) are constants: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
+static const uint32_t CHACHA20_CONSTANT_1 = 0x61707865;
+static const uint32_t CHACHA20_CONSTANT_2 = 0x3320646e;
+static const uint32_t CHACHA20_CONSTANT_3 = 0x79622d32;
+static const uint32_t CHACHA20_CONSTANT_4 = 0x6b206574;
+
+#define ROTL32(v, n) (U32V((v) << (n)) | ((v) >> (32 - (n))))
+
+#define PLUS(v,w) (U32V((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+
+// 2.1. The ChaCha Quarter Round
+// 1. a += b; d ^= a; d <<<= 16;
+// 2. c += d; b ^= c; b <<<= 12;
+// 3. a += b; d ^= a; d <<<= 8;
+// 4. c += d; b ^= c; b <<<= 7;
+
+#define QUARTERROUND(a, b, c, d) \
+ a += b; d ^= a; d = ROTL32(d, 16); \
+ c += d; b ^= c; b = ROTL32(b, 12); \
+ a += b; d ^= a; d = ROTL32(d, 8); \
+ c += d; b ^= c; b = ROTL32(b, 7)
+
+static inline void INNER_BLOCK(uint32_t *block) {
+ QUARTERROUND(block[0], block[4], block[ 8], block[12]); // column 0
+ QUARTERROUND(block[1], block[5], block[ 9], block[13]); // column 1
+ QUARTERROUND(block[2], block[6], block[10], block[14]); // column 2
+ QUARTERROUND(block[3], block[7], block[11], block[15]); // column 3
+ QUARTERROUND(block[0], block[5], block[10], block[15]); // diagonal 1
+ QUARTERROUND(block[1], block[6], block[11], block[12]); // diagonal 2
+ QUARTERROUND(block[2], block[7], block[ 8], block[13]); // diagonal 3
+ QUARTERROUND(block[3], block[4], block[ 9], block[14]); // diagonal 4
+}
+
+#define TWENTY_ROUNDS(x) ( \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x), \
+ INNER_BLOCK(x) \
+)
+
+// 2.3. The ChaCha20 Block Function
+// chacha20_block(key, counter, nonce):
+// state = constants | key | counter | nonce
+// working_state = state
+// for i=1 upto 10
+// inner_block(working_state)
+// end
+// state += working_state
+// return serialize(state)
+// end
+static void chacha20_block(struct chacha20_ctx *ctx, uint8_t *stream) {
+ uint32_t working_state[16];
+ int i;
+
+ for (i = 0; i < 16; ++i) {
+ working_state[i] = ctx->state[i];
+ }
+
+ TWENTY_ROUNDS(working_state);
+
+ for (i = 0; i < 16; ++i) {
+ U32TO8_LITTLE(stream + (4 * i), PLUS(working_state[i], ctx->state[i]));
+ }
+}
+
+void chacha20(struct chacha20_ctx *ctx, uint8_t *out, const uint8_t *in, uint32_t len) {
+ uint8_t output[CHACHA20_BLOCK_SIZE];
+ int i;
+
+ if (len) {
+ for (;;) {
+ chacha20_block(ctx, output);
+ // Word 12 is a block counter
+ ctx->state[12] = PLUSONE(ctx->state[12]);
+ if (len <= 64) {
+ for (i = 0;i < len;++i) {
+ out[i] = in[i] ^ output[i];
+ }
+ return;
+ }
+ for (i = 0;i < 64;++i) {
+ out[i] = in[i] ^ output[i];
+ }
+ len -= 64;
+ out += 64;
+ in += 64;
+ }
+ }
+}
+
+
+// 2.3. The ChaCha20 Block Function
+// The first four words (0-3) are constants: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
+// The next eight words (4-11) are taken from the 256-bit key by reading the bytes in little-endian order, in 4-byte chunks.
+// Word 12 is a block counter. Since each block is 64-byte, a 32-bit word is enough for 256 gigabytes of data.
+// Words 13-15 are a nonce, which should not be repeated for the same key.
+// For wireguard: "nonce being composed of 32 bits of zeros followed by the 64-bit little-endian value of counter." where counter comes from the Wireguard layer and is separate from the block counter in word 12
+void chacha20_init(struct chacha20_ctx *ctx, const uint8_t *key, const uint64_t nonce) {
+ ctx->state[0] = CHACHA20_CONSTANT_1;
+ ctx->state[1] = CHACHA20_CONSTANT_2;
+ ctx->state[2] = CHACHA20_CONSTANT_3;
+ ctx->state[3] = CHACHA20_CONSTANT_4;
+ ctx->state[4] = U8TO32_LITTLE(key + 0);
+ ctx->state[5] = U8TO32_LITTLE(key + 4);
+ ctx->state[6] = U8TO32_LITTLE(key + 8);
+ ctx->state[7] = U8TO32_LITTLE(key + 12);
+ ctx->state[8] = U8TO32_LITTLE(key + 16);
+ ctx->state[9] = U8TO32_LITTLE(key + 20);
+ ctx->state[10] = U8TO32_LITTLE(key + 24);
+ ctx->state[11] = U8TO32_LITTLE(key + 28);
+ ctx->state[12] = 0;
+ ctx->state[13] = 0;
+ ctx->state[14] = nonce & 0xFFFFFFFF;
+ ctx->state[15] = nonce >> 32;
+}
+
+// 2.2. HChaCha20
+// HChaCha20 is initialized the same way as the ChaCha cipher, except that HChaCha20 uses a 128-bit nonce and has no counter.
+// After initialization, proceed through the ChaCha rounds as usual.
+// Once the 20 ChaCha rounds have been completed, the first 128 bits and last 128 bits of the ChaCha state (both little-endian) are concatenated, and this 256-bit subkey is returned.
+void hchacha20(uint8_t *out, const uint8_t *nonce, const uint8_t *key) {
+ uint32_t state[16];
+ state[0] = CHACHA20_CONSTANT_1;
+ state[1] = CHACHA20_CONSTANT_2;
+ state[2] = CHACHA20_CONSTANT_3;
+ state[3] = CHACHA20_CONSTANT_4;
+ state[4] = U8TO32_LITTLE(key + 0);
+ state[5] = U8TO32_LITTLE(key + 4);
+ state[6] = U8TO32_LITTLE(key + 8);
+ state[7] = U8TO32_LITTLE(key + 12);
+ state[8] = U8TO32_LITTLE(key + 16);
+ state[9] = U8TO32_LITTLE(key + 20);
+ state[10] = U8TO32_LITTLE(key + 24);
+ state[11] = U8TO32_LITTLE(key + 28);
+ state[12] = U8TO32_LITTLE(nonce + 0);
+ state[13] = U8TO32_LITTLE(nonce + 4);
+ state[14] = U8TO32_LITTLE(nonce + 8);
+ state[15] = U8TO32_LITTLE(nonce + 12);
+
+ TWENTY_ROUNDS(state);
+
+ // Concatenate first/last 128 bits into 256bit output (as little endian)
+ U32TO8_LITTLE(out + 0, state[0]);
+ U32TO8_LITTLE(out + 4, state[1]);
+ U32TO8_LITTLE(out + 8, state[2]);
+ U32TO8_LITTLE(out + 12, state[3]);
+ U32TO8_LITTLE(out + 16, state[12]);
+ U32TO8_LITTLE(out + 20, state[13]);
+ U32TO8_LITTLE(out + 24, state[14]);
+ U32TO8_LITTLE(out + 28, state[15]);
+}
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/chacha20.h b/lib/WireGuard-ESP32/src/crypto/refc/chacha20.h
new file mode 100644
index 00000000..aaa80222
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/chacha20.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+// RFC7539 implementation of ChaCha20 with modified nonce size for WireGuard
+// https://tools.ietf.org/html/rfc7539
+// Adapted from https://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/ref/chacha.c by D. J. Bernstein (Public Domain)
+// HChaCha20 is described here: https://tools.ietf.org/id/draft-arciszewski-xchacha-02.html
+#ifndef _CHACHA20_H_
+#define _CHACHA20_H_
+
+#include
+
+#define CHACHA20_BLOCK_SIZE (64)
+#define CHACHA20_KEY_SIZE (32)
+
+struct chacha20_ctx {
+ uint32_t state[16];
+};
+
+void chacha20_init(struct chacha20_ctx *ctx, const uint8_t *key, const uint64_t nonce);
+void chacha20(struct chacha20_ctx *ctx, uint8_t *out, const uint8_t *in, uint32_t len);
+void hchacha20(uint8_t *out, const uint8_t *nonce, const uint8_t *key);
+
+#endif /* _CHACHA20_H_ */
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.c b/lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.c
new file mode 100644
index 00000000..972e8b1c
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+// AEAD_CHACHA20_POLY1305 as described in https://tools.ietf.org/html/rfc7539
+// AEAD_XChaCha20_Poly1305 as described in https://tools.ietf.org/id/draft-arciszewski-xchacha-02.html
+#include "chacha20poly1305.h"
+#include "chacha20.h"
+#include "poly1305-donna.h"
+
+#include
+#include
+#include "../../crypto.h"
+
+#define POLY1305_KEY_SIZE 32
+#define POLY1305_MAC_SIZE 16
+
+static const uint8_t zero[CHACHA20_BLOCK_SIZE] = { 0 };
+
+// 2.6. Generating the Poly1305 Key Using ChaCha20
+static void generate_poly1305_key(struct poly1305_context *poly1305_state, struct chacha20_ctx *chacha20_state, const uint8_t *key, uint64_t nonce) {
+ uint8_t block[POLY1305_KEY_SIZE] = {0};
+
+ // The method is to call the block function with the following parameters:
+ // - The 256-bit session integrity key is used as the ChaCha20 key.
+ // - The block counter is set to zero.
+ // - The protocol will specify a 96-bit or 64-bit nonce
+ chacha20_init(chacha20_state, key, nonce);
+
+ // We take the first 256 bits or the serialized state, and use those as the one-time Poly1305 key
+ chacha20(chacha20_state, block, block, sizeof(block));
+
+ poly1305_init(poly1305_state, block);
+
+ crypto_zero(&block, sizeof(block));
+}
+
+// 2.8. AEAD Construction (Encryption)
+void chacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, uint64_t nonce, const uint8_t *key) {
+ struct poly1305_context poly1305_state;
+ struct chacha20_ctx chacha20_state;
+ uint8_t block[8];
+ size_t padded_len;
+
+ // First, a Poly1305 one-time key is generated from the 256-bit key and nonce using the procedure described in Section 2.6.
+ generate_poly1305_key(&poly1305_state, &chacha20_state, key, nonce);
+
+ // Next, the ChaCha20 encryption function is called to encrypt the plaintext, using the same key and nonce, and with the initial counter set to 1.
+ chacha20(&chacha20_state, dst, src, src_len);
+
+ // Finally, the Poly1305 function is called with the Poly1305 key calculated above, and a message constructed as a concatenation of the following:
+ // - The AAD
+ poly1305_update(&poly1305_state, ad, ad_len);
+ // - padding1 -- the padding is up to 15 zero bytes, and it brings the total length so far to an integral multiple of 16
+ padded_len = (ad_len + 15) & 0xFFFFFFF0; // Round up to next 16 bytes
+ poly1305_update(&poly1305_state, zero, padded_len - ad_len);
+ // - The ciphertext
+ poly1305_update(&poly1305_state, dst, src_len);
+ // - padding2 -- the padding is up to 15 zero bytes, and it brings the total length so far to an integral multiple of 16.
+ padded_len = (src_len + 15) & 0xFFFFFFF0; // Round up to next 16 bytes
+ poly1305_update(&poly1305_state, zero, padded_len - src_len);
+ // - The length of the additional data in octets (as a 64-bit little-endian integer)
+ U64TO8_LITTLE(block, (uint64_t)ad_len);
+ poly1305_update(&poly1305_state, block, sizeof(block));
+ // - The length of the ciphertext in octets (as a 64-bit little-endian integer).
+ U64TO8_LITTLE(block, (uint64_t)src_len);
+ poly1305_update(&poly1305_state, block, sizeof(block));
+
+ // The output from the AEAD is twofold:
+ // - A ciphertext of the same length as the plaintext. (above, output of chacha20 into dst)
+ // - A 128-bit tag, which is the output of the Poly1305 function. (append to dst)
+ poly1305_finish(&poly1305_state, dst + src_len);
+
+ // Make sure we leave nothing sensitive on the stack
+ crypto_zero(&chacha20_state, sizeof(chacha20_state));
+ crypto_zero(&block, sizeof(block));
+}
+
+// 2.8. AEAD Construction (Decryption)
+bool chacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, uint64_t nonce, const uint8_t *key) {
+ struct poly1305_context poly1305_state;
+ struct chacha20_ctx chacha20_state;
+ uint8_t block[8];
+ uint8_t mac[POLY1305_MAC_SIZE];
+ size_t padded_len;
+ int dst_len;
+ bool result = false;
+
+ // Decryption is similar [to encryption] with the following differences:
+ // - The roles of ciphertext and plaintext are reversed, so the ChaCha20 encryption function is applied to the ciphertext, producing the plaintext.
+ // - The Poly1305 function is still run on the AAD and the ciphertext, not the plaintext.
+ // - The calculated tag is bitwise compared to the received tag. The message is authenticated if and only if the tags match.
+
+ if (src_len >= POLY1305_MAC_SIZE) {
+ dst_len = src_len - POLY1305_MAC_SIZE;
+
+ // First, a Poly1305 one-time key is generated from the 256-bit key and nonce using the procedure described in Section 2.6.
+ generate_poly1305_key(&poly1305_state, &chacha20_state, key, nonce);
+
+ // Calculate the MAC before attempting decryption
+
+ // the Poly1305 function is called with the Poly1305 key calculated above, and a message constructed as a concatenation of the following:
+ // - The AAD
+ poly1305_update(&poly1305_state, ad, ad_len);
+ // - padding1 -- the padding is up to 15 zero bytes, and it brings the total length so far to an integral multiple of 16
+ padded_len = (ad_len + 15) & 0xFFFFFFF0; // Round up to next 16 bytes
+ poly1305_update(&poly1305_state, zero, padded_len - ad_len);
+ // - The ciphertext (note the Poly1305 function is still run on the AAD and the ciphertext, not the plaintext)
+ poly1305_update(&poly1305_state, src, dst_len);
+ // - padding2 -- the padding is up to 15 zero bytes, and it brings the total length so far to an integral multiple of 16.
+ padded_len = (dst_len + 15) & 0xFFFFFFF0; // Round up to next 16 bytes
+ poly1305_update(&poly1305_state, zero, padded_len - dst_len);
+ // - The length of the additional data in octets (as a 64-bit little-endian integer)
+ U64TO8_LITTLE(block, (uint64_t)ad_len);
+ poly1305_update(&poly1305_state, block, sizeof(block));
+ // - The length of the ciphertext in octets (as a 64-bit little-endian integer).
+ U64TO8_LITTLE(block, (uint64_t)dst_len);
+ poly1305_update(&poly1305_state, block, sizeof(block));
+
+ // The output from the AEAD is twofold:
+ // - A plaintext of the same length as the ciphertext. (below, output of chacha20 into dst)
+ // - A 128-bit tag, which is the output of the Poly1305 function. (into mac for checking against passed mac)
+ poly1305_finish(&poly1305_state, mac);
+
+
+ if (crypto_equal(mac, src + dst_len, POLY1305_MAC_SIZE)) {
+ // mac is correct - do the decryption
+ // Next, the ChaCha20 encryption function is called to decrypt the ciphertext, using the same key and nonce, and with the initial counter set to 1.
+ chacha20(&chacha20_state, dst, src, dst_len);
+ result = true;
+ }
+ }
+ return result;
+}
+
+// AEAD_XChaCha20_Poly1305
+// XChaCha20-Poly1305 is a variant of the ChaCha20-Poly1305 AEAD construction as defined in [RFC7539] that uses a 192-bit nonce instead of a 96-bit nonce.
+// The algorithm for XChaCha20-Poly1305 is as follows:
+// 1. Calculate a subkey from the first 16 bytes of the nonce and the key, using HChaCha20 (Section 2.2).
+// 2. Use the subkey and remaining 8 bytes of the nonce (prefixed with 4 NUL bytes) with AEAD_CHACHA20_POLY1305 from [RFC7539] as normal. The definition for XChaCha20 is given in Section 2.3.
+void xchacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, const uint8_t *nonce, const uint8_t *key) {
+ uint8_t subkey[CHACHA20_KEY_SIZE];
+ uint64_t new_nonce;
+
+ new_nonce = U8TO64_LITTLE(nonce + 16);
+
+ hchacha20(subkey, nonce, key);
+ chacha20poly1305_encrypt(dst, src, src_len, ad, ad_len, new_nonce, subkey);
+
+ crypto_zero(subkey, sizeof(subkey));
+}
+
+bool xchacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, const uint8_t *nonce, const uint8_t *key) {
+ uint8_t subkey[CHACHA20_KEY_SIZE];
+ uint64_t new_nonce;
+ bool result;
+
+ new_nonce = U8TO64_LITTLE(nonce + 16);
+
+ hchacha20(subkey, nonce, key);
+ result = chacha20poly1305_decrypt(dst, src, src_len, ad, ad_len, new_nonce, subkey);
+
+ crypto_zero(subkey, sizeof(subkey));
+ return result;
+}
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.h b/lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.h
new file mode 100644
index 00000000..83fab072
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/chacha20poly1305.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+#ifndef _CHACHA20POLY1305_H_
+#define _CHACHA20POLY1305_H_
+
+#include
+#include
+#include
+
+// Aead(key, counter, plain text, auth text) ChaCha20Poly1305 AEAD, as specified in RFC7539 [17], with its nonce being composed of 32 bits of zeros followed by the 64-bit little-endian value of counter.
+// AEAD_CHACHA20_POLY1305 as described in https://tools.ietf.org/html/rfc7539
+void chacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, uint64_t nonce, const uint8_t *key);
+bool chacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, uint64_t nonce, const uint8_t *key);
+
+// Xaead(key, nonce, plain text, auth text) XChaCha20Poly1305 AEAD, with a 24-byte random nonce, instantiated using HChaCha20 [6] and ChaCha20Poly1305.
+// AEAD_XChaCha20_Poly1305 as described in https://tools.ietf.org/id/draft-arciszewski-xchacha-02.html
+void xchacha20poly1305_encrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, const uint8_t *nonce, const uint8_t *key);
+bool xchacha20poly1305_decrypt(uint8_t *dst, const uint8_t *src, size_t src_len, const uint8_t *ad, size_t ad_len, const uint8_t *nonce, const uint8_t *key);
+
+#endif /* _CHACHA20POLY1305_H_ */
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna-32.h b/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna-32.h
new file mode 100644
index 00000000..dbcec774
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna-32.h
@@ -0,0 +1,220 @@
+// Taken from https://github.com/floodyberry/poly1305-donna - public domain or MIT
+/*
+ poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition
+*/
+
+#if defined(_MSC_VER)
+ #define POLY1305_NOINLINE __declspec(noinline)
+#elif defined(__GNUC__)
+ #define POLY1305_NOINLINE __attribute__((noinline))
+#else
+ #define POLY1305_NOINLINE
+#endif
+
+#define poly1305_block_size 16
+
+/* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */
+typedef struct poly1305_state_internal_t {
+ unsigned long r[5];
+ unsigned long h[5];
+ unsigned long pad[4];
+ size_t leftover;
+ unsigned char buffer[poly1305_block_size];
+ unsigned char final;
+} poly1305_state_internal_t;
+
+/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */
+static unsigned long
+U8TO32(const unsigned char *p) {
+ return
+ (((unsigned long)(p[0] & 0xff) ) |
+ ((unsigned long)(p[1] & 0xff) << 8) |
+ ((unsigned long)(p[2] & 0xff) << 16) |
+ ((unsigned long)(p[3] & 0xff) << 24));
+}
+
+/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */
+static void
+U32TO8(unsigned char *p, unsigned long v) {
+ p[0] = (v ) & 0xff;
+ p[1] = (v >> 8) & 0xff;
+ p[2] = (v >> 16) & 0xff;
+ p[3] = (v >> 24) & 0xff;
+}
+
+void
+poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
+ poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
+
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+ st->r[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff;
+ st->r[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03;
+ st->r[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff;
+ st->r[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff;
+ st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff;
+
+ /* h = 0 */
+ st->h[0] = 0;
+ st->h[1] = 0;
+ st->h[2] = 0;
+ st->h[3] = 0;
+ st->h[4] = 0;
+
+ /* save pad for later */
+ st->pad[0] = U8TO32(&key[16]);
+ st->pad[1] = U8TO32(&key[20]);
+ st->pad[2] = U8TO32(&key[24]);
+ st->pad[3] = U8TO32(&key[28]);
+
+ st->leftover = 0;
+ st->final = 0;
+}
+
+static void
+poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) {
+ const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */
+ unsigned long r0,r1,r2,r3,r4;
+ unsigned long s1,s2,s3,s4;
+ unsigned long h0,h1,h2,h3,h4;
+ unsigned long long d0,d1,d2,d3,d4;
+ unsigned long c;
+
+ r0 = st->r[0];
+ r1 = st->r[1];
+ r2 = st->r[2];
+ r3 = st->r[3];
+ r4 = st->r[4];
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+ h3 = st->h[3];
+ h4 = st->h[4];
+
+ while (bytes >= poly1305_block_size) {
+ /* h += m[i] */
+ h0 += (U8TO32(m+ 0) ) & 0x3ffffff;
+ h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff;
+ h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff;
+ h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff;
+ h4 += (U8TO32(m+12) >> 8) | hibit;
+
+ /* h *= r */
+ d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1);
+ d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2);
+ d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3);
+ d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4);
+ d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0);
+
+ /* (partial) h %= p */
+ c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff;
+ d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff;
+ d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff;
+ d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff;
+ d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff;
+ h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
+ h1 += c;
+
+ m += poly1305_block_size;
+ bytes -= poly1305_block_size;
+ }
+
+ st->h[0] = h0;
+ st->h[1] = h1;
+ st->h[2] = h2;
+ st->h[3] = h3;
+ st->h[4] = h4;
+}
+
+POLY1305_NOINLINE void
+poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
+ poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
+ unsigned long h0,h1,h2,h3,h4,c;
+ unsigned long g0,g1,g2,g3,g4;
+ unsigned long long f;
+ unsigned long mask;
+
+ /* process the remaining block */
+ if (st->leftover) {
+ size_t i = st->leftover;
+ st->buffer[i++] = 1;
+ for (; i < poly1305_block_size; i++)
+ st->buffer[i] = 0;
+ st->final = 1;
+ poly1305_blocks(st, st->buffer, poly1305_block_size);
+ }
+
+ /* fully carry h */
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+ h3 = st->h[3];
+ h4 = st->h[4];
+
+ c = h1 >> 26; h1 = h1 & 0x3ffffff;
+ h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
+ h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
+ h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
+ h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
+ h1 += c;
+
+ /* compute h + -p */
+ g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
+ g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
+ g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
+ g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
+ g4 = h4 + c - (1UL << 26);
+
+ /* select h if h < p, or h + -p if h >= p */
+ mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
+ g0 &= mask;
+ g1 &= mask;
+ g2 &= mask;
+ g3 &= mask;
+ g4 &= mask;
+ mask = ~mask;
+ h0 = (h0 & mask) | g0;
+ h1 = (h1 & mask) | g1;
+ h2 = (h2 & mask) | g2;
+ h3 = (h3 & mask) | g3;
+ h4 = (h4 & mask) | g4;
+
+ /* h = h % (2^128) */
+ h0 = ((h0 ) | (h1 << 26)) & 0xffffffff;
+ h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
+ h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
+ h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
+
+ /* mac = (h + pad) % (2^128) */
+ f = (unsigned long long)h0 + st->pad[0] ; h0 = (unsigned long)f;
+ f = (unsigned long long)h1 + st->pad[1] + (f >> 32); h1 = (unsigned long)f;
+ f = (unsigned long long)h2 + st->pad[2] + (f >> 32); h2 = (unsigned long)f;
+ f = (unsigned long long)h3 + st->pad[3] + (f >> 32); h3 = (unsigned long)f;
+
+ U32TO8(mac + 0, h0);
+ U32TO8(mac + 4, h1);
+ U32TO8(mac + 8, h2);
+ U32TO8(mac + 12, h3);
+
+ /* zero out the state */
+ st->h[0] = 0;
+ st->h[1] = 0;
+ st->h[2] = 0;
+ st->h[3] = 0;
+ st->h[4] = 0;
+ st->r[0] = 0;
+ st->r[1] = 0;
+ st->r[2] = 0;
+ st->r[3] = 0;
+ st->r[4] = 0;
+ st->pad[0] = 0;
+ st->pad[1] = 0;
+ st->pad[2] = 0;
+ st->pad[3] = 0;
+}
+
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.c b/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.c
new file mode 100644
index 00000000..31ad7c59
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.c
@@ -0,0 +1,41 @@
+// Taken from https://github.com/floodyberry/poly1305-donna - public domain or MIT
+
+#include "poly1305-donna.h"
+#include "poly1305-donna-32.h"
+
+void
+poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) {
+ poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
+ size_t i;
+
+ /* handle leftover */
+ if (st->leftover) {
+ size_t want = (poly1305_block_size - st->leftover);
+ if (want > bytes)
+ want = bytes;
+ for (i = 0; i < want; i++)
+ st->buffer[st->leftover + i] = m[i];
+ bytes -= want;
+ m += want;
+ st->leftover += want;
+ if (st->leftover < poly1305_block_size)
+ return;
+ poly1305_blocks(st, st->buffer, poly1305_block_size);
+ st->leftover = 0;
+ }
+
+ /* process full blocks */
+ if (bytes >= poly1305_block_size) {
+ size_t want = (bytes & ~(poly1305_block_size - 1));
+ poly1305_blocks(st, m, want);
+ m += want;
+ bytes -= want;
+ }
+
+ /* store leftover */
+ if (bytes) {
+ for (i = 0; i < bytes; i++)
+ st->buffer[st->leftover + i] = m[i];
+ st->leftover += bytes;
+ }
+}
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.h b/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.h
new file mode 100644
index 00000000..955bca99
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/poly1305-donna.h
@@ -0,0 +1,16 @@
+// Taken from https://github.com/floodyberry/poly1305-donna - public domain or MIT
+#ifndef POLY1305_DONNA_H
+#define POLY1305_DONNA_H
+
+#include
+
+typedef struct poly1305_context {
+ size_t aligner;
+ unsigned char opaque[136];
+} poly1305_context;
+
+void poly1305_init(poly1305_context *ctx, const unsigned char key[32]);
+void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes);
+void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]);
+
+#endif /* POLY1305_DONNA_H */
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/x25519-license.txt b/lib/WireGuard-ESP32/src/crypto/refc/x25519-license.txt
new file mode 100644
index 00000000..81e48621
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/x25519-license.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015-2016 Cryptography Research, Inc.
+
+Permission 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.
diff --git a/lib/WireGuard-ESP32/src/crypto/refc/x25519.c b/lib/WireGuard-ESP32/src/crypto/refc/x25519.c
new file mode 100644
index 00000000..3b5ebe36
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/crypto/refc/x25519.c
@@ -0,0 +1,448 @@
+// Taken from https://sourceforge.net/p/strobe (MIT Licence)
+/**
+ * @cond internal
+ * @file x25519.c
+ * @copyright
+ * Copyright (c) 2015-2016 Cryptography Research, Inc. \n
+ * Released under the MIT License. See LICENSE.txt for license information.
+ * @author Mike Hamburg
+ * @brief Key exchange and signatures based on X25519.
+ */
+#include
+#include "x25519.h"
+//#include "strobe.h"
+//#include "strobe_config.h"
+// STROBE header replacement
+#include
+#define X25519_WBITS 32
+#define X25519_SUPPORT_SIGN 0
+#define X25519_MEMCPY_PARAMS 1
+#define X25519_USE_POWER_CHAIN 1
+#if BYTE_ORDER == LITTLE_ENDIAN
+static inline uint32_t eswap_letoh_32(uint32_t w) { return w; }
+#else
+#error "Fix eswap() on non-little-endian machine"
+#endif
+
+#if X25519_WBITS == 64
+ typedef uint64_t limb_t;
+ typedef __uint128_t dlimb_t;
+ typedef __int128_t sdlimb_t;
+ #define eswap_limb eswap_letoh_64
+ #define LIMB(x) x##ull
+#elif X25519_WBITS == 32
+ typedef uint32_t limb_t;
+ typedef uint64_t dlimb_t;
+ typedef int64_t sdlimb_t;
+ #define eswap_limb eswap_letoh_32
+ #define LIMB(x) (uint32_t)(x##ull),(uint32_t)((x##ull)>>32)
+#else
+ #error "Need to know X25519_WBITS"
+#endif
+
+#define NLIMBS (256/X25519_WBITS)
+typedef limb_t fe[NLIMBS];
+
+#if X25519_SUPPORT_SIGN
+typedef limb_t scalar_t[NLIMBS];
+static const limb_t MONTGOMERY_FACTOR = (limb_t)0xd2b51da312547e1bull;
+static const scalar_t sc_p = {
+ LIMB(0x5812631a5cf5d3ed), LIMB(0x14def9dea2f79cd6),
+ LIMB(0x0000000000000000), LIMB(0x1000000000000000)
+}, sc_r2 = {
+ LIMB(0xa40611e3449c0f01), LIMB(0xd00e1ba768859347),
+ LIMB(0xceec73d217f5be65), LIMB(0x0399411b7c309a3d)
+};
+#endif
+
+static inline limb_t umaal(
+ limb_t *carry, limb_t acc, limb_t mand, limb_t mier
+) {
+ dlimb_t tmp = (dlimb_t) mand * mier + acc + *carry;
+ *carry = tmp >> X25519_WBITS;
+ return tmp;
+}
+
+/* These functions are implemented in terms of umaal on ARM */
+static inline limb_t adc(limb_t *carry, limb_t acc, limb_t mand) {
+ dlimb_t total = (dlimb_t)*carry + acc + mand;
+ *carry = total>>X25519_WBITS;
+ return total;
+}
+
+static inline limb_t adc0(limb_t *carry, limb_t acc) {
+ dlimb_t total = (dlimb_t)*carry + acc;
+ *carry = total>>X25519_WBITS;
+ return total;
+}
+
+/* Precondition: carry is small.
+ * Invariant: result of propagate is < 2^255 + 1 word
+ * In particular, always less than 2p.
+ * Also, output x >= min(x,19)
+ */
+static void propagate(fe x, limb_t over) {
+ unsigned i;
+ over = x[NLIMBS-1]>>(X25519_WBITS-1) | over<<1;
+ x[NLIMBS-1] &= ~((limb_t)1<<(X25519_WBITS-1));
+
+ limb_t carry = over * 19;
+ for (i=0; i>= X25519_WBITS;
+ }
+ propagate(out,1+carry);
+}
+
+static void __attribute__((unused))
+swapin(limb_t *x, const uint8_t *in) {
+ memcpy(x,in,sizeof(fe));
+ unsigned i;
+ for (i=0; i>= X25519_WBITS;
+ }
+ return ((dlimb_t)res - 1) >> X25519_WBITS;
+}
+
+static const limb_t a24[1]={121665};
+
+static void ladder_part1(fe xs[5]) {
+ limb_t *x2 = xs[0], *z2=xs[1],*x3=xs[2],*z3=xs[3],*t1=xs[4];
+ add(t1,x2,z2); // t1 = A
+ sub(z2,x2,z2); // z2 = B
+ add(x2,x3,z3); // x2 = C
+ sub(z3,x3,z3); // z3 = D
+ mul1(z3,t1); // z3 = DA
+ mul1(x2,z2); // x3 = BC
+ add(x3,z3,x2); // x3 = DA+CB
+ sub(z3,z3,x2); // z3 = DA-CB
+ sqr1(t1); // t1 = AA
+ sqr1(z2); // z2 = BB
+ sub(x2,t1,z2); // x2 = E = AA-BB
+ mul(z2,x2,a24,sizeof(a24)/sizeof(a24[0])); // z2 = E*a24
+ add(z2,z2,t1); // z2 = E*a24 + AA
+}
+static void ladder_part2(fe xs[5], const fe x1) {
+ limb_t *x2 = xs[0], *z2=xs[1],*x3=xs[2],*z3=xs[3],*t1=xs[4];
+ sqr1(z3); // z3 = (DA-CB)^2
+ mul1(z3,x1); // z3 = x1 * (DA-CB)^2
+ sqr1(x3); // x3 = (DA+CB)^2
+ mul1(z2,x2); // z2 = AA*(E*a24+AA)
+ sub(x2,t1,x2); // x2 = BB again
+ mul1(x2,t1); // x2 = AA*BB
+}
+
+static void x25519_core(fe xs[5], const uint8_t scalar[X25519_BYTES], const uint8_t *x1, int clamp) {
+ int i;
+#if X25519_MEMCPY_PARAMS
+ fe x1i;
+ swapin(x1i,x1);
+ x1 = (const uint8_t *)x1;
+#endif
+ limb_t swap = 0;
+ limb_t *x2 = xs[0],*x3=xs[2],*z3=xs[3];
+ memset(xs,0,4*sizeof(fe));
+ x2[0] = z3[0] = 1;
+ memcpy(x3,x1,sizeof(fe));
+
+ for (i=255; i>=0; i--) {
+ uint8_t bytei = scalar[i/8];
+ if (clamp) {
+ if (i/8 == 0) {
+ bytei &= ~7;
+ } else if (i/8 == X25519_BYTES-1) {
+ bytei &= 0x7F;
+ bytei |= 0x40;
+ }
+ }
+ limb_t doswap = -(limb_t)((bytei>>(i%8)) & 1);
+ condswap(x2,x3,swap^doswap);
+ swap = doswap;
+
+ ladder_part1(xs);
+ ladder_part2(xs,(const limb_t *)x1);
+ }
+ condswap(x2,x3,swap);
+}
+
+int x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES], const uint8_t x1[X25519_BYTES], int clamp) {
+ fe xs[5];
+ x25519_core(xs,scalar,x1,clamp);
+
+ /* Precomputed inversion chain */
+ limb_t *x2 = xs[0], *z2=xs[1], *z3=xs[3];
+ int i;
+
+ limb_t *prev = z2;
+#if X25519_USE_POWER_CHAIN
+ static const struct { uint8_t a,c,n; } steps[13] = {
+ {2,1,1 },
+ {2,1,1 },
+ {4,2,3 },
+ {2,4,6 },
+ {3,1,1 },
+ {3,2,12 },
+ {4,3,25 },
+ {2,3,25 },
+ {2,4,50 },
+ {3,2,125},
+ {3,1,2 },
+ {3,1,2 },
+ {3,1,1 }
+ };
+ for (i=0; i<13; i++) {
+ int j;
+ limb_t *a = xs[steps[i].a];
+ for (j=steps[i].n; j>0; j--) {
+ sqr(a, prev);
+ prev = a;
+ }
+ mul1(a,xs[steps[i].c]);
+ }
+#else
+ /* Raise to the p-2 = 0x7f..ffeb */
+ for (i=253; i>=0; i--) {
+ sqr(z3,prev);
+ prev = z3;
+ if (i>=8 || (0xeb>>i & 1)) {
+ mul1(z3,z2);
+ }
+ }
+#endif
+
+ /* Here prev = z3 */
+ /* x2 /= z2 */
+#if X25519_MEMCPY_PARAMS
+ mul1(x2,z3);
+ int ret = canon(x2);
+ swapout(out,x2);
+#else
+ mul((limb_t *)out, x2, z3, NLIMBS);
+ int ret = canon((limb_t*)out);
+#endif
+ if (clamp) return ret;
+ else return 0;
+}
+
+const uint8_t X25519_BASE_POINT[X25519_BYTES] = {9};
+
+#if X25519_SUPPORT_VERIFY
+static limb_t x25519_verify_core(
+ fe xs[5],
+ const limb_t *other1,
+ const uint8_t other2[X25519_BYTES]
+) {
+ limb_t *z2=xs[1],*x3=xs[2],*z3=xs[3];
+#if X25519_MEMCPY_PARAMS
+ fe xo2;
+ swapin(xo2,other2);
+#else
+ const limb_t *xo2 = (const limb_t *)other2;
+#endif
+
+ memcpy(x3, other1, 2*sizeof(fe));
+
+ ladder_part1(xs);
+
+ /* Here z2 = t2^2 */
+ mul1(z2,other1);
+ mul1(z2,other1+NLIMBS);
+ mul1(z2,xo2);
+ const limb_t sixteen = 16;
+ mul (z2,z2,&sixteen,1);
+
+ mul1(z3,xo2);
+ sub(z3,z3,x3);
+ sqr1(z3);
+
+ /* check equality */
+ sub(z3,z3,z2);
+
+ /* If canon(z2) then both sides are zero.
+ * If canon(z3) then the two sides are equal.
+ *
+ * Reject sigs where both sides are zero, because
+ * that can happen if an input causes the ladder to
+ * return 0/0.
+ */
+ return canon(z2) | ~canon(z3);
+}
+
+int x25519_verify_p2 (
+ const uint8_t response[X25519_BYTES],
+ const uint8_t challenge[X25519_BYTES],
+ const uint8_t eph[X25519_BYTES],
+ const uint8_t pub[X25519_BYTES]
+) {
+ fe xs[7];
+ x25519_core(&xs[0],challenge,pub,0);
+ x25519_core(&xs[2],response,X25519_BASE_POINT,0);
+ return x25519_verify_core(&xs[2],xs[0],eph);
+}
+#endif // X25519_SUPPORT_VERIFY
+
+#if X25519_SUPPORT_SIGN
+static void sc_montmul (
+ scalar_t out,
+ const scalar_t a,
+ const scalar_t b
+) {
+ /**
+ * OK, so carry bounding. We're using a high carry, so that the
+ * inputs don't have to be reduced.
+ *
+ * First montmul: output < (M^2 + Mp)/M = M+p, subtract p, < M. This gets rid of high carry.
+ * Second montmul, by r^2 mod p < p: output < (Mp + Mp)/M = 2p, subtract p, < p, done.
+ */
+ unsigned i,j;
+ limb_t hic = 0;
+ for (i=0; i0) out[j-1] = acc;
+ }
+
+ /* Add two carry registers and high carry */
+ out[NLIMBS-1] = adc(&hic, carry, carry2);
+ }
+
+ /* Reduce */
+ sdlimb_t scarry = 0;
+ for (i=0; i>= X25519_WBITS;
+ }
+ limb_t need_add = -(scarry + hic);
+
+ limb_t carry = 0;
+ for (i=0; i
+#include "crypto.h"
+#include "lwip/sys.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "esp_system.h"
+
+static struct mbedtls_ctr_drbg_context random_context;
+static struct mbedtls_entropy_context entropy_context;
+static bool is_platform_initialized = false;
+
+static int entropy_hw_random_source( void *data, unsigned char *output, size_t len, size_t *olen ) {
+ esp_fill_random(output, len);
+ *olen = len;
+ return 0;
+}
+
+void wireguard_platform_init() {
+ if( is_platform_initialized ) return;
+
+ mbedtls_entropy_init(&entropy_context);
+ mbedtls_ctr_drbg_init(&random_context);
+ mbedtls_entropy_add_source(&entropy_context, entropy_hw_random_source, NULL, 134, MBEDTLS_ENTROPY_SOURCE_STRONG);
+ mbedtls_ctr_drbg_seed(&random_context, mbedtls_entropy_func, &entropy_context, NULL, 0);
+
+ is_platform_initialized = true;
+}
+
+void wireguard_random_bytes(void *bytes, size_t size) {
+ uint8_t *out = (uint8_t *)bytes;
+ mbedtls_ctr_drbg_random(&random_context, bytes, size);
+}
+
+uint32_t wireguard_sys_now() {
+ // Default to the LwIP system time
+ return sys_now();
+}
+
+void wireguard_tai64n_now(uint8_t *output) {
+ // See https://cr.yp.to/libtai/tai64.html
+ // 64 bit seconds from 1970 = 8 bytes
+ // 32 bit nano seconds from current second
+
+ // Get timestamp. Note that the timestamp must be synced by NTP,
+ // or at least preserved in NVS, not to go back after reset.
+ // Otherwise, the WireGuard remote peer rejects handshake.
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ uint64_t millis = (tv.tv_sec * 1000LL + (tv.tv_usec / 1000LL));
+
+ // Split into seconds offset + nanos
+ uint64_t seconds = 0x400000000000000aULL + (millis / 1000);
+ uint32_t nanos = (millis % 1000) * 1000;
+ U64TO8_BIG(output + 0, seconds);
+ U32TO8_BIG(output + 8, nanos);
+}
+
+bool wireguard_is_under_load() {
+ return false;
+}
+
diff --git a/lib/WireGuard-ESP32/src/wireguard-platform.h b/lib/WireGuard-ESP32/src/wireguard-platform.h
new file mode 100644
index 00000000..f54ec4a9
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/wireguard-platform.h
@@ -0,0 +1,71 @@
+/*
+ * Ported to ESP32 Arduino by Kenta Ida (fuga@fugafuga.org)
+ * The original license is below:
+ *
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+#ifndef _WIREGUARD_PLATFORM_H_
+#define _WIREGUARD_PLATFORM_H_
+
+#include
+#include
+#include
+
+// Peers are allocated statically inside the device structure to avoid malloc
+#define WIREGUARD_MAX_PEERS 1
+#define WIREGUARD_MAX_SRC_IPS 2
+
+// Per device limit on accepting (valid) initiation requests - per peer
+#define MAX_INITIATIONS_PER_SECOND (2)
+
+//
+// Your platform integration needs to provide implementations of these functions
+//
+
+void wireguard_platform_init();
+
+// The number of milliseconds since system boot - for LwIP systems this could be sys_now()
+uint32_t wireguard_sys_now();
+
+// Fill the supplied buffer with random data - random data is used for generating new session keys periodically
+void wireguard_random_bytes(void *bytes, size_t size);
+
+// Get the current time in tai64n format - 8 byte seconds, 4 byte nano sub-second - see https://cr.yp.to/libtai/tai64.html for details
+// Output buffer passed is 12 bytes
+// The Wireguard implementation doesn't strictly need this to be a time, but instead an increasing value
+// The remote end of the Wireguard tunnel will use this value in handshake replay detection
+void wireguard_tai64n_now(uint8_t *output);
+
+// Is the system under load - i.e. should we generate cookie reply message in response to initiation messages
+bool wireguard_is_under_load();
+
+#endif /* _WIREGUARD_PLATFORM_H_ */
diff --git a/lib/WireGuard-ESP32/src/wireguard.c b/lib/WireGuard-ESP32/src/wireguard.c
new file mode 100644
index 00000000..ca86e9be
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/wireguard.c
@@ -0,0 +1,1129 @@
+/*
+ * Ported to ESP32 Arduino by Kenta Ida (fuga@fugafuga.org)
+ * The original license is below:
+ *
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+#include "wireguard.h"
+
+#include
+#include
+#include
+
+#include "crypto.h"
+
+// For HMAC calculation
+#define WIREGUARD_BLAKE2S_BLOCK_SIZE (64)
+
+// 5.4 Messages
+// Constants
+static const uint8_t CONSTRUCTION[37] = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; // The UTF-8 string literal "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s", 37 bytes of output
+static const uint8_t IDENTIFIER[34] = "WireGuard v1 zx2c4 Jason@zx2c4.com"; // The UTF-8 string literal "WireGuard v1 zx2c4 Jason@zx2c4.com", 34 bytes of output
+static const uint8_t LABEL_MAC1[8] = "mac1----"; // Label-Mac1 The UTF-8 string literal "mac1----", 8 bytes of output.
+static const uint8_t LABEL_COOKIE[8] = "cookie--"; // Label-Cookie The UTF-8 string literal "cookie--", 8 bytes of output
+
+static const char *base64_lookup = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const uint8_t zero_key[WIREGUARD_PUBLIC_KEY_LEN] = { 0 };
+
+// Calculated in wireguard_init
+static uint8_t construction_hash[WIREGUARD_HASH_LEN];
+static uint8_t identifier_hash[WIREGUARD_HASH_LEN];
+
+
+void wireguard_init() {
+ wireguard_blake2s_ctx ctx;
+ // Pre-calculate chaining key hash
+ wireguard_blake2s_init(&ctx, WIREGUARD_HASH_LEN, NULL, 0);
+ wireguard_blake2s_update(&ctx, CONSTRUCTION, sizeof(CONSTRUCTION));
+ wireguard_blake2s_final(&ctx, construction_hash);
+ // Pre-calculate initial handshake hash - uses construction_hash calculated above
+ wireguard_blake2s_init(&ctx, WIREGUARD_HASH_LEN, NULL, 0);
+ wireguard_blake2s_update(&ctx, construction_hash, sizeof(construction_hash));
+ wireguard_blake2s_update(&ctx, IDENTIFIER, sizeof(IDENTIFIER));
+ wireguard_blake2s_final(&ctx, identifier_hash);
+}
+
+struct wireguard_peer *peer_alloc(struct wireguard_device *device) {
+ struct wireguard_peer *result = NULL;
+ struct wireguard_peer *tmp;
+ int x;
+ for (x=0; x < WIREGUARD_MAX_PEERS; x++) {
+ tmp = &device->peers[x];
+ if (!tmp->valid) {
+ result = tmp;
+ break;
+ }
+ }
+ return result;
+}
+
+struct wireguard_peer *peer_lookup_by_pubkey(struct wireguard_device *device, uint8_t *public_key) {
+ struct wireguard_peer *result = NULL;
+ struct wireguard_peer *tmp;
+ int x;
+ for (x=0; x < WIREGUARD_MAX_PEERS; x++) {
+ tmp = &device->peers[x];
+ if (tmp->valid) {
+ if (memcmp(tmp->public_key, public_key, WIREGUARD_PUBLIC_KEY_LEN) == 0) {
+ result = tmp;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+uint8_t wireguard_peer_index(struct wireguard_device *device, struct wireguard_peer *peer) {
+ uint8_t result = 0xFF;
+ uint8_t x;
+ for (x=0; x < WIREGUARD_MAX_PEERS; x++) {
+ if (peer == &device->peers[x]) {
+ result = x;
+ break;
+ }
+ }
+ return result;
+}
+
+struct wireguard_peer *peer_lookup_by_peer_index(struct wireguard_device *device, uint8_t peer_index) {
+ struct wireguard_peer *result = NULL;
+ if (peer_index < WIREGUARD_MAX_PEERS) {
+ if (device->peers[peer_index].valid) {
+ result = &device->peers[peer_index];
+ }
+ }
+ return result;
+}
+
+struct wireguard_peer *peer_lookup_by_receiver(struct wireguard_device *device, uint32_t receiver) {
+ struct wireguard_peer *result = NULL;
+ struct wireguard_peer *tmp;
+ int x;
+ for (x=0; x < WIREGUARD_MAX_PEERS; x++) {
+ tmp = &device->peers[x];
+ if (tmp->valid) {
+ if ((tmp->curr_keypair.valid && (tmp->curr_keypair.local_index == receiver)) ||
+ (tmp->next_keypair.valid && (tmp->next_keypair.local_index == receiver)) ||
+ (tmp->prev_keypair.valid && (tmp->prev_keypair.local_index == receiver))
+ ) {
+ result = tmp;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+struct wireguard_peer *peer_lookup_by_handshake(struct wireguard_device *device, uint32_t receiver) {
+ struct wireguard_peer *result = NULL;
+ struct wireguard_peer *tmp;
+ int x;
+ for (x=0; x < WIREGUARD_MAX_PEERS; x++) {
+ tmp = &device->peers[x];
+ if (tmp->valid) {
+ if (tmp->handshake.valid && tmp->handshake.initiator && (tmp->handshake.local_index == receiver)) {
+ result = tmp;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+bool wireguard_expired(uint32_t created_millis, uint32_t valid_seconds) {
+ uint32_t diff = wireguard_sys_now() - created_millis;
+ return (diff >= (valid_seconds * 1000));
+}
+
+
+static void generate_cookie_secret(struct wireguard_device *device) {
+ wireguard_random_bytes(device->cookie_secret, WIREGUARD_HASH_LEN);
+ device->cookie_secret_millis = wireguard_sys_now();
+}
+
+static void generate_peer_cookie(struct wireguard_device *device, uint8_t *cookie, uint8_t *source_addr_port, size_t source_length) {
+ wireguard_blake2s_ctx ctx;
+
+ if (wireguard_expired(device->cookie_secret_millis, COOKIE_SECRET_MAX_AGE)) {
+ // Generate new random bytes
+ generate_cookie_secret(device);
+ }
+
+ // Mac(key, input) Keyed-Blake2s(key, input, 16), the keyed MAC variant of the BLAKE2s hash function, returning 16 bytes of output
+ wireguard_blake2s_init(&ctx, WIREGUARD_COOKIE_LEN, device->cookie_secret, WIREGUARD_HASH_LEN);
+ // 5.4.7 Under Load: Cookie Reply Message
+ // Mix in the IP address and port - have the IP layer pass this in as byte array to avoid using Lwip specific APIs in this module
+ if ((source_addr_port) && (source_length > 0)) {
+ wireguard_blake2s_update(&ctx, source_addr_port, source_length);
+ }
+ wireguard_blake2s_final(&ctx, cookie);
+}
+
+static void wireguard_mac(uint8_t *dst, const void *message, size_t len, const uint8_t *key, size_t keylen) {
+ wireguard_blake2s(dst, WIREGUARD_COOKIE_LEN, key, keylen, message, len);
+}
+
+static void wireguard_mac_key(uint8_t *key, const uint8_t *public_key, const uint8_t *label, size_t label_len) {
+ blake2s_ctx ctx;
+ blake2s_init(&ctx, WIREGUARD_SESSION_KEY_LEN, NULL, 0);
+ blake2s_update(&ctx, label, label_len);
+ blake2s_update(&ctx, public_key, WIREGUARD_PUBLIC_KEY_LEN);
+ blake2s_final(&ctx, key);
+}
+
+static void wireguard_mix_hash(uint8_t *hash, const uint8_t *src, size_t src_len) {
+ wireguard_blake2s_ctx ctx;
+ wireguard_blake2s_init(&ctx, WIREGUARD_HASH_LEN, NULL, 0);
+ wireguard_blake2s_update(&ctx, hash, WIREGUARD_HASH_LEN);
+ wireguard_blake2s_update(&ctx, src, src_len);
+ wireguard_blake2s_final(&ctx, hash);
+}
+
+static void wireguard_hmac(uint8_t *digest, const uint8_t *key, size_t key_len, const uint8_t *text, size_t text_len) {
+ // Adapted from appendix example in RFC2104 to use BLAKE2S instead of MD5 - https://tools.ietf.org/html/rfc2104
+ wireguard_blake2s_ctx ctx;
+ uint8_t k_ipad[WIREGUARD_BLAKE2S_BLOCK_SIZE]; // inner padding - key XORd with ipad
+ uint8_t k_opad[WIREGUARD_BLAKE2S_BLOCK_SIZE]; // outer padding - key XORd with opad
+
+ uint8_t tk[WIREGUARD_HASH_LEN];
+ int i;
+ // if key is longer than BLAKE2S_BLOCK_SIZE bytes reset it to key=BLAKE2S(key)
+ if (key_len > WIREGUARD_BLAKE2S_BLOCK_SIZE) {
+ wireguard_blake2s_ctx tctx;
+ wireguard_blake2s_init(&tctx, WIREGUARD_HASH_LEN, NULL, 0);
+ wireguard_blake2s_update(&tctx, key, key_len);
+ wireguard_blake2s_final(&tctx, tk);
+ key = tk;
+ key_len = WIREGUARD_HASH_LEN;
+ }
+
+ // the HMAC transform looks like:
+ // HASH(K XOR opad, HASH(K XOR ipad, text))
+ // where K is an n byte key
+ // ipad is the byte 0x36 repeated BLAKE2S_BLOCK_SIZE times
+ // opad is the byte 0x5c repeated BLAKE2S_BLOCK_SIZE times
+ // and text is the data being protected
+ memset(k_ipad, 0, sizeof(k_ipad));
+ memset(k_opad, 0, sizeof(k_opad));
+ memcpy(k_ipad, key, key_len);
+ memcpy(k_opad, key, key_len);
+
+ // XOR key with ipad and opad values
+ for (i=0; i < WIREGUARD_BLAKE2S_BLOCK_SIZE; i++) {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+ // perform inner HASH
+ wireguard_blake2s_init(&ctx, WIREGUARD_HASH_LEN, NULL, 0); // init context for 1st pass
+ wireguard_blake2s_update(&ctx, k_ipad, WIREGUARD_BLAKE2S_BLOCK_SIZE); // start with inner pad
+ wireguard_blake2s_update(&ctx, text, text_len); // then text of datagram
+ wireguard_blake2s_final(&ctx, digest); // finish up 1st pass
+
+ // perform outer HASH
+ wireguard_blake2s_init(&ctx, WIREGUARD_HASH_LEN, NULL, 0); // init context for 2nd pass
+ wireguard_blake2s_update(&ctx, k_opad, WIREGUARD_BLAKE2S_BLOCK_SIZE); // start with outer pad
+ wireguard_blake2s_update(&ctx, digest, WIREGUARD_HASH_LEN); // then results of 1st hash
+ wireguard_blake2s_final(&ctx, digest); // finish up 2nd pass
+}
+
+static void wireguard_kdf1(uint8_t *tau1, const uint8_t *chaining_key, const uint8_t *data, size_t data_len) {
+ uint8_t tau0[WIREGUARD_HASH_LEN];
+ uint8_t output[WIREGUARD_HASH_LEN + 1];
+
+ // tau0 = Hmac(key, input)
+ wireguard_hmac(tau0, chaining_key, WIREGUARD_HASH_LEN, data, data_len);
+ // tau1 := Hmac(tau0, 0x1)
+ output[0] = 1;
+ wireguard_hmac(output, tau0, WIREGUARD_HASH_LEN, output, 1);
+ memcpy(tau1, output, WIREGUARD_HASH_LEN);
+
+ // Wipe intermediates
+ crypto_zero(tau0, sizeof(tau0));
+ crypto_zero(output, sizeof(output));
+}
+
+static void wireguard_kdf2(uint8_t *tau1, uint8_t *tau2, const uint8_t *chaining_key, const uint8_t *data, size_t data_len) {
+ uint8_t tau0[WIREGUARD_HASH_LEN];
+ uint8_t output[WIREGUARD_HASH_LEN + 1];
+
+ // tau0 = Hmac(key, input)
+ wireguard_hmac(tau0, chaining_key, WIREGUARD_HASH_LEN, data, data_len);
+ // tau1 := Hmac(tau0, 0x1)
+ output[0] = 1;
+ wireguard_hmac(output, tau0, WIREGUARD_HASH_LEN, output, 1);
+ memcpy(tau1, output, WIREGUARD_HASH_LEN);
+
+ // tau2 := Hmac(tau0,tau1 || 0x2)
+ output[WIREGUARD_HASH_LEN] = 2;
+ wireguard_hmac(output, tau0, WIREGUARD_HASH_LEN, output, WIREGUARD_HASH_LEN + 1);
+ memcpy(tau2, output, WIREGUARD_HASH_LEN);
+
+ // Wipe intermediates
+ crypto_zero(tau0, sizeof(tau0));
+ crypto_zero(output, sizeof(output));
+}
+
+static void wireguard_kdf3(uint8_t *tau1, uint8_t *tau2, uint8_t *tau3, const uint8_t *chaining_key, const uint8_t *data, size_t data_len) {
+ uint8_t tau0[WIREGUARD_HASH_LEN];
+ uint8_t output[WIREGUARD_HASH_LEN + 1];
+
+ // tau0 = Hmac(key, input)
+ wireguard_hmac(tau0, chaining_key, WIREGUARD_HASH_LEN, data, data_len);
+ // tau1 := Hmac(tau0, 0x1)
+ output[0] = 1;
+ wireguard_hmac(output, tau0, WIREGUARD_HASH_LEN, output, 1);
+ memcpy(tau1, output, WIREGUARD_HASH_LEN);
+
+ // tau2 := Hmac(tau0,tau1 || 0x2)
+ output[WIREGUARD_HASH_LEN] = 2;
+ wireguard_hmac(output, tau0, WIREGUARD_HASH_LEN, output, WIREGUARD_HASH_LEN + 1);
+ memcpy(tau2, output, WIREGUARD_HASH_LEN);
+
+ // tau3 := Hmac(tau0,tau1,tau2 || 0x3)
+ output[WIREGUARD_HASH_LEN] = 3;
+ wireguard_hmac(output, tau0, WIREGUARD_HASH_LEN, output, WIREGUARD_HASH_LEN + 1);
+ memcpy(tau3, output, WIREGUARD_HASH_LEN);
+
+ // Wipe intermediates
+ crypto_zero(tau0, sizeof(tau0));
+ crypto_zero(output, sizeof(output));
+}
+
+bool wireguard_check_replay(struct wireguard_keypair *keypair, uint64_t seq) {
+ // Implementation of packet replay window - as per RFC2401
+ // Adapted from code in Appendix C at https://tools.ietf.org/html/rfc2401
+ uint32_t diff;
+ bool result = false;
+ size_t ReplayWindowSize = sizeof(keypair->replay_bitmap); // 32 bits
+
+ if (seq != 0) {
+ if (seq > keypair->replay_counter) {
+ // new larger sequence number
+ diff = seq - keypair->replay_counter;
+ if (diff < ReplayWindowSize) {
+ // In window
+ keypair->replay_bitmap <<= diff;
+ // set bit for this packet
+ keypair->replay_bitmap |= 1;
+ } else {
+ // This packet has a "way larger"
+ keypair->replay_bitmap = 1;
+ }
+ keypair->replay_counter = seq;
+ // larger is good
+ result = true;
+ } else {
+ diff = keypair->replay_counter - seq;
+ if (diff < ReplayWindowSize) {
+ if (keypair->replay_bitmap & ((uint32_t)1 << diff)) {
+ // already seen
+ } else {
+ // mark as seen
+ keypair->replay_bitmap |= ((uint32_t)1 << diff);
+ // out of order but good
+ result = true;
+ }
+ } else {
+ // too old or wrapped
+ }
+ }
+ } else {
+ // first == 0 or wrapped
+ }
+ return result;
+}
+
+struct wireguard_keypair *get_peer_keypair_for_idx(struct wireguard_peer *peer, uint32_t idx) {
+ if (peer->curr_keypair.valid && peer->curr_keypair.local_index == idx) {
+ return &peer->curr_keypair;
+ } else if (peer->next_keypair.valid && peer->next_keypair.local_index == idx) {
+ return &peer->next_keypair;
+ } else if (peer->prev_keypair.valid && peer->prev_keypair.local_index == idx) {
+ return &peer->prev_keypair;
+ }
+ return NULL;
+}
+
+static uint32_t wireguard_generate_unique_index(struct wireguard_device *device) {
+ // We need a random 32-bit number but make sure it's not already been used in the context of this device
+ uint32_t result;
+ uint8_t buf[4];
+ int x;
+ struct wireguard_peer *peer;
+ bool existing;
+ do {
+ do {
+ wireguard_random_bytes(buf, 4);
+ result = U8TO32_LITTLE(buf);
+ } while ((result == 0) || (result == 0xFFFFFFFF)); // Don't allow 0 or 0xFFFFFFFF as valid values
+
+ existing = false;
+ for (x=0; x < WIREGUARD_MAX_PEERS; x++) {
+ peer = &device->peers[x];
+ existing = (result == peer->curr_keypair.local_index) ||
+ (result == peer->prev_keypair.local_index) ||
+ (result == peer->next_keypair.local_index) ||
+ (result == peer->handshake.local_index);
+
+ }
+ } while (existing);
+
+ return result;
+}
+
+static void wireguard_clamp_private_key(uint8_t *key) {
+ key[0] &= 248;
+ key[31] = (key[31] & 127) | 64;
+}
+
+static void wireguard_generate_private_key(uint8_t *key) {
+ wireguard_random_bytes(key, WIREGUARD_PRIVATE_KEY_LEN);
+ wireguard_clamp_private_key(key);
+}
+
+static bool wireguard_generate_public_key(uint8_t *public_key, const uint8_t *private_key) {
+ static const uint8_t basepoint[WIREGUARD_PUBLIC_KEY_LEN] = { 9 };
+ bool result = false;
+ if (memcmp(private_key, zero_key, WIREGUARD_PUBLIC_KEY_LEN) != 0) {
+ result = (wireguard_x25519(public_key, private_key, basepoint) == 0);
+ }
+ return result;
+}
+
+bool wireguard_check_mac1(struct wireguard_device *device, const uint8_t *data, size_t len, const uint8_t *mac1) {
+ bool result = false;
+ uint8_t calculated[WIREGUARD_COOKIE_LEN];
+ wireguard_mac(calculated, data, len, device->label_mac1_key, WIREGUARD_SESSION_KEY_LEN);
+ if (crypto_equal(calculated, mac1, WIREGUARD_COOKIE_LEN)) {
+ result = true;
+ }
+ return result;
+}
+
+bool wireguard_check_mac2(struct wireguard_device *device, const uint8_t *data, size_t len, uint8_t *source_addr_port, size_t source_length, const uint8_t *mac2) {
+ bool result = false;
+ uint8_t cookie[WIREGUARD_COOKIE_LEN];
+ uint8_t calculated[WIREGUARD_COOKIE_LEN];
+
+ generate_peer_cookie(device, cookie, source_addr_port, source_length);
+
+ wireguard_mac(calculated, data, len, cookie, WIREGUARD_COOKIE_LEN);
+ if (crypto_equal(calculated, mac2, WIREGUARD_COOKIE_LEN)) {
+ result = true;
+ }
+ return result;
+}
+
+void handshake_destroy(struct wireguard_handshake *handshake) {
+ crypto_zero(handshake->ephemeral_private, WIREGUARD_PUBLIC_KEY_LEN);
+ crypto_zero(handshake->remote_ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+ crypto_zero(handshake->hash, WIREGUARD_HASH_LEN);
+ crypto_zero(handshake->chaining_key, WIREGUARD_HASH_LEN);
+ handshake->remote_index = 0;
+ handshake->local_index = 0;
+ handshake->valid = false;
+}
+
+void keypair_destroy(struct wireguard_keypair *keypair) {
+ crypto_zero(keypair, sizeof(struct wireguard_keypair));
+ keypair->valid = false;
+}
+
+void keypair_update(struct wireguard_peer *peer, struct wireguard_keypair *received_keypair) {
+ bool key_is_next = (received_keypair == &peer->next_keypair);
+ if (key_is_next) {
+ peer->prev_keypair = peer->curr_keypair;
+ peer->curr_keypair = peer->next_keypair;
+ keypair_destroy(&peer->next_keypair);
+ }
+}
+
+static void add_new_keypair(struct wireguard_peer *peer, struct wireguard_keypair new_keypair) {
+ if (new_keypair.initiator) {
+ if (peer->next_keypair.valid) {
+ peer->prev_keypair = peer->next_keypair;
+ keypair_destroy(&peer->next_keypair);
+ } else {
+ peer->prev_keypair = peer->curr_keypair;
+ }
+ peer->curr_keypair = new_keypair;
+ } else {
+ peer->next_keypair = new_keypair;
+ keypair_destroy(&peer->prev_keypair);
+ }
+}
+
+void wireguard_start_session(struct wireguard_peer *peer, bool initiator) {
+ struct wireguard_handshake *handshake = &peer->handshake;
+ struct wireguard_keypair new_keypair;
+
+ crypto_zero(&new_keypair, sizeof(struct wireguard_keypair));
+ new_keypair.initiator = initiator;
+ new_keypair.local_index = handshake->local_index;
+ new_keypair.remote_index = handshake->remote_index;
+
+ new_keypair.keypair_millis = wireguard_sys_now();
+ new_keypair.sending_valid = true;
+ new_keypair.receiving_valid = true;
+
+ // 5.4.5 Transport Data Key Derivation
+ // (Tsendi = Trecvr, Trecvi = Tsendr) := Kdf2(Ci = Cr,E)
+ if (new_keypair.initiator) {
+ wireguard_kdf2(new_keypair.sending_key, new_keypair.receiving_key, handshake->chaining_key, NULL, 0);
+ } else {
+ wireguard_kdf2(new_keypair.receiving_key, new_keypair.sending_key, handshake->chaining_key, NULL, 0);
+ }
+
+ new_keypair.replay_bitmap = 0;
+ new_keypair.replay_counter = 0;
+
+ new_keypair.last_tx = 0;
+ new_keypair.last_rx = 0; // No packets received yet
+
+ new_keypair.valid = true;
+
+ // Eprivi = Epubi = Eprivr = Epubr = Ci = Cr := E
+ crypto_zero(handshake->ephemeral_private, WIREGUARD_PUBLIC_KEY_LEN);
+ crypto_zero(handshake->remote_ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+ crypto_zero(handshake->hash, WIREGUARD_HASH_LEN);
+ crypto_zero(handshake->chaining_key, WIREGUARD_HASH_LEN);
+ handshake->remote_index = 0;
+ handshake->local_index = 0;
+ handshake->valid = false;
+
+ add_new_keypair(peer, new_keypair);
+}
+
+uint8_t wireguard_get_message_type(const uint8_t *data, size_t len) {
+ uint8_t result = MESSAGE_INVALID;
+ if (len >= 4) {
+ if ((data[1] == 0) && (data[2] == 0) && (data[3] == 0)) {
+ switch (data[0]) {
+ case MESSAGE_HANDSHAKE_INITIATION:
+ if (len == sizeof(struct message_handshake_initiation)) {
+ result = MESSAGE_HANDSHAKE_INITIATION;
+ }
+ break;
+ case MESSAGE_HANDSHAKE_RESPONSE:
+ if (len == sizeof(struct message_handshake_response)) {
+ result = MESSAGE_HANDSHAKE_RESPONSE;
+ }
+ break;
+ case MESSAGE_COOKIE_REPLY:
+ if (len == sizeof(struct message_cookie_reply)) {
+ result = MESSAGE_COOKIE_REPLY;
+ }
+ break;
+ case MESSAGE_TRANSPORT_DATA:
+ if (len >= sizeof(struct message_transport_data) + WIREGUARD_AUTHTAG_LEN) {
+ result = MESSAGE_TRANSPORT_DATA;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+struct wireguard_peer *wireguard_process_initiation_message(struct wireguard_device *device, struct message_handshake_initiation *msg) {
+ struct wireguard_peer *ret_peer = NULL;
+ struct wireguard_peer *peer = NULL;
+ struct wireguard_handshake *handshake;
+ uint8_t key[WIREGUARD_SESSION_KEY_LEN];
+ uint8_t chaining_key[WIREGUARD_HASH_LEN];
+ uint8_t hash[WIREGUARD_HASH_LEN];
+ uint8_t s[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t e[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t t[WIREGUARD_TAI64N_LEN];
+ uint8_t dh_calculation[WIREGUARD_PUBLIC_KEY_LEN];
+ uint32_t now;
+ bool rate_limit;
+ bool replay;
+
+ // We are the responder, other end is the initiator
+
+ // Ci := Hash(Construction) (precalculated hash)
+ memcpy(chaining_key, construction_hash, WIREGUARD_HASH_LEN);
+
+ // Hi := Hash(Ci || Identifier
+ memcpy(hash, identifier_hash, WIREGUARD_HASH_LEN);
+
+ // Hi := Hash(Hi || Spubr)
+ wireguard_mix_hash(hash, device->public_key, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Ci := Kdf1(Ci, Epubi)
+ wireguard_kdf1(chaining_key, chaining_key, msg->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.ephemeral := Epubi
+ memcpy(e, msg->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Hi := Hash(Hi || msg.ephemeral)
+ wireguard_mix_hash(hash, msg->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Calculate DH(Eprivi,Spubr)
+ wireguard_x25519(dh_calculation, device->private_key, e);
+ if (!crypto_equal(dh_calculation, zero_key, WIREGUARD_PUBLIC_KEY_LEN)) {
+
+ // (Ci,k) := Kdf2(Ci,DH(Eprivi,Spubr))
+ wireguard_kdf2(chaining_key, key, chaining_key, dh_calculation, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.static := AEAD(k, 0, Spubi, Hi)
+ if (wireguard_aead_decrypt(s, msg->enc_static, sizeof(msg->enc_static), hash, WIREGUARD_HASH_LEN, 0, key)) {
+ // Hi := Hash(Hi || msg.static)
+ wireguard_mix_hash(hash, msg->enc_static, sizeof(msg->enc_static));
+
+ peer = peer_lookup_by_pubkey(device, s);
+ if (peer) {
+ handshake = &peer->handshake;
+
+ // (Ci,k) := Kdf2(Ci,DH(Sprivi,Spubr))
+ wireguard_kdf2(chaining_key, key, chaining_key, peer->public_key_dh, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.timestamp := AEAD(k, 0, Timestamp(), Hi)
+ if (wireguard_aead_decrypt(t, msg->enc_timestamp, sizeof(msg->enc_timestamp), hash, WIREGUARD_HASH_LEN, 0, key)) {
+ // Hi := Hash(Hi || msg.timestamp)
+ wireguard_mix_hash(hash, msg->enc_timestamp, sizeof(msg->enc_timestamp));
+
+ now = wireguard_sys_now();
+
+ // Check that timestamp is increasing and we haven't had too many initiations (should only get one per peer every 5 seconds max?)
+ replay = (memcmp(t, peer->greatest_timestamp, WIREGUARD_TAI64N_LEN) <= 0); // tai64n is big endian so we can use memcmp to compare
+ rate_limit = (peer->last_initiation_rx - now) < (1000 / MAX_INITIATIONS_PER_SECOND);
+
+ if (!replay && !rate_limit) {
+ // Success! Copy everything to peer
+ peer->last_initiation_rx = now;
+ if (memcmp(t, peer->greatest_timestamp, WIREGUARD_TAI64N_LEN) > 0) {
+ memcpy(peer->greatest_timestamp, t, WIREGUARD_TAI64N_LEN);
+ // TODO: Need to notify if the higher layers want to persist latest timestamp/nonce somewhere
+ }
+ memcpy(handshake->remote_ephemeral, e, WIREGUARD_PUBLIC_KEY_LEN);
+ memcpy(handshake->hash, hash, WIREGUARD_HASH_LEN);
+ memcpy(handshake->chaining_key, chaining_key, WIREGUARD_HASH_LEN);
+ handshake->remote_index = msg->sender;
+ handshake->valid = true;
+ handshake->initiator = false;
+ ret_peer = peer;
+
+ } else {
+ // Ignore
+ }
+ } else {
+ // Failed to decrypt
+ }
+ } else {
+ // peer not found
+ }
+ } else {
+ // Failed to decrypt
+ }
+ } else {
+ // Bad X25519
+ }
+
+ crypto_zero(key, sizeof(key));
+ crypto_zero(hash, sizeof(hash));
+ crypto_zero(chaining_key, sizeof(chaining_key));
+ crypto_zero(dh_calculation, sizeof(dh_calculation));
+
+ return ret_peer;
+}
+
+bool wireguard_process_handshake_response(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_response *src) {
+ struct wireguard_handshake *handshake = &peer->handshake;
+
+ bool result = false;
+ uint8_t key[WIREGUARD_SESSION_KEY_LEN];
+ uint8_t hash[WIREGUARD_HASH_LEN];
+ uint8_t chaining_key[WIREGUARD_HASH_LEN];
+ uint8_t e[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t ephemeral_private[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t static_private[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t preshared_key[WIREGUARD_SESSION_KEY_LEN];
+ uint8_t dh_calculation[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t tau[WIREGUARD_PUBLIC_KEY_LEN];
+
+ if (handshake->valid && handshake->initiator) {
+
+ memcpy(hash, handshake->hash, WIREGUARD_HASH_LEN);
+ memcpy(chaining_key, handshake->chaining_key, WIREGUARD_HASH_LEN);
+ memcpy(ephemeral_private, handshake->ephemeral_private, WIREGUARD_PUBLIC_KEY_LEN);
+ memcpy(preshared_key, peer->preshared_key, WIREGUARD_SESSION_KEY_LEN);
+
+ // (Eprivr, Epubr) := DH-Generate()
+ // Not required
+
+ // Cr := Kdf1(Cr,Epubr)
+ wireguard_kdf1(chaining_key, chaining_key, src->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.ephemeral := Epubr
+ memcpy(e, src->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Hr := Hash(Hr || msg.ephemeral)
+ wireguard_mix_hash(hash, src->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Cr := Kdf1(Cr, DH(Eprivr, Epubi))
+ // Calculate DH(Eprivr, Epubi)
+ wireguard_x25519(dh_calculation, ephemeral_private, e);
+ if (!crypto_equal(dh_calculation, zero_key, WIREGUARD_PUBLIC_KEY_LEN)) {
+ wireguard_kdf1(chaining_key, chaining_key, dh_calculation, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Cr := Kdf1(Cr, DH(Eprivr, Spubi))
+ // CalculateDH(Eprivr, Spubi)
+ wireguard_x25519(dh_calculation, device->private_key, e);
+ if (!crypto_equal(dh_calculation, zero_key, WIREGUARD_PUBLIC_KEY_LEN)) {
+ wireguard_kdf1(chaining_key, chaining_key, dh_calculation, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // (Cr, t, k) := Kdf3(Cr, Q)
+ wireguard_kdf3(chaining_key, tau, key, chaining_key, peer->preshared_key, WIREGUARD_SESSION_KEY_LEN);
+
+ // Hr := Hash(Hr | t)
+ wireguard_mix_hash(hash, tau, WIREGUARD_HASH_LEN);
+
+ // msg.empty := AEAD(k, 0, E, Hr)
+ if (wireguard_aead_decrypt(NULL, src->enc_empty, sizeof(src->enc_empty), hash, WIREGUARD_HASH_LEN, 0, key)) {
+ // Hr := Hash(Hr | msg.empty)
+ // Not required as discarded
+
+ //Copy details to handshake
+ memcpy(handshake->remote_ephemeral, e, WIREGUARD_HASH_LEN);
+ memcpy(handshake->hash, hash, WIREGUARD_HASH_LEN);
+ memcpy(handshake->chaining_key, chaining_key, WIREGUARD_HASH_LEN);
+ handshake->remote_index = src->sender;
+
+ result = true;
+ } else {
+ // Decrypt failed
+ }
+
+ } else {
+ // X25519 fail
+ }
+
+ } else {
+ // X25519 fail
+ }
+
+ }
+ crypto_zero(key, sizeof(key));
+ crypto_zero(hash, sizeof(hash));
+ crypto_zero(chaining_key, sizeof(chaining_key));
+ crypto_zero(ephemeral_private, sizeof(ephemeral_private));
+ crypto_zero(static_private, sizeof(static_private));
+ crypto_zero(preshared_key, sizeof(preshared_key));
+ crypto_zero(tau, sizeof(tau));
+
+ return result;
+}
+
+bool wireguard_process_cookie_message(struct wireguard_device *device, struct wireguard_peer *peer, struct message_cookie_reply *src) {
+ uint8_t cookie[WIREGUARD_COOKIE_LEN];
+ bool result = false;
+
+ if (peer->handshake_mac1_valid) {
+
+ result = wireguard_xaead_decrypt(cookie, src->enc_cookie, sizeof(src->enc_cookie), peer->handshake_mac1, WIREGUARD_COOKIE_LEN, src->nonce, peer->label_cookie_key);
+
+ if (result) {
+ // 5.4.7 Under Load: Cookie Reply Message
+ // Upon receiving this message, if it is valid, the only thing the recipient of this message should do is store the cookie along with the time at which it was received
+ memcpy(peer->cookie, cookie, WIREGUARD_COOKIE_LEN);
+ peer->cookie_millis = wireguard_sys_now();
+ peer->handshake_mac1_valid = false;
+ }
+ } else {
+ // We didn't send any initiation packet so we shouldn't be getting a cookie reply!
+ }
+ return result;
+}
+
+bool wireguard_create_handshake_initiation(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_initiation *dst) {
+ uint8_t timestamp[WIREGUARD_TAI64N_LEN];
+ uint8_t key[WIREGUARD_SESSION_KEY_LEN];
+ uint8_t dh_calculation[WIREGUARD_PUBLIC_KEY_LEN];
+ bool result = false;
+
+ struct wireguard_handshake *handshake = &peer->handshake;
+
+ memset(dst, 0, sizeof(struct message_handshake_initiation));
+
+ // Ci := Hash(Construction) (precalculated hash)
+ memcpy(handshake->chaining_key, construction_hash, WIREGUARD_HASH_LEN);
+
+ // Hi := Hash(Ci || Identifier)
+ memcpy(handshake->hash, identifier_hash, WIREGUARD_HASH_LEN);
+
+ // Hi := Hash(Hi || Spubr)
+ wireguard_mix_hash(handshake->hash, peer->public_key, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // (Eprivi, Epubi) := DH-Generate()
+ wireguard_generate_private_key(handshake->ephemeral_private);
+ if (wireguard_generate_public_key(dst->ephemeral, handshake->ephemeral_private)) {
+
+ // Ci := Kdf1(Ci, Epubi)
+ wireguard_kdf1(handshake->chaining_key, handshake->chaining_key, dst->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.ephemeral := Epubi
+ // Done above - public keys is calculated into dst->ephemeral
+
+ // Hi := Hash(Hi || msg.ephemeral)
+ wireguard_mix_hash(handshake->hash, dst->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Calculate DH(Eprivi,Spubr)
+ wireguard_x25519(dh_calculation, handshake->ephemeral_private, peer->public_key);
+ if (!crypto_equal(dh_calculation, zero_key, WIREGUARD_PUBLIC_KEY_LEN)) {
+
+ // (Ci,k) := Kdf2(Ci,DH(Eprivi,Spubr))
+ wireguard_kdf2(handshake->chaining_key, key, handshake->chaining_key, dh_calculation, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.static := AEAD(k,0,Spubi, Hi)
+ wireguard_aead_encrypt(dst->enc_static, device->public_key, WIREGUARD_PUBLIC_KEY_LEN, handshake->hash, WIREGUARD_HASH_LEN, 0, key);
+
+ // Hi := Hash(Hi || msg.static)
+ wireguard_mix_hash(handshake->hash, dst->enc_static, sizeof(dst->enc_static));
+
+ // (Ci,k) := Kdf2(Ci,DH(Sprivi,Spubr))
+ // note DH(Sprivi,Spubr) is precomputed per peer
+ wireguard_kdf2(handshake->chaining_key, key, handshake->chaining_key, peer->public_key_dh, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.timestamp := AEAD(k, 0, Timestamp(), Hi)
+ wireguard_tai64n_now(timestamp);
+ wireguard_aead_encrypt(dst->enc_timestamp, timestamp, WIREGUARD_TAI64N_LEN, handshake->hash, WIREGUARD_HASH_LEN, 0, key);
+
+ // Hi := Hash(Hi || msg.timestamp)
+ wireguard_mix_hash(handshake->hash, dst->enc_timestamp, sizeof(dst->enc_timestamp));
+
+ dst->type = MESSAGE_HANDSHAKE_INITIATION;
+ dst->sender = wireguard_generate_unique_index(device);
+
+ handshake->valid = true;
+ handshake->initiator = true;
+ handshake->local_index = dst->sender;
+
+ result = true;
+ }
+ }
+
+ if (result) {
+ // 5.4.4 Cookie MACs
+ // msg.mac1 := Mac(Hash(Label-Mac1 || Spubm' ), msgA)
+ // The value Hash(Label-Mac1 || Spubm' ) above can be pre-computed
+ wireguard_mac(dst->mac1, dst, (sizeof(struct message_handshake_initiation)-(2*WIREGUARD_COOKIE_LEN)), peer->label_mac1_key, WIREGUARD_SESSION_KEY_LEN);
+
+ // if Lm = E or Lm ≥ 120:
+ if ((peer->cookie_millis == 0) || wireguard_expired(peer->cookie_millis, COOKIE_SECRET_MAX_AGE)) {
+ // msg.mac2 := 0
+ crypto_zero(dst->mac2, WIREGUARD_COOKIE_LEN);
+ } else {
+ // msg.mac2 := Mac(Lm, msgB)
+ wireguard_mac(dst->mac2, dst, (sizeof(struct message_handshake_initiation)-(WIREGUARD_COOKIE_LEN)), peer->cookie, WIREGUARD_COOKIE_LEN);
+
+ }
+ }
+
+ crypto_zero(key, sizeof(key));
+ crypto_zero(dh_calculation, sizeof(dh_calculation));
+ return result;
+}
+
+bool wireguard_create_handshake_response(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_response *dst) {
+ struct wireguard_handshake *handshake = &peer->handshake;
+ uint8_t key[WIREGUARD_SESSION_KEY_LEN];
+ uint8_t dh_calculation[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t tau[WIREGUARD_HASH_LEN];
+ bool result = false;
+
+ memset(dst, 0, sizeof(struct message_handshake_response));
+
+ if (handshake->valid && !handshake->initiator) {
+
+ // (Eprivr, Epubr) := DH-Generate()
+ wireguard_generate_private_key(handshake->ephemeral_private);
+ if (wireguard_generate_public_key(dst->ephemeral, handshake->ephemeral_private)) {
+
+ // Cr := Kdf1(Cr,Epubr)
+ wireguard_kdf1(handshake->chaining_key, handshake->chaining_key, dst->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // msg.ephemeral := Epubr
+ // Copied above when generated
+
+ // Hr := Hash(Hr || msg.ephemeral)
+ wireguard_mix_hash(handshake->hash, dst->ephemeral, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Cr := Kdf1(Cr, DH(Eprivr, Epubi))
+ // Calculate DH(Eprivi,Spubr)
+ wireguard_x25519(dh_calculation, handshake->ephemeral_private, handshake->remote_ephemeral);
+ if (!crypto_equal(dh_calculation, zero_key, WIREGUARD_PUBLIC_KEY_LEN)) {
+ wireguard_kdf1(handshake->chaining_key, handshake->chaining_key, dh_calculation, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // Cr := Kdf1(Cr, DH(Eprivr, Spubi))
+ // Calculate DH(Eprivi,Spubr)
+ wireguard_x25519(dh_calculation, handshake->ephemeral_private, peer->public_key);
+ if (!crypto_equal(dh_calculation, zero_key, WIREGUARD_PUBLIC_KEY_LEN)) {
+ wireguard_kdf1(handshake->chaining_key, handshake->chaining_key, dh_calculation, WIREGUARD_PUBLIC_KEY_LEN);
+
+ // (Cr, t, k) := Kdf3(Cr, Q)
+ wireguard_kdf3(handshake->chaining_key, tau, key, handshake->chaining_key, peer->preshared_key, WIREGUARD_SESSION_KEY_LEN);
+
+ // Hr := Hash(Hr | t)
+ wireguard_mix_hash(handshake->hash, tau, WIREGUARD_HASH_LEN);
+
+ // msg.empty := AEAD(k, 0, E, Hr)
+ wireguard_aead_encrypt(dst->enc_empty, NULL, 0, handshake->hash, WIREGUARD_HASH_LEN, 0, key);
+
+ // Hr := Hash(Hr | msg.empty)
+ wireguard_mix_hash(handshake->hash, dst->enc_empty, sizeof(dst->enc_empty));
+
+ dst->type = MESSAGE_HANDSHAKE_RESPONSE;
+ dst->receiver = handshake->remote_index;
+ dst->sender = wireguard_generate_unique_index(device);
+ // Update handshake object too
+ handshake->local_index = dst->sender;
+
+ result = true;
+ } else {
+ // Bad x25519
+ }
+ } else {
+ // Bad x25519
+ }
+
+ } else {
+ // Failed to generate DH
+ }
+ }
+
+ if (result) {
+ // 5.4.4 Cookie MACs
+ // msg.mac1 := Mac(Hash(Label-Mac1 || Spubm' ), msgA)
+ // The value Hash(Label-Mac1 || Spubm' ) above can be pre-computed
+ wireguard_mac(dst->mac1, dst, (sizeof(struct message_handshake_response)-(2*WIREGUARD_COOKIE_LEN)), peer->label_mac1_key, WIREGUARD_SESSION_KEY_LEN);
+
+ // if Lm = E or Lm ≥ 120:
+ if ((peer->cookie_millis == 0) || wireguard_expired(peer->cookie_millis, COOKIE_SECRET_MAX_AGE)) {
+ // msg.mac2 := 0
+ crypto_zero(dst->mac2, WIREGUARD_COOKIE_LEN);
+ } else {
+ // msg.mac2 := Mac(Lm, msgB)
+ wireguard_mac(dst->mac2, dst, (sizeof(struct message_handshake_response)-(WIREGUARD_COOKIE_LEN)), peer->cookie, WIREGUARD_COOKIE_LEN);
+ }
+ }
+
+ crypto_zero(key, sizeof(key));
+ crypto_zero(dh_calculation, sizeof(dh_calculation));
+ crypto_zero(tau, sizeof(tau));
+ return result;
+}
+
+void wireguard_create_cookie_reply(struct wireguard_device *device, struct message_cookie_reply *dst, const uint8_t *mac1, uint32_t index, uint8_t *source_addr_port, size_t source_length) {
+ uint8_t cookie[WIREGUARD_COOKIE_LEN];
+ crypto_zero(dst, sizeof(struct message_cookie_reply));
+ dst->type = MESSAGE_COOKIE_REPLY;
+ dst->receiver = index;
+ wireguard_random_bytes(dst->nonce, COOKIE_NONCE_LEN);
+ generate_peer_cookie(device, cookie, source_addr_port, source_length);
+ wireguard_xaead_encrypt(dst->enc_cookie, cookie, WIREGUARD_COOKIE_LEN, mac1, WIREGUARD_COOKIE_LEN, dst->nonce, device->label_cookie_key);
+}
+
+bool wireguard_peer_init(struct wireguard_device *device, struct wireguard_peer *peer, const uint8_t *public_key, const uint8_t *preshared_key) {
+ // Clear out structure
+ memset(peer, 0, sizeof(struct wireguard_peer));
+
+ if (device->valid) {
+ // Copy across the public key into our peer structure
+ memcpy(peer->public_key, public_key, WIREGUARD_PUBLIC_KEY_LEN);
+ if (preshared_key) {
+ memcpy(peer->preshared_key, preshared_key, WIREGUARD_SESSION_KEY_LEN);
+ } else {
+ crypto_zero(peer->preshared_key, WIREGUARD_SESSION_KEY_LEN);
+ }
+
+ if (wireguard_x25519(peer->public_key_dh, device->private_key, peer->public_key) == 0) {
+ // Zero out handshake
+ memset(&peer->handshake, 0, sizeof(struct wireguard_handshake));
+ peer->handshake.valid = false;
+
+ // Zero out any cookie info - we haven't received one yet
+ peer->cookie_millis = 0;
+ memset(&peer->cookie, 0, WIREGUARD_COOKIE_LEN);
+
+ // Precompute keys to deal with mac1/2 calculation
+ wireguard_mac_key(peer->label_mac1_key, peer->public_key, LABEL_MAC1, sizeof(LABEL_MAC1));
+ wireguard_mac_key(peer->label_cookie_key, peer->public_key, LABEL_COOKIE, sizeof(LABEL_COOKIE));
+
+ peer->valid = true;
+ } else {
+ crypto_zero(peer->public_key_dh, WIREGUARD_PUBLIC_KEY_LEN);
+ }
+ }
+ return peer->valid;
+}
+
+bool wireguard_device_init(struct wireguard_device *device, const uint8_t *private_key) {
+ // Set the private key and calculate public key from it
+ memcpy(device->private_key, private_key, WIREGUARD_PRIVATE_KEY_LEN);
+ // Ensure private key is correctly "clamped"
+ wireguard_clamp_private_key(device->private_key);
+ device->valid = wireguard_generate_public_key(device->public_key, private_key);
+ if (device->valid) {
+ generate_cookie_secret(device);
+ // 5.4.4 Cookie MACs - The value Hash(Label-Mac1 || Spubm' ) above can be pre-computed.
+ wireguard_mac_key(device->label_mac1_key, device->public_key, LABEL_MAC1, sizeof(LABEL_MAC1));
+ // 5.4.7 Under Load: Cookie Reply Message - The value Hash(Label-Cookie || Spubm) above can be pre-computed.
+ wireguard_mac_key(device->label_cookie_key, device->public_key, LABEL_COOKIE, sizeof(LABEL_COOKIE));
+
+ } else {
+ crypto_zero(device->private_key, WIREGUARD_PRIVATE_KEY_LEN);
+ }
+ return device->valid;
+}
+
+void wireguard_encrypt_packet(uint8_t *dst, const uint8_t *src, size_t src_len, struct wireguard_keypair *keypair) {
+ wireguard_aead_encrypt(dst, src, src_len, NULL, 0, keypair->sending_counter, keypair->sending_key);
+ keypair->sending_counter++;
+}
+
+bool wireguard_decrypt_packet(uint8_t *dst, const uint8_t *src, size_t src_len, uint64_t counter, struct wireguard_keypair *keypair) {
+ return wireguard_aead_decrypt(dst, src, src_len, NULL, 0, counter, keypair->receiving_key);
+}
+
+bool wireguard_base64_decode(const char *str, uint8_t *out, size_t *outlen) {
+ uint32_t accum = 0; // We accumulate upto four blocks of 6 bits into this to form 3 bytes output
+ uint8_t char_count = 0; // How many characters have we processed in this block
+ int byte_count = 3; // How many bytes are we expecting in current 4 char block
+ int len = 0; // result length in bytes
+ bool result = true;
+ uint8_t bits;
+ char c;
+ char *ptr;
+ int x;
+ size_t inlen;
+
+ if (!str) {
+ return false;
+ }
+
+ inlen = strlen(str);
+
+ for (x = 0; x < inlen; x++) {
+ c = str[x];
+ if (c == '=') {
+ // This is '=' padding at end of string - decrease the number of bytes to write
+ bits = 0;
+ byte_count--;
+ if (byte_count < 0) {
+ // Too much padding!
+ result = false;
+ break;
+ }
+ } else {
+ if (byte_count != 3) {
+ // Padding only allowed at end - this is a valid byte and we have already seen padding
+ result = false;
+ break;
+ }
+ ptr = strchr(base64_lookup, c);
+ if (ptr) {
+ bits = (uint8_t)((ptr - base64_lookup) & 0x3F);
+ } else {
+ // invalid character in input string
+ result = false;
+ break;
+ }
+ }
+
+ accum = (accum << 6) | bits;
+ char_count++;
+
+ if (char_count == 4) {
+ if (len + byte_count > *outlen) {
+ // Output buffer overflow
+ result = false;
+ break;
+ }
+ out[len++] = (uint8_t)((accum >> 16) & 0xFF);
+ if (byte_count > 1) {
+ out[len++] = (uint8_t)((accum >> 8) & 0xFF);
+ }
+ if (byte_count > 2) {
+ out[len++] = (uint8_t)(accum & 0xFF);
+ }
+ char_count = 0;
+ accum = 0;
+ }
+ }
+ if (char_count != 0) {
+ // We require padding to multiple of 3 input length - bytes are missing from output!
+ result = false;
+ }
+ *outlen = len;
+ return result;
+}
+
+bool wireguard_base64_encode(const uint8_t *in, size_t inlen, char *out, size_t *outlen) {
+ bool result = false;
+ int read_offset = 0;
+ int write_offset = 0;
+ uint8_t byte1, byte2, byte3;
+ uint32_t tmp;
+ char c;
+ size_t len = 4 * ((inlen + 2) / 3);
+ int padding = (3 - (inlen % 3));
+ if (padding > 2) padding = 0;
+ if (*outlen > len) {
+
+ while (read_offset < inlen) {
+ // Read three bytes
+ byte1 = (read_offset < inlen) ? in[read_offset++] : 0;
+ byte2 = (read_offset < inlen) ? in[read_offset++] : 0;
+ byte3 = (read_offset < inlen) ? in[read_offset++] : 0;
+ // Turn into 24 bit intermediate
+ tmp = (byte1 << 16) | (byte2 << 8) | (byte3);
+ // Write out 4 characters each representing 6 bits of input
+ out[write_offset++] = base64_lookup[(tmp >> 18) & 0x3F];
+ out[write_offset++] = base64_lookup[(tmp >> 12) & 0x3F];
+ c = (write_offset < len - padding) ? base64_lookup[(tmp >> 6) & 0x3F] : '=';
+ out[write_offset++] = c;
+ c = (write_offset < len - padding) ? base64_lookup[(tmp) & 0x3F] : '=';
+ out[write_offset++] = c;
+ }
+ out[len] = '\0';
+ *outlen = len;
+ result = true;
+ } else {
+ // Not enough data to put in base64 and null terminate
+ }
+ return result;
+}
diff --git a/lib/WireGuard-ESP32/src/wireguard.h b/lib/WireGuard-ESP32/src/wireguard.h
new file mode 100644
index 00000000..961792a0
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/wireguard.h
@@ -0,0 +1,287 @@
+/*
+ * Ported to ESP32 Arduino by Kenta Ida (fuga@fugafuga.org)
+ * The original license is below:
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+#ifndef _WIREGUARD_H_
+#define _WIREGUARD_H_
+
+#include
+#include
+#include
+
+// Note: these are only required for definitions in device/peer for netif, udp_pcb, ip_addr_t and u16_t
+#include "lwip/netif.h"
+#include "lwip/udp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/arch.h"
+
+// Platform-specific functions that need to be implemented per-platform
+#include "wireguard-platform.h"
+
+// tai64n contains 64-bit seconds and 32-bit nano offset (12 bytes)
+#define WIREGUARD_TAI64N_LEN (12)
+// Auth algorithm is chacha20pol1305 which is 128bit (16 byte) authenticator
+#define WIREGUARD_AUTHTAG_LEN (16)
+// Hash algorithm is blake2s which makes 32 byte hashes
+#define WIREGUARD_HASH_LEN (32)
+// Public key algo is curve22519 which uses 32 byte keys
+#define WIREGUARD_PUBLIC_KEY_LEN (32)
+// Public key algo is curve22519 which uses 32 byte keys
+#define WIREGUARD_PRIVATE_KEY_LEN (32)
+// Symmetric session keys are chacha20/poly1305 which uses 32 byte keys
+#define WIREGUARD_SESSION_KEY_LEN (32)
+
+// Timers / Limits
+#define WIREGUARD_COOKIE_LEN (16)
+#define COOKIE_SECRET_MAX_AGE (2 * 60)
+#define COOKIE_NONCE_LEN (24)
+
+#define REKEY_AFTER_MESSAGES (1ULL << 60)
+#define REJECT_AFTER_MESSAGES (0xFFFFFFFFFFFFFFFFULL - (1ULL << 13))
+#define REKEY_AFTER_TIME (120)
+#define REJECT_AFTER_TIME (180)
+#define REKEY_TIMEOUT (5)
+#define KEEPALIVE_TIMEOUT (10)
+
+struct wireguard_keypair {
+ bool valid;
+ bool initiator; // Did we initiate this session (send the initiation packet rather than sending the response packet)
+ uint32_t keypair_millis;
+
+ uint8_t sending_key[WIREGUARD_SESSION_KEY_LEN];
+ bool sending_valid;
+ uint64_t sending_counter;
+
+ uint8_t receiving_key[WIREGUARD_SESSION_KEY_LEN];
+ bool receiving_valid;
+
+ uint32_t last_tx;
+ uint32_t last_rx;
+
+ uint32_t replay_bitmap;
+ uint64_t replay_counter;
+
+ uint32_t local_index; // This is the index we generated for our end
+ uint32_t remote_index; // This is the index on the other end
+};
+
+struct wireguard_handshake {
+ bool valid;
+ bool initiator;
+ uint32_t local_index;
+ uint32_t remote_index;
+ uint8_t ephemeral_private[WIREGUARD_PRIVATE_KEY_LEN];
+ uint8_t remote_ephemeral[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t hash[WIREGUARD_HASH_LEN];
+ uint8_t chaining_key[WIREGUARD_HASH_LEN];
+};
+
+struct wireguard_allowed_ip {
+ bool valid;
+ ip_addr_t ip;
+ ip_addr_t mask;
+};
+
+struct wireguard_peer {
+ bool valid; // Is this peer initialised?
+ bool active; // Should we be actively trying to connect?
+
+ // This is the configured IP of the peer (endpoint)
+ ip_addr_t connect_ip;
+ u16_t connect_port;
+ // This is the latest received IP/port
+ ip_addr_t ip;
+ u16_t port;
+ // keep-alive interval in seconds, 0 is disable
+ uint16_t keepalive_interval;
+
+ struct wireguard_allowed_ip allowed_source_ips[WIREGUARD_MAX_SRC_IPS];
+
+ uint8_t public_key[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t preshared_key[WIREGUARD_SESSION_KEY_LEN];
+
+ // Precomputed DH(Sprivi,Spubr) with device private key, and peer public key
+ uint8_t public_key_dh[WIREGUARD_PUBLIC_KEY_LEN];
+
+ // Session keypairs
+ struct wireguard_keypair curr_keypair;
+ struct wireguard_keypair prev_keypair;
+ struct wireguard_keypair next_keypair;
+
+ // 5.1 Silence is a Virtue: The responder keeps track of the greatest timestamp received per peer
+ uint8_t greatest_timestamp[WIREGUARD_TAI64N_LEN];
+
+ // The active handshake that is happening
+ struct wireguard_handshake handshake;
+
+ // Decrypted cookie from the responder
+ uint32_t cookie_millis;
+ uint8_t cookie[WIREGUARD_COOKIE_LEN];
+
+ // The latest mac1 we sent with initiation
+ bool handshake_mac1_valid;
+ uint8_t handshake_mac1[WIREGUARD_COOKIE_LEN];
+
+ // Precomputed keys for use in mac validation
+ uint8_t label_cookie_key[WIREGUARD_SESSION_KEY_LEN];
+ uint8_t label_mac1_key[WIREGUARD_SESSION_KEY_LEN];
+
+ // The last time we received a valid initiation message
+ uint32_t last_initiation_rx;
+ // The last time we sent an initiation message to this peer
+ uint32_t last_initiation_tx;
+
+ // last_tx and last_rx of data packets
+ uint32_t last_tx;
+ uint32_t last_rx;
+
+ // We set this flag on RX/TX of packets if we think that we should initiate a new handshake
+ bool send_handshake;
+};
+
+struct wireguard_device {
+ // Maybe have a "Device private" member to abstract these?
+ struct netif *netif;
+ struct udp_pcb *udp_pcb;
+
+ struct netif *underlying_netif;
+
+ uint8_t public_key[WIREGUARD_PUBLIC_KEY_LEN];
+ uint8_t private_key[WIREGUARD_PRIVATE_KEY_LEN];
+
+ uint8_t cookie_secret[WIREGUARD_HASH_LEN];
+ uint32_t cookie_secret_millis;
+
+ // Precalculated
+ uint8_t label_cookie_key[WIREGUARD_SESSION_KEY_LEN];
+ uint8_t label_mac1_key[WIREGUARD_SESSION_KEY_LEN];
+
+ // List of peers associated with this device
+ struct wireguard_peer peers[WIREGUARD_MAX_PEERS];
+
+ bool valid;
+};
+
+#define MESSAGE_INVALID 0
+#define MESSAGE_HANDSHAKE_INITIATION 1
+#define MESSAGE_HANDSHAKE_RESPONSE 2
+#define MESSAGE_COOKIE_REPLY 3
+#define MESSAGE_TRANSPORT_DATA 4
+
+
+// 5.4.2 First Message: Initiator to Responder
+struct message_handshake_initiation {
+ uint8_t type;
+ uint8_t reserved[3];
+ uint32_t sender;
+ uint8_t ephemeral[32];
+ uint8_t enc_static[32 + WIREGUARD_AUTHTAG_LEN];
+ uint8_t enc_timestamp[WIREGUARD_TAI64N_LEN + WIREGUARD_AUTHTAG_LEN];
+ uint8_t mac1[WIREGUARD_COOKIE_LEN];
+ uint8_t mac2[WIREGUARD_COOKIE_LEN];
+} __attribute__ ((__packed__));
+
+// 5.4.3 Second Message: Responder to Initiator
+struct message_handshake_response {
+ uint8_t type;
+ uint8_t reserved[3];
+ uint32_t sender;
+ uint32_t receiver;
+ uint8_t ephemeral[32];
+ uint8_t enc_empty[0 + WIREGUARD_AUTHTAG_LEN];
+ uint8_t mac1[WIREGUARD_COOKIE_LEN];
+ uint8_t mac2[WIREGUARD_COOKIE_LEN];
+} __attribute__ ((__packed__));
+
+// 5.4.7 Under Load: Cookie Reply Message
+struct message_cookie_reply {
+ uint8_t type;
+ uint8_t reserved[3];
+ uint32_t receiver;
+ uint8_t nonce[COOKIE_NONCE_LEN];
+ uint8_t enc_cookie[WIREGUARD_COOKIE_LEN + WIREGUARD_AUTHTAG_LEN];
+} __attribute__ ((__packed__));
+
+// 5.4.6 Subsequent Messages: Transport Data Messages
+struct message_transport_data {
+ uint8_t type;
+ uint8_t reserved[3];
+ uint32_t receiver;
+ uint8_t counter[8];
+ // Followed by encrypted data
+ uint8_t enc_packet[];
+} __attribute__ ((__packed__));
+
+// Initialise the WireGuard system - need to call this before anything else
+void wireguard_init();
+bool wireguard_device_init(struct wireguard_device *device, const uint8_t *private_key);
+bool wireguard_peer_init(struct wireguard_device *device, struct wireguard_peer *peer, const uint8_t *public_key, const uint8_t *preshared_key);
+
+struct wireguard_peer *peer_alloc(struct wireguard_device *device);
+uint8_t wireguard_peer_index(struct wireguard_device *device, struct wireguard_peer *peer);
+struct wireguard_peer *peer_lookup_by_pubkey(struct wireguard_device *device, uint8_t *public_key);
+struct wireguard_peer *peer_lookup_by_peer_index(struct wireguard_device *device, uint8_t peer_index);
+struct wireguard_peer *peer_lookup_by_receiver(struct wireguard_device *device, uint32_t receiver);
+struct wireguard_peer *peer_lookup_by_handshake(struct wireguard_device *device, uint32_t receiver);
+
+void wireguard_start_session(struct wireguard_peer *peer, bool initiator);
+
+void keypair_update(struct wireguard_peer *peer, struct wireguard_keypair *received_keypair);
+void keypair_destroy(struct wireguard_keypair *keypair);
+
+struct wireguard_keypair *get_peer_keypair_for_idx(struct wireguard_peer *peer, uint32_t idx);
+bool wireguard_check_replay(struct wireguard_keypair *keypair, uint64_t seq);
+
+uint8_t wireguard_get_message_type(const uint8_t *data, size_t len);
+
+struct wireguard_peer *wireguard_process_initiation_message(struct wireguard_device *device, struct message_handshake_initiation *msg);
+bool wireguard_process_handshake_response(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_response *src);
+bool wireguard_process_cookie_message(struct wireguard_device *device, struct wireguard_peer *peer, struct message_cookie_reply *src);
+
+bool wireguard_create_handshake_initiation(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_initiation *dst);
+bool wireguard_create_handshake_response(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_response *dst);
+void wireguard_create_cookie_reply(struct wireguard_device *device, struct message_cookie_reply *dst, const uint8_t *mac1, uint32_t index, uint8_t *source_addr_port, size_t source_length);
+
+
+bool wireguard_check_mac1(struct wireguard_device *device, const uint8_t *data, size_t len, const uint8_t *mac1);
+bool wireguard_check_mac2(struct wireguard_device *device, const uint8_t *data, size_t len, uint8_t *source_addr_port, size_t source_length, const uint8_t *mac2);
+
+bool wireguard_expired(uint32_t created_millis, uint32_t valid_seconds);
+
+void wireguard_encrypt_packet(uint8_t *dst, const uint8_t *src, size_t src_len, struct wireguard_keypair *keypair);
+bool wireguard_decrypt_packet(uint8_t *dst, const uint8_t *src, size_t src_len, uint64_t counter, struct wireguard_keypair *keypair);
+
+bool wireguard_base64_decode(const char *str, uint8_t *out, size_t *outlen);
+bool wireguard_base64_encode(const uint8_t *in, size_t inlen, char *out, size_t *outlen);
+
+#endif /* _WIREGUARD_H_ */
diff --git a/lib/WireGuard-ESP32/src/wireguardif.c b/lib/WireGuard-ESP32/src/wireguardif.c
new file mode 100644
index 00000000..d64ad854
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/wireguardif.c
@@ -0,0 +1,1028 @@
+/*
+ * Ported to ESP32 Arduino by Kenta Ida (fuga@fugafuga.org)
+ * The original license is below:
+ *
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+#include "wireguardif.h"
+
+#include
+#include
+
+#include "lwip/netif.h"
+#include "lwip/ip.h"
+#include "lwip/udp.h"
+#include "lwip/mem.h"
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+
+#include "wireguard.h"
+#include "crypto.h"
+#include "esp_log.h"
+#include "tcpip_adapter.h"
+
+#include "esp32-hal-log.h"
+
+#define WIREGUARDIF_TIMER_MSECS 400
+
+#define TAG "[WireGuard] "
+
+static void update_peer_addr(struct wireguard_peer *peer, const ip_addr_t *addr, u16_t port) {
+ peer->ip = *addr;
+ peer->port = port;
+}
+
+static struct wireguard_peer *peer_lookup_by_allowed_ip(struct wireguard_device *device, const ip_addr_t *ipaddr) {
+ struct wireguard_peer *result = NULL;
+ struct wireguard_peer *tmp;
+ int x;
+ int y;
+ for (x=0; (!result) && (x < WIREGUARD_MAX_PEERS); x++) {
+ tmp = &device->peers[x];
+ if (tmp->valid) {
+ for (y=0; y < WIREGUARD_MAX_SRC_IPS; y++) {
+ if ((tmp->allowed_source_ips[y].valid) && ip_addr_netcmp(ipaddr, &tmp->allowed_source_ips[y].ip, ip_2_ip4(&tmp->allowed_source_ips[y].mask))) {
+ result = tmp;
+ break;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+static bool wireguardif_can_send_initiation(struct wireguard_peer *peer) {
+ return ((peer->last_initiation_tx == 0) || (wireguard_expired(peer->last_initiation_tx, REKEY_TIMEOUT)));
+}
+
+static err_t wireguardif_peer_output(struct netif *netif, struct pbuf *q, struct wireguard_peer *peer) {
+ struct wireguard_device *device = (struct wireguard_device *)netif->state;
+ // Send to last know port, not the connect port
+ //TODO: Support DSCP and ECN - lwip requires this set on PCB globally, not per packet
+ return udp_sendto_if(device->udp_pcb, q, &peer->ip, peer->port, device->underlying_netif);
+}
+
+static err_t wireguardif_device_output(struct wireguard_device *device, struct pbuf *q, const ip_addr_t *ipaddr, u16_t port) {
+ return udp_sendto_if(device->udp_pcb, q, ipaddr, port, device->underlying_netif);
+}
+
+static err_t wireguardif_output_to_peer(struct netif *netif, struct pbuf *q, const ip_addr_t *ipaddr, struct wireguard_peer *peer) {
+ // The LWIP IP layer wants to send an IP packet out over the interface - we need to encrypt and send it to the peer
+ struct message_transport_data *hdr;
+ struct pbuf *pbuf;
+ err_t result;
+ size_t unpadded_len;
+ size_t padded_len;
+ size_t header_len = 16;
+ uint8_t *dst;
+ uint32_t now;
+ struct wireguard_keypair *keypair = &peer->curr_keypair;
+
+ // Note: We may not be able to use the current keypair if we haven't received data, may need to resort to using previous keypair
+ if (keypair->valid && (!keypair->initiator) && (keypair->last_rx == 0)) {
+ keypair = &peer->prev_keypair;
+ }
+
+ if (keypair->valid && (keypair->initiator || keypair->last_rx != 0)) {
+
+ if (
+ !wireguard_expired(keypair->keypair_millis, REJECT_AFTER_TIME) &&
+ (keypair->sending_counter < REJECT_AFTER_MESSAGES)
+ ) {
+
+ // Calculate the outgoing packet size - round up to next 16 bytes, add 16 bytes for header
+ if (q) {
+ // This is actual transport data
+ unpadded_len = q->tot_len;
+ } else {
+ // This is a keep-alive
+ unpadded_len = 0;
+ }
+ padded_len = (unpadded_len + 15) & 0xFFFFFFF0; // Round up to next 16 byte boundary
+
+ // The buffer needs to be allocated from "transport" pool to leave room for LwIP generated IP headers
+ // The IP packet consists of 16 byte header (struct message_transport_data), data padded upto 16 byte boundary + encrypted auth tag (16 bytes)
+ pbuf = pbuf_alloc(PBUF_TRANSPORT, header_len + padded_len + WIREGUARD_AUTHTAG_LEN, PBUF_RAM);
+ if (pbuf) {
+ log_v(TAG "preparing transport data...");
+ // Note: allocating pbuf from RAM above guarantees that the pbuf is in one section and not chained
+ // - i.e payload points to the contiguous memory region
+ memset(pbuf->payload, 0, pbuf->tot_len);
+
+ hdr = (struct message_transport_data *)pbuf->payload;
+
+ hdr->type = MESSAGE_TRANSPORT_DATA;
+ hdr->receiver = keypair->remote_index;
+ // Alignment required... pbuf_alloc has probably aligned data, but want to be sure
+ U64TO8_LITTLE(hdr->counter, keypair->sending_counter);
+
+ // Copy the encrypted (padded) data to the output packet - chacha20poly1305_encrypt() can encrypt data in-place which avoids call to mem_malloc
+ dst = &hdr->enc_packet[0];
+ if ((padded_len > 0) && q) {
+ // Note: before copying make sure we have inserted the IP header checksum
+ // The IP header checksum (and other checksums in the IP packet - e.g. ICMP) need to be calculated by LWIP before calling
+ // The Wireguard interface always needs checksums to be generated in software but the base netif may have some checksums generated by hardware
+
+ // Copy pbuf to memory - handles case where pbuf is chained
+ pbuf_copy_partial(q, dst, unpadded_len, 0);
+ }
+
+ // Then encrypt
+ wireguard_encrypt_packet(dst, dst, padded_len, keypair);
+
+ result = wireguardif_peer_output(netif, pbuf, peer);
+
+ if (result == ERR_OK) {
+ now = wireguard_sys_now();
+ peer->last_tx = now;
+ keypair->last_tx = now;
+ }
+
+ pbuf_free(pbuf);
+
+ // Check to see if we should rekey
+ if (keypair->sending_counter >= REKEY_AFTER_MESSAGES) {
+ peer->send_handshake = true;
+ } else if (keypair->initiator && wireguard_expired(keypair->keypair_millis, REKEY_AFTER_TIME)) {
+ peer->send_handshake = true;
+ }
+
+ } else {
+ // Failed to allocate memory
+ result = ERR_MEM;
+ }
+ } else {
+ // key has expired...
+ keypair_destroy(keypair);
+ result = ERR_CONN;
+ }
+ } else {
+ // No valid keys!
+ result = ERR_CONN;
+ }
+ return result;
+}
+
+// This is used as the output function for the Wireguard netif
+// The ipaddr here is the one inside the VPN which we use to lookup the correct peer/endpoint
+static err_t wireguardif_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ip4addr) {
+ struct wireguard_device *device = (struct wireguard_device *)netif->state;
+ // Send to peer that matches dest IP
+ ip_addr_t ipaddr;
+ ip_addr_copy_from_ip4(ipaddr, *ip4addr);
+ struct wireguard_peer *peer = peer_lookup_by_allowed_ip(device, &ipaddr);
+ if (peer) {
+ return wireguardif_output_to_peer(netif, q, &ipaddr, peer);
+ } else {
+ return ERR_RTE;
+ }
+}
+
+static void wireguardif_send_keepalive(struct wireguard_device *device, struct wireguard_peer *peer) {
+ // Send a NULL packet as a keep-alive
+ wireguardif_output_to_peer(device->netif, NULL, NULL, peer);
+}
+
+static void wireguardif_process_response_message(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_response *response, const ip_addr_t *addr, u16_t port) {
+ if (wireguard_process_handshake_response(device, peer, response)) {
+ // Packet is good
+ // Update the peer location
+ log_i(TAG "good handshake from %08x:%d", addr->u_addr.ip4.addr, port);
+ update_peer_addr(peer, addr, port);
+
+ wireguard_start_session(peer, true);
+ wireguardif_send_keepalive(device, peer);
+
+ // Set the IF-UP flag on netif
+ netif_set_link_up(device->netif);
+ } else {
+ // Packet bad
+ log_i(TAG "bad handshake from %08x:%d", addr->u_addr.ip4.addr, port);
+ }
+}
+
+static bool peer_add_ip(struct wireguard_peer *peer, ip_addr_t ip, ip_addr_t mask) {
+ bool result = false;
+ struct wireguard_allowed_ip *allowed;
+ int x;
+ // Look for existing match first
+ for (x=0; x < WIREGUARD_MAX_SRC_IPS; x++) {
+ allowed = &peer->allowed_source_ips[x];
+ if ((allowed->valid) && ip_addr_cmp(&allowed->ip, &ip) && ip_addr_cmp(&allowed->mask, &mask)) {
+ result = true;
+ break;
+ }
+ }
+ if (!result) {
+ // Look for a free slot
+ for (x=0; x < WIREGUARD_MAX_SRC_IPS; x++) {
+ allowed = &peer->allowed_source_ips[x];
+ if (!allowed->valid) {
+ allowed->valid = true;
+ allowed->ip = ip;
+ allowed->mask = mask;
+ result = true;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+static void wireguardif_process_data_message(struct wireguard_device *device, struct wireguard_peer *peer, struct message_transport_data *data_hdr, size_t data_len, const ip_addr_t *addr, u16_t port) {
+ struct wireguard_keypair *keypair;
+ uint64_t nonce;
+ uint8_t *src;
+ size_t src_len;
+ struct pbuf *pbuf;
+ struct ip_hdr *iphdr;
+ ip_addr_t dest;
+ bool dest_ok = false;
+ int x;
+ uint32_t now;
+ uint16_t header_len = 0xFFFF;
+ uint32_t idx = data_hdr->receiver;
+
+ keypair = get_peer_keypair_for_idx(peer, idx);
+
+ if (keypair) {
+ if (
+ (keypair->receiving_valid) &&
+ !wireguard_expired(keypair->keypair_millis, REJECT_AFTER_TIME) &&
+ (keypair->sending_counter < REJECT_AFTER_MESSAGES)
+
+ ) {
+
+ nonce = U8TO64_LITTLE(data_hdr->counter);
+ src = &data_hdr->enc_packet[0];
+ src_len = data_len;
+
+ // We don't know the unpadded size until we have decrypted the packet and validated/inspected the IP header
+ pbuf = pbuf_alloc(PBUF_TRANSPORT, src_len - WIREGUARD_AUTHTAG_LEN, PBUF_RAM);
+ if (pbuf) {
+ // Decrypt the packet
+ memset(pbuf->payload, 0, pbuf->tot_len);
+ if (wireguard_decrypt_packet(pbuf->payload, src, src_len, nonce, keypair)) {
+
+ // 3. Since the packet has authenticated correctly, the source IP of the outer UDP/IP packet is used to update the endpoint for peer TrMv...WXX0.
+ // Update the peer location
+ update_peer_addr(peer, addr, port);
+
+ now = wireguard_sys_now();
+ keypair->last_rx = now;
+ peer->last_rx = now;
+
+ // Might need to shuffle next key --> current keypair
+ keypair_update(peer, keypair);
+
+ // Check to see if we should rekey
+ if (keypair->initiator && wireguard_expired(keypair->keypair_millis, REJECT_AFTER_TIME - peer->keepalive_interval - REKEY_TIMEOUT)) {
+ peer->send_handshake = true;
+ }
+
+ // Make sure that link is reported as up
+ netif_set_link_up(device->netif);
+
+ if (pbuf->tot_len > 0) {
+ //4a. Once the packet payload is decrypted, the interface has a plaintext packet. If this is not an IP packet, it is dropped.
+ iphdr = (struct ip_hdr *)pbuf->payload;
+ // Check for packet replay / dupes
+ if (wireguard_check_replay(keypair, nonce)) {
+
+ // 4b. Otherwise, WireGuard checks to see if the source IP address of the plaintext inner-packet routes correspondingly in the cryptokey routing table
+ // Also check packet length!
+#if LWIP_IPV4
+ if (IPH_V(iphdr) == 4) {
+ ip_addr_copy_from_ip4(dest, iphdr->dest);
+ for (x=0; x < WIREGUARD_MAX_SRC_IPS; x++) {
+ if (peer->allowed_source_ips[x].valid) {
+ if (ip_addr_netcmp(&dest, &peer->allowed_source_ips[x].ip, ip_2_ip4(&peer->allowed_source_ips[x].mask))) {
+ dest_ok = true;
+ header_len = PP_NTOHS(IPH_LEN(iphdr));
+ break;
+ }
+ }
+ }
+ }
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+ if (IPH_V(iphdr) == 6) {
+ // TODO: IPV6 support for route filtering
+ header_len = PP_NTOHS(IPH_LEN(iphdr));
+ dest_ok = true;
+ }
+#endif /* LWIP_IPV6 */
+ if (header_len <= pbuf->tot_len) {
+
+ // 5. If the plaintext packet has not been dropped, it is inserted into the receive queue of the wg0 interface.
+ if (dest_ok) {
+ // Send packet to be process by LWIP
+ ip_input(pbuf, device->netif);
+ // pbuf is owned by IP layer now
+ pbuf = NULL;
+ }
+ } else {
+ // IP header is corrupt or lied about packet size
+ }
+ } else {
+ // This is a duplicate packet / replayed / too far out of order
+ }
+ } else {
+ // This was a keep-alive packet
+ }
+ }
+
+ if (pbuf) {
+ pbuf_free(pbuf);
+ }
+ }
+
+
+ } else {
+ //After Reject-After-Messages transport data messages or after the current secure session is Reject- After-Time seconds old,
+ // whichever comes first, WireGuard will refuse to send or receive any more transport data messages using the current secure session,
+ // until a new secure session is created through the 1-RTT handshake
+ keypair_destroy(keypair);
+ }
+
+ } else {
+ // Could not locate valid keypair for remote index
+ }
+}
+
+static struct pbuf *wireguardif_initiate_handshake(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_initiation *msg, err_t *error) {
+ struct pbuf *pbuf = NULL;
+ err_t err = ERR_OK;
+ if (wireguard_create_handshake_initiation(device, peer, msg)) {
+ // Send this packet out!
+ pbuf = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct message_handshake_initiation), PBUF_RAM);
+ if (pbuf) {
+ err = pbuf_take(pbuf, msg, sizeof(struct message_handshake_initiation));
+ if (err == ERR_OK) {
+ // OK!
+ } else {
+ pbuf_free(pbuf);
+ pbuf = NULL;
+ }
+ } else {
+ err = ERR_MEM;
+ }
+ } else {
+ err = ERR_ARG;
+ }
+ if (error) {
+ *error = err;
+ }
+ return pbuf;
+}
+
+static void wireguardif_send_handshake_response(struct wireguard_device *device, struct wireguard_peer *peer) {
+ struct message_handshake_response packet;
+ struct pbuf *pbuf = NULL;
+ err_t err = ERR_OK;
+
+ if (wireguard_create_handshake_response(device, peer, &packet)) {
+
+ wireguard_start_session(peer, false);
+
+ // Send this packet out!
+ pbuf = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct message_handshake_response), PBUF_RAM);
+ if (pbuf) {
+ err = pbuf_take(pbuf, &packet, sizeof(struct message_handshake_response));
+ if (err == ERR_OK) {
+ // OK!
+ wireguardif_peer_output(device->netif, pbuf, peer);
+ }
+ pbuf_free(pbuf);
+ }
+ }
+}
+
+static size_t get_source_addr_port(const ip_addr_t *addr, u16_t port, uint8_t *buf, size_t buflen) {
+ size_t result = 0;
+
+#if LWIP_IPV4
+ if (IP_IS_V4(addr) && (buflen >= 4)) {
+ U32TO8_BIG(buf + result, PP_NTOHL(ip4_addr_get_u32(ip_2_ip4(addr))));
+ result += 4;
+ }
+#endif
+#if LWIP_IPV6
+ if (IP_IS_V6(addr) && (buflen >= 16)) {
+ U16TO8_BIG(buf + result + 0, IP6_ADDR_BLOCK1(ip_2_ip6(addr)));
+ U16TO8_BIG(buf + result + 2, IP6_ADDR_BLOCK2(ip_2_ip6(addr)));
+ U16TO8_BIG(buf + result + 4, IP6_ADDR_BLOCK3(ip_2_ip6(addr)));
+ U16TO8_BIG(buf + result + 6, IP6_ADDR_BLOCK4(ip_2_ip6(addr)));
+ U16TO8_BIG(buf + result + 8, IP6_ADDR_BLOCK5(ip_2_ip6(addr)));
+ U16TO8_BIG(buf + result + 10, IP6_ADDR_BLOCK6(ip_2_ip6(addr)));
+ U16TO8_BIG(buf + result + 12, IP6_ADDR_BLOCK7(ip_2_ip6(addr)));
+ U16TO8_BIG(buf + result + 14, IP6_ADDR_BLOCK8(ip_2_ip6(addr)));
+ result += 16;
+ }
+#endif
+ if (buflen >= result + 2) {
+ U16TO8_BIG(buf + result, port);
+ result += 2;
+ }
+ return result;
+}
+
+static void wireguardif_send_handshake_cookie(struct wireguard_device *device, const uint8_t *mac1, uint32_t index, const ip_addr_t *addr, u16_t port) {
+ struct message_cookie_reply packet;
+ struct pbuf *pbuf = NULL;
+ err_t err = ERR_OK;
+ uint8_t source_buf[18];
+ size_t source_len = get_source_addr_port(addr, port, source_buf, sizeof(source_buf));
+
+ wireguard_create_cookie_reply(device, &packet, mac1, index, source_buf, source_len);
+
+ // Send this packet out!
+ pbuf = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct message_cookie_reply), PBUF_RAM);
+ if (pbuf) {
+ err = pbuf_take(pbuf, &packet, sizeof(struct message_cookie_reply));
+ if (err == ERR_OK) {
+ wireguardif_device_output(device, pbuf, addr, port);
+ }
+ pbuf_free(pbuf);
+ }
+}
+
+static bool wireguardif_check_initiation_message(struct wireguard_device *device, struct message_handshake_initiation *msg, const ip_addr_t *addr, u16_t port) {
+ bool result = false;
+ uint8_t *data = (uint8_t *)msg;
+ uint8_t source_buf[18];
+ size_t source_len;
+ // We received an initiation packet check it is valid
+
+ if (wireguard_check_mac1(device, data, sizeof(struct message_handshake_initiation) - (2 * WIREGUARD_COOKIE_LEN), msg->mac1)) {
+ // mac1 is valid!
+ if (!wireguard_is_under_load()) {
+ // If we aren't under load we only need mac1 to be correct
+ result = true;
+ } else {
+ // If we are under load then check mac2
+ source_len = get_source_addr_port(addr, port, source_buf, sizeof(source_buf));
+
+ result = wireguard_check_mac2(device, data, sizeof(struct message_handshake_initiation) - (WIREGUARD_COOKIE_LEN), source_buf, source_len, msg->mac2);
+
+ if (!result) {
+ // mac2 is invalid (cookie may have expired) or not present
+ // 5.3 Denial of Service Mitigation & Cookies
+ // If the responder receives a message with a valid msg.mac1 yet with an invalid msg.mac2, and is under load, it may respond with a cookie reply message
+ wireguardif_send_handshake_cookie(device, msg->mac1, msg->sender, addr, port);
+ }
+ }
+
+ } else {
+ // mac1 is invalid
+ }
+ return result;
+}
+
+static bool wireguardif_check_response_message(struct wireguard_device *device, struct message_handshake_response *msg, const ip_addr_t *addr, u16_t port) {
+ bool result = false;
+ uint8_t *data = (uint8_t *)msg;
+ uint8_t source_buf[18];
+ size_t source_len;
+ // We received an initiation packet check it is valid
+
+ if (wireguard_check_mac1(device, data, sizeof(struct message_handshake_response) - (2 * WIREGUARD_COOKIE_LEN), msg->mac1)) {
+ // mac1 is valid!
+ if (!wireguard_is_under_load()) {
+ // If we aren't under load we only need mac1 to be correct
+ result = true;
+ } else {
+ // If we are under load then check mac2
+ source_len = get_source_addr_port(addr, port, source_buf, sizeof(source_buf));
+
+ result = wireguard_check_mac2(device, data, sizeof(struct message_handshake_response) - (WIREGUARD_COOKIE_LEN), source_buf, source_len, msg->mac2);
+
+ if (!result) {
+ // mac2 is invalid (cookie may have expired) or not present
+ // 5.3 Denial of Service Mitigation & Cookies
+ // If the responder receives a message with a valid msg.mac1 yet with an invalid msg.mac2, and is under load, it may respond with a cookie reply message
+ wireguardif_send_handshake_cookie(device, msg->mac1, msg->sender, addr, port);
+ }
+ }
+
+ } else {
+ // mac1 is invalid
+ }
+ return result;
+}
+
+
+void wireguardif_network_rx(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
+ LWIP_ASSERT("wireguardif_network_rx: invalid arg", arg != NULL);
+ LWIP_ASSERT("wireguardif_network_rx: invalid pbuf", p != NULL);
+ // We have received a packet from the base_netif to our UDP port - process this as a possible Wireguard packet
+ struct wireguard_device *device = (struct wireguard_device *)arg;
+ struct wireguard_peer *peer;
+ uint8_t *data = p->payload;
+ size_t len = p->len; // This buf, not chained ones
+
+ struct message_handshake_initiation *msg_initiation;
+ struct message_handshake_response *msg_response;
+ struct message_cookie_reply *msg_cookie;
+ struct message_transport_data *msg_data;
+
+ uint8_t type = wireguard_get_message_type(data, len);
+ ESP_LOGV(TAG, "network_rx: %08x:%d", addr->u_addr.ip4.addr, port);
+
+ switch (type) {
+ case MESSAGE_HANDSHAKE_INITIATION:
+ msg_initiation = (struct message_handshake_initiation *)data;
+ log_i(TAG "HANDSHAKE_INITIATION: %08x:%d", addr->u_addr.ip4.addr, port);
+ // Check mac1 (and optionally mac2) are correct - note it may internally generate a cookie reply packet
+ if (wireguardif_check_initiation_message(device, msg_initiation, addr, port)) {
+
+ peer = wireguard_process_initiation_message(device, msg_initiation);
+ if (peer) {
+ // Update the peer location
+ update_peer_addr(peer, addr, port);
+
+ // Send back a handshake response
+ wireguardif_send_handshake_response(device, peer);
+ }
+ }
+ break;
+
+ case MESSAGE_HANDSHAKE_RESPONSE:
+ log_i(TAG "HANDSHAKE_RESPONSE: %08x:%d", addr->u_addr.ip4.addr, port);
+ msg_response = (struct message_handshake_response *)data;
+
+ // Check mac1 (and optionally mac2) are correct - note it may internally generate a cookie reply packet
+ if (wireguardif_check_response_message(device, msg_response, addr, port)) {
+
+ peer = peer_lookup_by_handshake(device, msg_response->receiver);
+ if (peer) {
+ // Process the handshake response
+ wireguardif_process_response_message(device, peer, msg_response, addr, port);
+ }
+ }
+ break;
+
+ case MESSAGE_COOKIE_REPLY:
+ log_i(TAG "COOKIE_REPLY: %08x:%d", addr->u_addr.ip4.addr, port);
+ msg_cookie = (struct message_cookie_reply *)data;
+ peer = peer_lookup_by_handshake(device, msg_cookie->receiver);
+ if (peer) {
+ if (wireguard_process_cookie_message(device, peer, msg_cookie)) {
+ // Update the peer location
+ update_peer_addr(peer, addr, port);
+
+ // Don't send anything out - we stay quiet until the next initiation message
+ }
+ }
+ break;
+
+ case MESSAGE_TRANSPORT_DATA:
+ ESP_LOGV(TAG, "TRANSPORT_DATA: %08x:%d", addr->u_addr.ip4.addr, port);
+
+ msg_data = (struct message_transport_data *)data;
+ peer = peer_lookup_by_receiver(device, msg_data->receiver);
+ if (peer) {
+ // header is 16 bytes long so take that off the length
+ wireguardif_process_data_message(device, peer, msg_data, len - 16, addr, port);
+ }
+ break;
+
+ default:
+ // Unknown or bad packet header
+ break;
+ }
+ // Release data!
+ pbuf_free(p);
+}
+
+static err_t wireguard_start_handshake(struct netif *netif, struct wireguard_peer *peer) {
+ struct wireguard_device *device = (struct wireguard_device *)netif->state;
+ err_t result;
+ struct pbuf *pbuf;
+ struct message_handshake_initiation msg;
+
+ pbuf = wireguardif_initiate_handshake(device, peer, &msg, &result);
+ if (pbuf) {
+ result = wireguardif_peer_output(netif, pbuf, peer);
+ log_i(TAG "start handshake %08x,%d - %d", peer->ip.u_addr.ip4.addr, peer->port, result);
+ pbuf_free(pbuf);
+ peer->send_handshake = false;
+ peer->last_initiation_tx = wireguard_sys_now();
+ memcpy(peer->handshake_mac1, msg.mac1, WIREGUARD_COOKIE_LEN);
+ peer->handshake_mac1_valid = true;
+ }
+ return result;
+}
+
+static err_t wireguardif_lookup_peer(struct netif *netif, u8_t peer_index, struct wireguard_peer **out) {
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("state != NULL", (netif->state != NULL));
+ struct wireguard_device *device = (struct wireguard_device *)netif->state;
+ struct wireguard_peer *peer = NULL;
+ err_t result;
+
+ if (device->valid) {
+ peer = peer_lookup_by_peer_index(device, peer_index);
+ if (peer) {
+ result = ERR_OK;
+ } else {
+ result = ERR_ARG;
+ }
+ } else {
+ result = ERR_ARG;
+ }
+ *out = peer;
+ return result;
+}
+
+err_t wireguardif_connect(struct netif *netif, u8_t peer_index) {
+ struct wireguard_peer *peer;
+ err_t result = wireguardif_lookup_peer(netif, peer_index, &peer);
+ if (result == ERR_OK) {
+ // Check that a valid connect ip and port have been set
+ if (!ip_addr_isany(&peer->connect_ip) && (peer->connect_port > 0)) {
+ // Set the flag that we want to try connecting
+ peer->active = true;
+ peer->ip = peer->connect_ip;
+ peer->port = peer->connect_port;
+ result = ERR_OK;
+ } else {
+ result = ERR_ARG;
+ }
+ }
+ return result;
+}
+
+err_t wireguardif_disconnect(struct netif *netif, u8_t peer_index) {
+ struct wireguard_peer *peer;
+ err_t result = wireguardif_lookup_peer(netif, peer_index, &peer);
+ if (result == ERR_OK) {
+ // Set the flag that we want to try connecting
+ peer->active = false;
+ // Wipe out current keys
+ keypair_destroy(&peer->next_keypair);
+ keypair_destroy(&peer->curr_keypair);
+ keypair_destroy(&peer->prev_keypair);
+ result = ERR_OK;
+ }
+ return result;
+}
+
+err_t wireguardif_peer_is_up(struct netif *netif, u8_t peer_index, ip_addr_t *current_ip, u16_t *current_port) {
+ struct wireguard_peer *peer;
+ err_t result = wireguardif_lookup_peer(netif, peer_index, &peer);
+ if (result == ERR_OK) {
+ if ((peer->curr_keypair.valid) || (peer->prev_keypair.valid)) {
+ result = ERR_OK;
+ } else {
+ result = ERR_CONN;
+ }
+ if (current_ip) {
+ *current_ip = peer->ip;
+ }
+ if (current_port) {
+ *current_port = peer->port;
+ }
+ }
+ return result;
+}
+
+err_t wireguardif_remove_peer(struct netif *netif, u8_t peer_index) {
+ struct wireguard_peer *peer;
+ err_t result = wireguardif_lookup_peer(netif, peer_index, &peer);
+ if (result == ERR_OK) {
+ crypto_zero(peer, sizeof(struct wireguard_peer));
+ peer->valid = false;
+ result = ERR_OK;
+ }
+ return result;
+}
+
+err_t wireguardif_update_endpoint(struct netif *netif, u8_t peer_index, const ip_addr_t *ip, u16_t port) {
+ struct wireguard_peer *peer;
+ err_t result = wireguardif_lookup_peer(netif, peer_index, &peer);
+ if (result == ERR_OK) {
+ peer->connect_ip = *ip;
+ peer->connect_port = port;
+ result = ERR_OK;
+ }
+ return result;
+}
+
+
+err_t wireguardif_add_peer(struct netif *netif, struct wireguardif_peer *p, u8_t *peer_index) {
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("state != NULL", (netif->state != NULL));
+ LWIP_ASSERT("p != NULL", (p != NULL));
+ struct wireguard_device *device = (struct wireguard_device *)netif->state;
+ err_t result;
+ uint8_t public_key[WIREGUARD_PUBLIC_KEY_LEN];
+ size_t public_key_len = sizeof(public_key);
+ struct wireguard_peer *peer = NULL;
+
+ uint32_t t1 = wireguard_sys_now();
+
+ if (wireguard_base64_decode(p->public_key, public_key, &public_key_len)
+ && (public_key_len == WIREGUARD_PUBLIC_KEY_LEN)) {
+
+ // See if the peer is already registered
+ peer = peer_lookup_by_pubkey(device, public_key);
+ if (!peer) {
+ // Not active - see if we have room to allocate a new one
+ peer = peer_alloc(device);
+ if (peer) {
+
+ if (wireguard_peer_init(device, peer, public_key, p->preshared_key)) {
+
+ peer->connect_ip = p->endpoint_ip;
+ peer->connect_port = p->endport_port;
+ peer->ip = peer->connect_ip;
+ peer->port = peer->connect_port;
+ if (p->keep_alive == WIREGUARDIF_KEEPALIVE_DEFAULT) {
+ peer->keepalive_interval = KEEPALIVE_TIMEOUT;
+ } else {
+ peer->keepalive_interval = p->keep_alive;
+ }
+ peer_add_ip(peer, p->allowed_ip, p->allowed_mask);
+ memcpy(peer->greatest_timestamp, p->greatest_timestamp, sizeof(peer->greatest_timestamp));
+
+ result = ERR_OK;
+ } else {
+ result = ERR_ARG;
+ }
+ } else {
+ result = ERR_MEM;
+ }
+ } else {
+ result = ERR_OK;
+ }
+ } else {
+ result = ERR_ARG;
+ }
+
+ uint32_t t2 = wireguard_sys_now();
+ log_i(TAG "Adding peer took %ums\r\n", (t2-t1));
+
+ if (peer_index) {
+ if (peer) {
+ *peer_index = wireguard_peer_index(device, peer);
+ } else {
+ *peer_index = WIREGUARDIF_INVALID_INDEX;
+ }
+ }
+ return result;
+}
+
+static bool should_send_initiation(struct wireguard_peer *peer) {
+ bool result = false;
+ if (wireguardif_can_send_initiation(peer)) {
+ if (peer->send_handshake) {
+ result = true;
+ } else if (peer->curr_keypair.valid && !peer->curr_keypair.initiator && wireguard_expired(peer->curr_keypair.keypair_millis, REJECT_AFTER_TIME - peer->keepalive_interval)) {
+ result = true;
+ } else if (!peer->curr_keypair.valid && peer->active) {
+ result = true;
+ }
+ }
+ return result;
+}
+
+static bool should_send_keepalive(struct wireguard_peer *peer) {
+ bool result = false;
+ if (peer->keepalive_interval > 0) {
+ if ((peer->curr_keypair.valid) || (peer->prev_keypair.valid)) {
+ if (wireguard_expired(peer->last_tx, peer->keepalive_interval)) {
+ result = true;
+ }
+ }
+ }
+ return result;
+}
+
+static bool should_destroy_current_keypair(struct wireguard_peer *peer) {
+ bool result = false;
+ if (peer->curr_keypair.valid &&
+ (wireguard_expired(peer->curr_keypair.keypair_millis, REJECT_AFTER_TIME) ||
+ (peer->curr_keypair.sending_counter >= REJECT_AFTER_MESSAGES))
+ ) {
+ result = true;
+ }
+ return result;
+}
+
+static bool should_reset_peer(struct wireguard_peer *peer) {
+ bool result = false;
+ if (peer->curr_keypair.valid && (wireguard_expired(peer->curr_keypair.keypair_millis, REJECT_AFTER_TIME * 3))) {
+ result = true;
+ }
+ return result;
+}
+
+static void wireguardif_tmr(void *arg) {
+ struct wireguard_device *device = (struct wireguard_device *)arg;
+ struct wireguard_peer *peer;
+ int x;
+ // Reschedule this timer
+ sys_timeout(WIREGUARDIF_TIMER_MSECS, wireguardif_tmr, device);
+
+ // Check periodic things
+ bool link_up = false;
+ for (x=0; x < WIREGUARD_MAX_PEERS; x++) {
+ peer = &device->peers[x];
+ if (peer->valid) {
+ // Do we need to rekey / send a handshake?
+ if (should_reset_peer(peer)) {
+ // Nothing back for too long - we should wipe out all crypto state
+ keypair_destroy(&peer->next_keypair);
+ keypair_destroy(&peer->curr_keypair);
+ keypair_destroy(&peer->prev_keypair);
+ handshake_destroy(&peer->handshake);
+
+ // Revert back to default IP/port if these were altered
+ peer->ip = peer->connect_ip;
+ peer->port = peer->connect_port;
+ }
+ if (should_destroy_current_keypair(peer)) {
+ // Destroy current keypair
+ keypair_destroy(&peer->curr_keypair);
+ }
+ if (should_send_keepalive(peer)) {
+ wireguardif_send_keepalive(device, peer);
+ }
+ if (should_send_initiation(peer)) {
+ wireguard_start_handshake(device->netif, peer);
+ }
+
+ if ((peer->curr_keypair.valid) || (peer->prev_keypair.valid)) {
+ link_up = true;
+ }
+ }
+ }
+
+ if (!link_up) {
+ // Clear the IF-UP flag on netif
+ netif_set_link_down(device->netif);
+ }
+}
+
+void wireguardif_shutdown(struct netif *netif) {
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("state != NULL", (netif->state != NULL));
+
+ struct wireguard_device * device = (struct wireguard_device *)netif->state;
+ // Disable timer.
+ sys_untimeout(wireguardif_tmr, device);
+ // remove UDP context.
+ if( device->udp_pcb ) {
+ udp_disconnect(device->udp_pcb);
+ udp_remove(device->udp_pcb);
+ device->udp_pcb = NULL;
+ }
+ // remove device context.
+ free(device);
+ netif->state = NULL;
+}
+
+err_t wireguardif_init(struct netif *netif) {
+ err_t result;
+ struct wireguardif_init_data *init_data;
+ struct wireguard_device *device;
+ struct udp_pcb *udp;
+ uint8_t private_key[WIREGUARD_PRIVATE_KEY_LEN];
+ size_t private_key_len = sizeof(private_key);
+
+ struct netif* underlying_netif;
+ tcpip_adapter_get_netif(TCPIP_ADAPTER_IF_STA, &underlying_netif);
+ log_i(TAG "underlying_netif = %p", underlying_netif);
+
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+ LWIP_ASSERT("state != NULL", (netif->state != NULL));
+
+ // We need to initialise the wireguard module
+ wireguard_init();
+ log_i(TAG "wireguard module initialized.");
+
+ if (netif && netif->state) {
+
+ // The init data is passed into the netif_add call as the 'state' - we will replace this with our private state data
+ init_data = (struct wireguardif_init_data *)netif->state;
+
+ // Clear out and set if function is successful
+ netif->state = NULL;
+
+ if (wireguard_base64_decode(init_data->private_key, private_key, &private_key_len)
+ && (private_key_len == WIREGUARD_PRIVATE_KEY_LEN)) {
+
+ udp = udp_new();
+
+ if (udp) {
+ result = udp_bind(udp, IP_ADDR_ANY, init_data->listen_port); // Note this listens on all interfaces! Really just want the passed netif
+ if (result == ERR_OK) {
+ device = (struct wireguard_device *)mem_calloc(1, sizeof(struct wireguard_device));
+ if (device) {
+ device->netif = netif;
+ device->underlying_netif = underlying_netif;
+ //udp_bind_netif(udp, underlying_netif);
+
+ device->udp_pcb = udp;
+ log_d(TAG "start device initialization");
+ // Per-wireguard netif/device setup
+ uint32_t t1 = wireguard_sys_now();
+ if (wireguard_device_init(device, private_key)) {
+ uint32_t t2 = wireguard_sys_now();
+ log_d(TAG "Device init took %ums\r\n", (t2-t1));
+
+#if LWIP_CHECKSUM_CTRL_PER_NETIF
+ NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
+#endif
+ netif->state = device;
+ netif->name[0] = 'w';
+ netif->name[1] = 'g';
+ netif->output = wireguardif_output;
+ netif->linkoutput = NULL;
+ netif->hwaddr_len = 0;
+ netif->mtu = WIREGUARDIF_MTU;
+ // We set up no state flags here - caller should set them
+ // NETIF_FLAG_LINK_UP is automatically set/cleared when at least one peer is connected
+ netif->flags = 0;
+
+ udp_recv(udp, wireguardif_network_rx, device);
+
+ // Start a periodic timer for this wireguard device
+ sys_timeout(WIREGUARDIF_TIMER_MSECS, wireguardif_tmr, device);
+
+ result = ERR_OK;
+ } else {
+ log_e(TAG "failed to initialize WireGuard device.");
+ mem_free(device);
+ device = NULL;
+ udp_remove(udp);
+ result = ERR_ARG;
+ }
+ } else {
+ log_e(TAG "failed to allocate device context.");
+ udp_remove(udp);
+ result = ERR_MEM;
+ }
+ } else {
+ log_e(TAG "failed to bind UDP err=%d", result);
+ udp_remove(udp);
+ }
+
+ } else {
+ log_e(TAG "failed to allocate UDP");
+ result = ERR_MEM;
+ }
+ } else {
+ log_e(TAG "invalid init_data private key");
+ result = ERR_ARG;
+ }
+ } else {
+ log_e(TAG "netif or state is NULL: netif=%p, netif.state:%p", netif, netif ? netif->state : NULL);
+ result = ERR_ARG;
+ }
+ return result;
+}
+
+void wireguardif_peer_init(struct wireguardif_peer *peer) {
+ LWIP_ASSERT("peer != NULL", (peer != NULL));
+ memset(peer, 0, sizeof(struct wireguardif_peer));
+ // Caller must provide 'public_key'
+ peer->public_key = NULL;
+ ip_addr_set_any(false, &peer->endpoint_ip);
+ peer->endport_port = WIREGUARDIF_DEFAULT_PORT;
+ peer->keep_alive = WIREGUARDIF_KEEPALIVE_DEFAULT;
+ ip_addr_set_any(false, &peer->allowed_ip);
+ ip_addr_set_any(false, &peer->allowed_mask);
+ memset(peer->greatest_timestamp, 0, sizeof(peer->greatest_timestamp));
+ peer->preshared_key = NULL;
+}
diff --git a/lib/WireGuard-ESP32/src/wireguardif.h b/lib/WireGuard-ESP32/src/wireguardif.h
new file mode 100644
index 00000000..ad9d4a15
--- /dev/null
+++ b/lib/WireGuard-ESP32/src/wireguardif.h
@@ -0,0 +1,137 @@
+/*
+ * Ported to ESP32 Arduino by Kenta Ida (fuga@fugafuga.org)
+ * The original license is below:
+ *
+ * Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
+ * its contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Daniel Hope
+ */
+
+
+#ifndef _WIREGUARDIF_H_
+#define _WIREGUARDIF_H_
+
+#include "lwip/arch.h"
+#include "lwip/netif.h"
+#include "lwip/ip_addr.h"
+
+// Default MTU for WireGuard is 1420 bytes
+#define WIREGUARDIF_MTU (1420)
+
+#define WIREGUARDIF_DEFAULT_PORT (51820)
+#define WIREGUARDIF_KEEPALIVE_DEFAULT (0xFFFF)
+
+struct wireguardif_init_data {
+ // Required: the private key of this WireGuard network interface
+ const char *private_key;
+ // Required: What UDP port to listen on
+ u16_t listen_port;
+ // Optional: restrict send/receive of encapsulated WireGuard traffic to this network interface only (NULL to use routing table)
+ struct netif *bind_netif;
+};
+
+struct wireguardif_peer {
+ const char *public_key;
+ // Optional pre-shared key (32 bytes) - make sure this is NULL if not to be used
+ const uint8_t *preshared_key;
+ // tai64n of largest timestamp we have seen during handshake to avoid replays
+ uint8_t greatest_timestamp[12];
+
+ // Allowed ip/netmask (can add additional later but at least one is required)
+ ip_addr_t allowed_ip;
+ ip_addr_t allowed_mask;
+
+ // End-point details (may be blank)
+ ip_addr_t endpoint_ip;
+ u16_t endport_port;
+ u16_t keep_alive;
+};
+
+#define WIREGUARDIF_INVALID_INDEX (0xFF)
+
+/* static struct netif wg_netif_struct = {0};
+ * struct wireguard_interface wg;
+ * wg.private_key = "abcdefxxx..xxxxx=";
+ * wg.listen_port = 51820;
+ * wg.bind_netif = NULL; // Pass netif to listen on, NULL for all interfaces
+ *
+ * netif = netif_add(&netif_struct, &ipaddr, &netmask, &gateway, &wg, &wireguardif_init, &ip_input);
+ *
+ * netif_set_up(wg_net);
+ *
+ * struct wireguardif_peer peer;
+ * wireguardif_peer_init(&peer);
+ * peer.public_key = "apoehc...4322abcdfejg=;
+ * peer.preshared_key = NULL;
+ * peer.allowed_ip = allowed_ip;
+ * peer.allowed_mask = allowed_mask;
+ *
+ * // If you want to enable output connection
+ * peer.endpoint_ip = peer_ip;
+ * peer.endport_port = 12345;
+ *
+ * uint8_t wireguard_peer_index;
+ * wireguardif_add_peer(netif, &peer, &wireguard_peer_index);
+ *
+ * if ((wireguard_peer_index != WIREGUARDIF_INVALID_INDEX) && !ip_addr_isany(&peer.endpoint_ip)) {
+ * // Start outbound connection to peer
+ * wireguardif_connect(wg_net, wireguard_peer_index);
+ * }
+ *
+ */
+
+// Initialise a new WireGuard network interface (netif)
+err_t wireguardif_init(struct netif *netif);
+
+// Shutdown a WireGuard network interface (netif)
+void wireguardif_shutdown(struct netif *netif);
+
+// Helper to initialise the peer struct with defaults
+void wireguardif_peer_init(struct wireguardif_peer *peer);
+
+// Add a new peer to the specified interface - see wireguard.h for maximum number of peers allowed
+// On success the peer_index can be used to reference this peer in future function calls
+err_t wireguardif_add_peer(struct netif *netif, struct wireguardif_peer *peer, u8_t *peer_index);
+
+// Remove the given peer from the network interface
+err_t wireguardif_remove_peer(struct netif *netif, u8_t peer_index);
+
+// Update the "connect" IP of the given peer
+err_t wireguardif_update_endpoint(struct netif *netif, u8_t peer_index, const ip_addr_t *ip, u16_t port);
+
+// Try and connect to the given peer
+err_t wireguardif_connect(struct netif *netif, u8_t peer_index);
+
+// Stop trying to connect to the given peer
+err_t wireguardif_disconnect(struct netif *netif, u8_t peer_index);
+
+// Is the given peer "up"? A peer is up if it has a valid session key it can communicate with
+err_t wireguardif_peer_is_up(struct netif *netif, u8_t peer_index, ip_addr_t *current_ip, u16_t *current_port);
+
+#endif /* _WIREGUARDIF_H_ */
From 3789d446bd3c4ec18731b0e1ce025df04b4ec245 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Thu, 30 Nov 2023 15:25:09 +0100
Subject: [PATCH 012/135] fix some warnings in the wireguard library
---
lib/WireGuard-ESP32/src/wireguard.h | 1 +
lib/WireGuard-ESP32/src/wireguardif.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/WireGuard-ESP32/src/wireguard.h b/lib/WireGuard-ESP32/src/wireguard.h
index 961792a0..d5554926 100644
--- a/lib/WireGuard-ESP32/src/wireguard.h
+++ b/lib/WireGuard-ESP32/src/wireguard.h
@@ -272,6 +272,7 @@ bool wireguard_create_handshake_initiation(struct wireguard_device *device, stru
bool wireguard_create_handshake_response(struct wireguard_device *device, struct wireguard_peer *peer, struct message_handshake_response *dst);
void wireguard_create_cookie_reply(struct wireguard_device *device, struct message_cookie_reply *dst, const uint8_t *mac1, uint32_t index, uint8_t *source_addr_port, size_t source_length);
+void handshake_destroy(struct wireguard_handshake *handshake);
bool wireguard_check_mac1(struct wireguard_device *device, const uint8_t *data, size_t len, const uint8_t *mac1);
bool wireguard_check_mac2(struct wireguard_device *device, const uint8_t *data, size_t len, uint8_t *source_addr_port, size_t source_length, const uint8_t *mac2);
diff --git a/lib/WireGuard-ESP32/src/wireguardif.c b/lib/WireGuard-ESP32/src/wireguardif.c
index d64ad854..c8192f62 100644
--- a/lib/WireGuard-ESP32/src/wireguardif.c
+++ b/lib/WireGuard-ESP32/src/wireguardif.c
@@ -48,7 +48,7 @@
#include "wireguard.h"
#include "crypto.h"
#include "esp_log.h"
-#include "tcpip_adapter.h"
+#include "esp_netif.h"
#include "esp32-hal-log.h"
@@ -921,7 +921,7 @@ err_t wireguardif_init(struct netif *netif) {
size_t private_key_len = sizeof(private_key);
struct netif* underlying_netif;
- tcpip_adapter_get_netif(TCPIP_ADAPTER_IF_STA, &underlying_netif);
+ tcpip_adapter_get_netif(TCPIP_ADAPTER_IF_STA, (void **)&underlying_netif);
log_i(TAG "underlying_netif = %p", underlying_netif);
LWIP_ASSERT("netif != NULL", (netif != NULL));
From 2c94573edb7226ce510674f1e04e8142e6df9a0b Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 29 Nov 2023 20:41:28 +0100
Subject: [PATCH 013/135] add WireGuard implementation to increase security
WireGuard is really ideal for those IoT devices with limited resources.
---
data/en.json | 2 +-
data/main.js | 2 +-
include/hasp_conf.h | 8 ++
src/hasp/hasp_dispatch.cpp | 8 ++
src/hasp/hasp_nvs.cpp | 37 ++++++---
src/hasp_config.cpp | 51 +++++++++++--
src/hasp_config.h | 5 ++
src/hasp_debug.cpp | 4 +
src/hasp_debug.h | 1 +
src/lang/en_US.h | 7 ++
src/sys/net/hasp_network.cpp | 31 ++++++++
src/sys/net/hasp_network.h | 1 +
src/sys/net/hasp_wireguard.cpp | 131 ++++++++++++++++++++++++++++++++
src/sys/net/hasp_wireguard.h | 40 ++++++++++
src/sys/svc/hasp_http.cpp | 75 ++++++++++++++++++
src/sys/svc/hasp_http_async.cpp | 2 +-
16 files changed, 384 insertions(+), 21 deletions(-)
create mode 100644 src/sys/net/hasp_wireguard.cpp
create mode 100644 src/sys/net/hasp_wireguard.h
diff --git a/data/en.json b/data/en.json
index 0bfe12d4..248e4adc 100644
--- a/data/en.json
+++ b/data/en.json
@@ -1 +1 @@
-{"en":{"language":"English","home":{"title":"Main Menu","btn":"Main Menu","nav":"Home"},"save":"Save Settings","user":"Username","pass":"Password","hasp":{"title":"HASP Design","btn":"HASP Design","theme":"UI Theme","color1":"Primary color","color2":"Secondary color","pages":"Start Layout","font":"Default Font","startpage":"Startup Page","startdim":"Startup Dim"},"screenshot":{"title":"Screenshot","btn":"Screenshot","nav":"Screenshot","prev":"Prev Page","next":"Next Page","refresh":"Refresh"},"info":{"title":"Information","btn":"Information","nav":"Information"},"config":{"title":"Configuration","btn":"Configuration","nav":"Settings"},"ota":{"title":"Firmware Update","btn":"Firmware Update","nav":"Firmware","submit":"Update Firmware","file":"Firmware File","url":"Firmware URL","redirect":"Follow Redirects","never":"Never","strict":"Strict","always":"Always"},"editor":{"title":"File Editor","btn":"File Editor","nav":"File Editor"},"reset":{"title":"Factory Reset","btn":"Factory Reset","warning":"Warning","message":"This process will reset all settings to the default values. The internal flash will be erased and the device is restarted. You may need to connect to the WiFi AP displayed on the panel to reconfigure the device before accessing it again.","fileloss":"ALL FILES WILL BE LOST!"},"reboot":{"title":"Rebooting...","btn":"Restart","nav":"Reboot","message":"The device is rebooting."},"about":{"credits":"Based on the previous work of the following open source developers:","copyright":"Copyright ","rights":"All rights reserved.","clause1":"Permission 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:","clause2":"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.","clause3":"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.","mit":"MIT License","bsd":"BSD License","freebsd":"FreeBSD License","apache2":"Apache2 License"},"wifi":{"title":"Wifi Settings","btn":"Wifi Settings","ssid":"SSID"},"mqtt":{"title":"MQTT Settings","btn":"MQTT Settings","name":"Hostname","group":"Groupname","host":"Broker","port":"Port","node_t":"Node Topic","group_t":"Group Topic","broadcast_t":"Broadcast Topic","hass_t":"HA LWT Topic"},"http":{"title":"HTTP Settings","btn":"HTTP Settings"},"ftp":{"title":"FTP Settings","btn":"FTP Settings","port":"FTP Port","pasv":"Passive Port"},"gui":{"title":"Display Settings","btn":"Display Settings","antiburn":"Antiburn","calibrate":"Calibrate"},"gpio":"GPIO Settings","debug":{"title":"Debug Settings","btn":"Debug Settings","baud":"Baudrate","tele":"Tele Period","ansi":"Use ANSI codes","host":"Syslog Server","port":"Syslog Port","ietf":"IETF (RFC 5424)","bsd":"BSD (RFC 3164)","log":"Facility"},"time":{"title":"Time Settings","btn":"Time Settings","region":"Region","zone":"Timezone","tz":"Timezone","ntp":"NTP Servers"},"region":{"etc":"Etcetera ","continents":"Continents ","af":"Africa ","as":"Asia ","au":"Australia ","aq":"Antarctica ","eu":"Europe ","na":"North America ","sa":"South America ","islands":"Islands ","at":"Atlantic Ocean ","in":"Indian Ocean ","pa":"Pacific Ocean "}}}
\ No newline at end of file
+{"en":{"language":"English","home":{"title":"Main Menu","btn":"Main Menu","nav":"Home"},"save":"Save Settings","user":"Username","pass":"Password","hasp":{"title":"HASP Design","btn":"HASP Design","theme":"UI Theme","color1":"Primary color","color2":"Secondary color","pages":"Start Layout","font":"Default Font","startpage":"Startup Page","startdim":"Startup Dim"},"screenshot":{"title":"Screenshot","btn":"Screenshot","nav":"Screenshot","prev":"Prev Page","next":"Next Page","refresh":"Refresh"},"info":{"title":"Information","btn":"Information","nav":"Information"},"config":{"title":"Configuration","btn":"Configuration","nav":"Settings"},"ota":{"title":"Firmware Update","btn":"Firmware Update","nav":"Firmware","submit":"Update Firmware","file":"Firmware File","url":"Firmware URL","redirect":"Follow Redirects","never":"Never","strict":"Strict","always":"Always"},"editor":{"title":"File Editor","btn":"File Editor","nav":"File Editor"},"reset":{"title":"Factory Reset","btn":"Factory Reset","warning":"Warning","message":"This process will reset all settings to the default values. The internal flash will be erased and the device is restarted. You may need to connect to the WiFi AP displayed on the panel to reconfigure the device before accessing it again.","fileloss":"ALL FILES WILL BE LOST!"},"reboot":{"title":"Rebooting...","btn":"Restart","nav":"Reboot","message":"The device is rebooting."},"about":{"credits":"Based on the previous work of the following open source developers:","copyright":"Copyright ","rights":"All rights reserved.","clause1":"Permission 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:","clause2":"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.","clause3":"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.","mit":"MIT License","bsd":"BSD License","freebsd":"FreeBSD License","apache2":"Apache2 License"},"wifi":{"title":"Wifi Settings","btn":"Wifi Settings","ssid":"SSID"},"wg":{"title":"WireGuard Settings","btn":"WireGuard Settings","vpnip":"VPN IP","privkey":"Private Key","host":"Remote IP","port":"Remote Port","pubkey":"Remote Public Key"},"mqtt":{"title":"MQTT Settings","btn":"MQTT Settings","name":"Hostname","group":"Groupname","host":"Broker","port":"Port","node_t":"Node Topic","group_t":"Group Topic","broadcast_t":"Broadcast Topic","hass_t":"HA LWT Topic"},"http":{"title":"HTTP Settings","btn":"HTTP Settings"},"ftp":{"title":"FTP Settings","btn":"FTP Settings","port":"FTP Port","pasv":"Passive Port"},"gui":{"title":"Display Settings","btn":"Display Settings","antiburn":"Antiburn","calibrate":"Calibrate"},"gpio":"GPIO Settings","debug":{"title":"Debug Settings","btn":"Debug Settings","baud":"Baudrate","tele":"Tele Period","ansi":"Use ANSI codes","host":"Syslog Server","port":"Syslog Port","ietf":"IETF (RFC 5424)","bsd":"BSD (RFC 3164)","log":"Facility"},"time":{"title":"Time Settings","btn":"Time Settings","region":"Region","zone":"Timezone","tz":"Timezone","ntp":"NTP Servers"},"region":{"etc":"Etcetera ","continents":"Continents ","af":"Africa ","as":"Asia ","au":"Australia ","aq":"Antarctica ","eu":"Europe ","na":"North America ","sa":"South America ","islands":"Islands ","at":"Atlantic Ocean ","in":"Indian Ocean ","pa":"Pacific Ocean "}}}
\ No newline at end of file
diff --git a/data/main.js b/data/main.js
index a74ef0c9..989d9086 100644
--- a/data/main.js
+++ b/data/main.js
@@ -1 +1 @@
-import{createApp,reactive,createI18n}from"/static/petite-vue.hasp.js?COMMIT_HASH";const languages=[{code:"en",name:"English"},{code:"nl",name:"Nederlands"},{code:"fr",name:"Français"}];var locations={af:["Abidjan","Algiers","Bissau","Cairo","Casablanca","El_Aaiun","Johannesburg","Juba","Khartoum","Lagos","Maputo","Monrovia","Nairobi","Ndjamena","Sao_Tome","Tripoli","Tunis","Windhoek","Cape_Verde","Mauritius"],eu:["Ceuta","Danmarkshavn","Nuuk","Scoresbysund","Thule","Anadyr","Barnaul","Chita","Irkutsk","Kamchatka","Khandyga","Krasnoyarsk","Magadan","Novokuznetsk","Novosibirsk","Omsk","Sakhalin","Srednekolymsk","Tomsk","Ust-Nera","Vladivostok","Yakutsk","Yekaterinburg","Azores","Canary","Faroe","Madeira","Andorra","Astrakhan","Athens","Belgrade","Berlin","Brussels","Bucharest","Budapest","Chisinau","Dublin","Gibraltar","Helsinki","Istanbul","Kaliningrad","Kirov","Kyiv","Lisbon","London","Madrid","Malta","Minsk","Moscow","Paris","Prague","Riga","Rome","Samara","Saratov","Sofia","Tallinn","Tirane","Ulyanovsk","Vienna","Vilnius","Volgograd","Warsaw","Zurich"],as:["Almaty","Amman","Aqtau","Aqtobe","Ashgabat","Atyrau","Baghdad","Baku","Bangkok","Beirut","Bishkek","Choibalsan","Colombo","Damascus","Dhaka","Dili","Dubai","Dushanbe","Famagusta","Gaza","Hebron","Ho_Chi_Minh","Hong_Kong","Hovd","Jakarta","Jayapura","Jerusalem","Kabul","Karachi","Kathmandu","Kolkata","Kuching","Macau","Makassar","Manila","Nicosia","Oral","Pontianak","Pyongyang","Qatar","Qostanay","Qyzylorda","Riyadh","Samarkand","Seoul","Shanghai","Singapore","Taipei","Tashkent","Tbilisi","Tehran","Thimphu","Tokyo","Ulaanbaatar","Urumqi","Yangon","Yerevan","Chagos","Maldives"],au:["Perth","Eucla","Adelaide","Broken_Hill","Darwin","Brisbane","Hobart","Lindeman","Melbourne","Sydney","Lord_Howe"],na:["Adak","Anchorage","Bahia_Banderas","Barbados","Belize","Boise","Cambridge_Bay","Cancun","Chicago","Chihuahua","Ciudad_Juarez","Costa_Rica","Dawson","Dawson_Creek","Denver","Detroit","Edmonton","El_Salvador","Fort_Nelson","Glace_Bay","Goose_Bay","Grand_Turk","Guatemala","Halifax","Havana","Hermosillo","Indiana/Indianapolis","Indiana/Knox","Indiana/Marengo","Indiana/Petersburg","Indiana/Tell_City","Indiana/Vevay","Indiana/Vincennes","Indiana/Winamac","Inuvik","Iqaluit","Jamaica","Juneau","Kentucky/Louisville","Kentucky/Monticello","Los_Angeles","Managua","Martinique","Matamoros","Mazatlan","Menominee","Merida","Metlakatla","Mexico_City","Miquelon","Moncton","Monterrey","New_York","Nome","North_Dakota/Beulah","North_Dakota/Center","North_Dakota/New_Salem","Ojinaga","Panama","Phoenix","Port-au-Prince","Puerto_Rico","Rankin_Inlet","Regina","Resolute","Santo_Domingo","Sitka","St_Johns","Swift_Current","Tegucigalpa","Tijuana","Toronto","Vancouver","Whitehorse","Winnipeg","Yakutat","Yellowknife","Bermuda","Honolulu"],sa:["Araguaina","Argentina/Buenos_Aires","Argentina/Catamarca","Argentina/Cordoba","Argentina/Jujuy","Argentina/La_Rioja","Argentina/Mendoza","Argentina/Rio_Gallegos","Argentina/Salta","Argentina/San_Juan","Argentina/San_Luis","Argentina/Tucuman","Argentina/Ushuaia","Asuncion","Bahia","Belem","Boa_Vista","Bogota","Campo_Grande","Caracas","Cayenne","Cuiaba","Eirunepe","Fortaleza","Guayaquil","Guyana","La_Paz","Lima","Maceio","Manaus","Montevideo","Noronha","Paramaribo","Porto_Velho","Punta_Arenas","Recife","Rio_Branco","Santarem","Santiago","Sao_Paulo","Palmer","South_Georgia","Stanley","Easter","Galapagos"],at:["Cape_Verde","Canary","Faroe","Madeira","Azores","Bermuda","South_Georgia","Stanley"],in:["Mauritius","Maldives","Chagos"],pa:["Palau","Guam","Port_Moresby","Bougainville","Efate","Guadalcanal","Kosrae","Norfolk","Noumea","Auckland","Fiji","Kwajalein","Nauru","Tarawa","Chatham","Apia","Fakaofo","Kanton","Tongatapu","Kiritimati","Pitcairn","Gambier","Marquesas","Rarotonga","Tahiti","Niue","Pago_Pago","Honolulu","Easter","Galapagos"],aq:["Troll","Mawson","Davis","Casey","Rothera","Macquarie","Palmer"],etc:["Greenwich","Universal","Zulu","GMT-14","GMT-13","GMT-12","GMT-11","GMT-10","GMT-9","GMT-8","GMT-7","GMT-6","GMT-5","GMT-4","GMT-3","GMT-2","GMT-1","GMT","GMT+1","GMT+2","GMT+3","GMT+4","GMT+5","GMT+6","GMT+7","GMT+8","GMT+9","GMT+10","GMT+11","GMT+12","UCT","UTC"]};const regions={etc:"Etc",af:"Africa",as:"Asia",au:"Australia",aq:"Antarctica",eu:"Europe",na:"America",sa:"America",at:"Atlantic",in:"Indian",pa:"Pacific"},licenseData=[],licenseApp=[{t:"Petite Vue",y:2021,a:"Yuxi (Evan) You",l:"mit"},{t:"Petite Vue I18n Lite",y:2021,a:"Front Labs",l:"mit"},{t:"Ace Editor",y:2010,a:"Ajax.org B.V.",r:1,l:"bsd"},{t:"MaterialDesign Icons",y:2022,a:"Google",l:"apache2"}];function Credits(a){return{$template:"#credit-template",model:a}}function RegionItem(a,o,e){return{$template:"#region-template",model:a,region:o,i18n:e,list(e){if(a[e]&&o[e]){for(var n="etc"===e?a[e]:a[e].sort(),t=[],i=0;ie.t(a).toString().replace(/_/g," ")}}fetch("/static/en.json?COMMIT_HASH").then((a=>a.json())).then((a=>{const o=reactive(createI18n({locale:"en",fallbackLocale:"en",messages:{en:a.en}}));createApp({i18n:o,languages:languages,RegionItem:RegionItem,regions:regions,locations:locations,licenseData:licenseData,licenseApp:licenseApp,Credits:Credits,hostname:null,title:null,config:{hasp:null,wifi:null,mqtt:null,http:null,gui:null,gpio:null,debug:null,time:null,ota:null},info:null,files:null,show:null,t(a){return this.i18n.t(a)},fetchConfig(a){fetch("/api/config/"+a+"/").then((a=>a.json())).then((o=>{this.config[a]=o,this.show=a,document.title=a}))},submitConfig(){let a=this.show;fetch("/api/config/"+a+"/",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(this.config[a])}).then((a=>a.json())).then((o=>{this.config[a]=o,window.history.pushState({},"","/config/"),window.dispatchEvent(new Event("popstate"))}))},submitOldConfig(a){fetch("/api/config/"+a+"/",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(this.config[a])}).then((a=>a.json())).then((a=>{window.location.href="/config"}))},fetchLang(a){fetch("/static/"+a+".json?COMMIT_HASH").then((a=>a.json())).then((o=>{let e=o[a]?o[a]:{};this.i18n.setLocaleMessage(a,e),this.i18n.changeLocale(a),console.log(a)}))},fetchInfo(){fetch("/api/info/").then((a=>a.json())).then((a=>{this.info=a,this.show="info",document.title="Info"}))},fetchAbout(){fetch("/api/credits/").then((a=>a.json())).then((a=>{this.licenseData=a,this.show="about",document.title="About"}))},showPage(a){console.log("showPage "+a),this.show=a,document.title=a,""!=a&&(a+="/")},showInfo(){console.log("showInfo"),this.fetchInfo(),document.title="Info"},showConfig(a){console.log("showConfig "+a),this.fetchConfig(a),document.title=a},showEditor(){console.log("showEditor"),fetch("/api/files/").then((a=>a.json())).then((a=>{this.files=a,this.show="edit";var o=document.getElementsByClassName("container__editor")[0];o&&(o.style.display="flex"),document.title="Editor"}))},handleLocation(a,o){const e={"/":()=>{this.showPage("")},"/hasp.htm":()=>{this.showPage("")},"/config/":()=>{this.showPage("config")},"/config/hasp/":()=>{this.showConfig("hasp")},"/config/wifi/":()=>{this.showConfig("wifi")},"/config/http/":()=>{this.showConfig("http")},"/config/mqtt/":()=>{this.showConfig("mqtt")},"/config/gui/":()=>{this.showConfig("gui")},"/config/ftp/":()=>{this.showConfig("ftp")},"/config/time/":()=>{this.showConfig("time")},"/config/debug/":()=>{this.showConfig("debug")},"/config/reset/":()=>{this.showPage("reset")},"/firmware/":()=>{this.showConfig("ota")},"/info/":()=>{this.showInfo()},"/screenshot/":()=>{this.showPage("screenshot")},"/about/":()=>{this.fetchAbout()},"/edit/":()=>{this.showEditor()},"/edit":()=>{},"/static/editor.htm":()=>{},"/reboot/":()=>{this.showPage("reboot")}};"function"==typeof e[a]?(console.log("Location: "+a),e[a]()):"/"!==a.slice(-1)&&"function"==typeof e[a+"/"]?(console.log("Location: "+a),e[a+"/"]()):(console.log("Not found: "+a),e["/"]);const n=document.getElementsByClassName("container__editor")[0];n&&(n.style.display=a.includes("/edit")?"flex":"none"),window.scrollTo({top:o})},mounted(){let a=decodeURIComponent(document.cookie).split(";");for(let o=0;o{const o=window.location.pathname;console.log("Popstate: "+o),console.log(a);var e=a.state,n=0;e&&(n=e.scrollTop),this.handleLocation(o,n)};const o=window.location.pathname;this.handleLocation(o,0),console.log("App Mounted")},route(a){console.log("Routing..."),a=a||window.event,console.log(a.target),a.preventDefault();const o=a.currentTarget.href||a.target.parentNode.href,e=new URL(o).pathname;if(window.location.pathname!=e){console.log("Push Route: "+e);var n={path:window.location.href||a.target.href,scrollTop:document.body.scrollTop};window.history.replaceState(n,"",document.location.pathname),n={path:window.location.href,scrollTop:0},window.history.pushState(n,"",e),window.dispatchEvent(new Event("popstate"))}},goto(a){if(console.log("Goto..."),window.location.pathname!=a){console.log("Push Route: "+a);var o={path:window.location.href,scrollTop:document.body.scrollTop};window.history.replaceState(o,"",document.location.pathname),o={path:window.location.href,scrollTop:0},window.history.pushState(o,"",a),window.dispatchEvent(new Event("popstate"))}},ref(a){},aref(a){setTimeout((function(){}),1e3*a)},upd(a){var o=(new Date).getTime();document.getElementById("bmp").src="/screenshot?a="+a+"&q="+o}}).directive("t",(({el:a,get:e,effect:n})=>n((()=>a.textContent=o.t(e()))))).directive("ts",(({el:a,get:e,effect:n})=>n((()=>a.textContent=o.t(e()).replace(/_/g," "))))).mount(),console.log("JS Loaded...")}));
\ No newline at end of file
+import{createApp,reactive,createI18n}from"/static/petite-vue.hasp.js?COMMIT_HASH";const languages=[{code:"en",name:"English"},{code:"nl",name:"Nederlands"},{code:"fr",name:"Français"}];var locations={af:["Abidjan","Algiers","Bissau","Cairo","Casablanca","El_Aaiun","Johannesburg","Juba","Khartoum","Lagos","Maputo","Monrovia","Nairobi","Ndjamena","Sao_Tome","Tripoli","Tunis","Windhoek","Cape_Verde","Mauritius"],eu:["Ceuta","Danmarkshavn","Nuuk","Scoresbysund","Thule","Anadyr","Barnaul","Chita","Irkutsk","Kamchatka","Khandyga","Krasnoyarsk","Magadan","Novokuznetsk","Novosibirsk","Omsk","Sakhalin","Srednekolymsk","Tomsk","Ust-Nera","Vladivostok","Yakutsk","Yekaterinburg","Azores","Canary","Faroe","Madeira","Andorra","Astrakhan","Athens","Belgrade","Berlin","Brussels","Bucharest","Budapest","Chisinau","Dublin","Gibraltar","Helsinki","Istanbul","Kaliningrad","Kirov","Kyiv","Lisbon","London","Madrid","Malta","Minsk","Moscow","Paris","Prague","Riga","Rome","Samara","Saratov","Sofia","Tallinn","Tirane","Ulyanovsk","Vienna","Vilnius","Volgograd","Warsaw","Zurich"],as:["Almaty","Amman","Aqtau","Aqtobe","Ashgabat","Atyrau","Baghdad","Baku","Bangkok","Beirut","Bishkek","Choibalsan","Colombo","Damascus","Dhaka","Dili","Dubai","Dushanbe","Famagusta","Gaza","Hebron","Ho_Chi_Minh","Hong_Kong","Hovd","Jakarta","Jayapura","Jerusalem","Kabul","Karachi","Kathmandu","Kolkata","Kuching","Macau","Makassar","Manila","Nicosia","Oral","Pontianak","Pyongyang","Qatar","Qostanay","Qyzylorda","Riyadh","Samarkand","Seoul","Shanghai","Singapore","Taipei","Tashkent","Tbilisi","Tehran","Thimphu","Tokyo","Ulaanbaatar","Urumqi","Yangon","Yerevan","Chagos","Maldives"],au:["Perth","Eucla","Adelaide","Broken_Hill","Darwin","Brisbane","Hobart","Lindeman","Melbourne","Sydney","Lord_Howe"],na:["Adak","Anchorage","Bahia_Banderas","Barbados","Belize","Boise","Cambridge_Bay","Cancun","Chicago","Chihuahua","Ciudad_Juarez","Costa_Rica","Dawson","Dawson_Creek","Denver","Detroit","Edmonton","El_Salvador","Fort_Nelson","Glace_Bay","Goose_Bay","Grand_Turk","Guatemala","Halifax","Havana","Hermosillo","Indiana/Indianapolis","Indiana/Knox","Indiana/Marengo","Indiana/Petersburg","Indiana/Tell_City","Indiana/Vevay","Indiana/Vincennes","Indiana/Winamac","Inuvik","Iqaluit","Jamaica","Juneau","Kentucky/Louisville","Kentucky/Monticello","Los_Angeles","Managua","Martinique","Matamoros","Mazatlan","Menominee","Merida","Metlakatla","Mexico_City","Miquelon","Moncton","Monterrey","New_York","Nome","North_Dakota/Beulah","North_Dakota/Center","North_Dakota/New_Salem","Ojinaga","Panama","Phoenix","Port-au-Prince","Puerto_Rico","Rankin_Inlet","Regina","Resolute","Santo_Domingo","Sitka","St_Johns","Swift_Current","Tegucigalpa","Tijuana","Toronto","Vancouver","Whitehorse","Winnipeg","Yakutat","Yellowknife","Bermuda","Honolulu"],sa:["Araguaina","Argentina/Buenos_Aires","Argentina/Catamarca","Argentina/Cordoba","Argentina/Jujuy","Argentina/La_Rioja","Argentina/Mendoza","Argentina/Rio_Gallegos","Argentina/Salta","Argentina/San_Juan","Argentina/San_Luis","Argentina/Tucuman","Argentina/Ushuaia","Asuncion","Bahia","Belem","Boa_Vista","Bogota","Campo_Grande","Caracas","Cayenne","Cuiaba","Eirunepe","Fortaleza","Guayaquil","Guyana","La_Paz","Lima","Maceio","Manaus","Montevideo","Noronha","Paramaribo","Porto_Velho","Punta_Arenas","Recife","Rio_Branco","Santarem","Santiago","Sao_Paulo","Palmer","South_Georgia","Stanley","Easter","Galapagos"],at:["Cape_Verde","Canary","Faroe","Madeira","Azores","Bermuda","South_Georgia","Stanley"],in:["Mauritius","Maldives","Chagos"],pa:["Palau","Guam","Port_Moresby","Bougainville","Efate","Guadalcanal","Kosrae","Norfolk","Noumea","Auckland","Fiji","Kwajalein","Nauru","Tarawa","Chatham","Apia","Fakaofo","Kanton","Tongatapu","Kiritimati","Pitcairn","Gambier","Marquesas","Rarotonga","Tahiti","Niue","Pago_Pago","Honolulu","Easter","Galapagos"],aq:["Troll","Mawson","Davis","Casey","Rothera","Macquarie","Palmer"],etc:["Greenwich","Universal","Zulu","GMT-14","GMT-13","GMT-12","GMT-11","GMT-10","GMT-9","GMT-8","GMT-7","GMT-6","GMT-5","GMT-4","GMT-3","GMT-2","GMT-1","GMT","GMT+1","GMT+2","GMT+3","GMT+4","GMT+5","GMT+6","GMT+7","GMT+8","GMT+9","GMT+10","GMT+11","GMT+12","UCT","UTC"]};const regions={etc:"Etc",af:"Africa",as:"Asia",au:"Australia",aq:"Antarctica",eu:"Europe",na:"America",sa:"America",at:"Atlantic",in:"Indian",pa:"Pacific"},licenseData=[],licenseApp=[{t:"Petite Vue",y:2021,a:"Yuxi (Evan) You",l:"mit"},{t:"Petite Vue I18n Lite",y:2021,a:"Front Labs",l:"mit"},{t:"Ace Editor",y:2010,a:"Ajax.org B.V.",r:1,l:"bsd"},{t:"MaterialDesign Icons",y:2022,a:"Google",l:"apache2"}];function Credits(a){return{$template:"#credit-template",model:a}}function RegionItem(a,o,e){return{$template:"#region-template",model:a,region:o,i18n:e,list(e){if(a[e]&&o[e]){for(var n="etc"===e?a[e]:a[e].sort(),t=[],i=0;ie.t(a).toString().replace(/_/g," ")}}fetch("/static/en.json?COMMIT_HASH").then((a=>a.json())).then((a=>{const o=reactive(createI18n({locale:"en",fallbackLocale:"en",messages:{en:a.en}}));createApp({i18n:o,languages:languages,RegionItem:RegionItem,regions:regions,locations:locations,licenseData:licenseData,licenseApp:licenseApp,Credits:Credits,hostname:null,title:null,config:{hasp:null,wifi:null,wg:null,mqtt:null,http:null,gui:null,gpio:null,debug:null,time:null,ota:null},info:null,files:null,show:null,t(a){return this.i18n.t(a)},fetchConfig(a){fetch("/api/config/"+a+"/").then((a=>a.json())).then((o=>{this.config[a]=o,this.show=a,document.title=a}))},submitConfig(){let a=this.show;fetch("/api/config/"+a+"/",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(this.config[a])}).then((a=>a.json())).then((o=>{this.config[a]=o,window.history.pushState({},"","/config/"),window.dispatchEvent(new Event("popstate"))}))},submitOldConfig(a){fetch("/api/config/"+a+"/",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(this.config[a])}).then((a=>a.json())).then((a=>{window.location.href="/config"}))},fetchLang(a){fetch("/static/"+a+".json?COMMIT_HASH").then((a=>a.json())).then((o=>{let e=o[a]?o[a]:{};this.i18n.setLocaleMessage(a,e),this.i18n.changeLocale(a),console.log(a)}))},fetchInfo(){fetch("/api/info/").then((a=>a.json())).then((a=>{this.info=a,this.show="info",document.title="Info"}))},fetchAbout(){fetch("/api/credits/").then((a=>a.json())).then((a=>{this.licenseData=a,this.show="about",document.title="About"}))},showPage(a){console.log("showPage "+a),this.show=a,document.title=a,""!=a&&(a+="/")},showInfo(){console.log("showInfo"),this.fetchInfo(),document.title="Info"},showConfig(a){console.log("showConfig "+a),this.fetchConfig(a),document.title=a},showEditor(){console.log("showEditor"),fetch("/api/files/").then((a=>a.json())).then((a=>{this.files=a,this.show="edit";var o=document.getElementsByClassName("container__editor")[0];o&&(o.style.display="flex"),document.title="Editor"}))},handleLocation(a,o){const e={"/":()=>{this.showPage("")},"/hasp.htm":()=>{this.showPage("")},"/config/":()=>{this.showPage("config")},"/config/hasp/":()=>{this.showConfig("hasp")},"/config/wifi/":()=>{this.showConfig("wifi")},"/config/wg/":()=>{this.showConfig("wg")},"/config/http/":()=>{this.showConfig("http")},"/config/mqtt/":()=>{this.showConfig("mqtt")},"/config/gui/":()=>{this.showConfig("gui")},"/config/ftp/":()=>{this.showConfig("ftp")},"/config/time/":()=>{this.showConfig("time")},"/config/debug/":()=>{this.showConfig("debug")},"/config/reset/":()=>{this.showPage("reset")},"/firmware/":()=>{this.showConfig("ota")},"/info/":()=>{this.showInfo()},"/screenshot/":()=>{this.showPage("screenshot")},"/about/":()=>{this.fetchAbout()},"/edit/":()=>{this.showEditor()},"/edit":()=>{},"/static/editor.htm":()=>{},"/reboot/":()=>{this.showPage("reboot")}};"function"==typeof e[a]?(console.log("Location: "+a),e[a]()):"/"!==a.slice(-1)&&"function"==typeof e[a+"/"]?(console.log("Location: "+a),e[a+"/"]()):(console.log("Not found: "+a),e["/"]);const n=document.getElementsByClassName("container__editor")[0];n&&(n.style.display=a.includes("/edit")?"flex":"none"),window.scrollTo({top:o})},mounted(){let a=decodeURIComponent(document.cookie).split(";");for(let o=0;o{const o=window.location.pathname;console.log("Popstate: "+o),console.log(a);var e=a.state,n=0;e&&(n=e.scrollTop),this.handleLocation(o,n)};const o=window.location.pathname;this.handleLocation(o,0),console.log("App Mounted")},route(a){console.log("Routing..."),a=a||window.event,console.log(a.target),a.preventDefault();const o=a.currentTarget.href||a.target.parentNode.href,e=new URL(o).pathname;if(window.location.pathname!=e){console.log("Push Route: "+e);var n={path:window.location.href||a.target.href,scrollTop:document.body.scrollTop};window.history.replaceState(n,"",document.location.pathname),n={path:window.location.href,scrollTop:0},window.history.pushState(n,"",e),window.dispatchEvent(new Event("popstate"))}},goto(a){if(console.log("Goto..."),window.location.pathname!=a){console.log("Push Route: "+a);var o={path:window.location.href,scrollTop:document.body.scrollTop};window.history.replaceState(o,"",document.location.pathname),o={path:window.location.href,scrollTop:0},window.history.pushState(o,"",a),window.dispatchEvent(new Event("popstate"))}},ref(a){},aref(a){setTimeout((function(){}),1e3*a)},upd(a){var o=(new Date).getTime();document.getElementById("bmp").src="/screenshot?a="+a+"&q="+o}}).directive("t",(({el:a,get:e,effect:n})=>n((()=>a.textContent=o.t(e()))))).directive("ts",(({el:a,get:e,effect:n})=>n((()=>a.textContent=o.t(e()).replace(/_/g," "))))).mount(),console.log("JS Loaded...")}));
\ No newline at end of file
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index 16a4ab23..448b66a3 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -65,6 +65,10 @@
#define HASP_USE_MQTT (HASP_HAS_NETWORK)
#endif
+#ifndef HASP_USE_WIREGUARD
+#define HASP_USE_WIREGUARD (HASP_HAS_NETWORK)
+#endif
+
#ifndef HASP_USE_BROADCAST
#define HASP_USE_BROADCAST 1
#endif
@@ -232,6 +236,10 @@ static WiFiSpiClass WiFi;
#endif
#endif // HASP_USE_WIFI
+#if HASP_USE_WIREGUARD > 0
+#include "sys/net/hasp_wireguard.h"
+#endif
+
#if HASP_USE_ETHERNET > 0
#if defined(ARDUINO_ARCH_ESP32)
#include "sys/net/hasp_ethernet_esp32.h"
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index acbc9734..38548264 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -503,6 +503,14 @@ void dispatch_config(const char* topic, const char* payload, uint8_t source)
else
timeGetConfig(settings);
}
+#if HASP_USE_WIREGUARD > 0
+ else if(strcasecmp_P(topic, PSTR(FP_WG)) == 0) {
+ if(update)
+ wgSetConfig(settings);
+ else
+ wgGetConfig(settings);
+ }
+#endif
#if HASP_USE_MQTT > 0
else if(strcasecmp_P(topic, PSTR(FP_MQTT)) == 0) {
if(update)
diff --git a/src/hasp/hasp_nvs.cpp b/src/hasp/hasp_nvs.cpp
index 439a1bea..a2fd0b23 100644
--- a/src/hasp/hasp_nvs.cpp
+++ b/src/hasp/hasp_nvs.cpp
@@ -6,6 +6,8 @@
#include "hasplib.h"
#include "hasp_nvs.h"
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
bool nvs_user_begin(Preferences& preferences, const char* key, bool readonly)
{
if(preferences.begin(key, false, "config")) {
@@ -22,16 +24,16 @@ bool nvs_user_begin(Preferences& preferences, const char* key, bool readonly)
bool nvs_clear_user_config()
{
- const char* name[] = {FP_TIME, FP_OTA, FP_HTTP, FP_FTP, FP_MQTT, FP_WIFI};
+ const char* name[] = {FP_TIME, FP_OTA, FP_HTTP, FP_FTP, FP_MQTT, FP_WIFI, FP_WG};
Preferences preferences;
bool state = true;
- for(int i = 0; i < sizeof(name) / sizeof(name[0]); i++) {
+ for(int i = 0; i < ARRAY_SIZE(name); i++) {
if(preferences.begin(name[i], false) && !preferences.clear()) state = false;
preferences.end();
}
- for(int i = 0; i < sizeof(name) / sizeof(name[0]); i++) {
+ for(int i = 0; i < ARRAY_SIZE(name); i++) {
if(preferences.begin(name[i], false, "config") && !preferences.clear()) state = false;
preferences.end();
}
@@ -226,19 +228,30 @@ void nvs_setup()
nvs_stats.free_entries, nvs_stats.total_entries);
{ // TODO: remove migratrion of keys from default NVS partition to CONFIG partition
- const char* name[8] = {FP_TIME, FP_OTA, FP_HTTP, FP_FTP, FP_MQTT, FP_WIFI};
+ const struct {
+ const char* name;
+ const char* config;
+ } sec[] = {
+ { .name = FP_TIME, .config = FP_CONFIG_PASS },
+ { .name = FP_OTA, .config = FP_CONFIG_PASS },
+ { .name = FP_HTTP, .config = FP_CONFIG_PASS },
+ { .name = FP_FTP, .config = FP_CONFIG_PASS },
+ { .name = FP_MQTT, .config = FP_CONFIG_PASS },
+ { .name = FP_WIFI, .config = FP_CONFIG_PASS },
+ { .name = FP_WG, .config = FP_CONFIG_PRIVATE_KEY }
+ };
Preferences oldPrefs, newPrefs;
- for(int i = 0; i < 6; i++) {
- if(oldPrefs.begin(name[i], false) && newPrefs.begin(name[i], false, "config")) {
- LOG_INFO(TAG_NVS, "opened %s", name[i]);
- String password = oldPrefs.getString(FP_CONFIG_PASS, D_PASSWORD_MASK);
+ for(int i = 0; i < ARRAY_SIZE(sec); i++) {
+ if(oldPrefs.begin(sec[i].name, false) && newPrefs.begin(sec[i].name, false, "config")) {
+ LOG_INFO(TAG_NVS, "opened %s", sec[i].name);
+ String password = oldPrefs.getString(sec[i].config, D_PASSWORD_MASK);
if(password != D_PASSWORD_MASK) {
- LOG_INFO(TAG_NVS, "found %s %s => %s", name[i], D_PASSWORD_MASK, password.c_str());
- size_t len = newPrefs.putString(FP_CONFIG_PASS, password);
+ LOG_INFO(TAG_NVS, "found %s %s => %s", sec[i].name, D_PASSWORD_MASK, password.c_str());
+ size_t len = newPrefs.putString(sec[i].config, password);
if(len == password.length()) {
- oldPrefs.remove(FP_CONFIG_PASS);
- LOG_INFO(TAG_NVS, "Moved %s key %s to new NVS partition", name[i], FP_CONFIG_PASS);
+ oldPrefs.remove(sec[i].config);
+ LOG_INFO(TAG_NVS, "Moved %s key %s to new NVS partition", sec[i].name, sec[i].config);
}
}
}
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index 9e3f5ce5..09ceea05 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -117,6 +117,19 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const __FlashStrin
}
return false;
}
+bool configSet(char *value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name)
+{
+ if(!setting.isNull()) {
+ const char *val = setting;
+ if(strcmp(value, val) != 0) {
+ confDebugSet(fstr_name);
+ strncpy(value, val, size - 1);
+ value[size - 1] = '\0';
+ return true;
+ }
+ }
+ return false;
+}
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name)
{
@@ -198,28 +211,30 @@ void configSetupDebug(JsonDocument& settings)
debugStart(); // Debug started, now we can use it; HASP header sent
}
-void configStorePasswords(JsonDocument& settings, String& wifiPass, String& mqttPass, String& httpPass)
+void configStorePasswords(JsonDocument& settings, String& wifiPass, String& mqttPass, String& httpPass, String &wgPrivKey)
{
const char* pass = ("pass");
wifiPass = settings[FPSTR(FP_WIFI)][pass].as();
mqttPass = settings[FPSTR(FP_MQTT)][pass].as();
httpPass = settings[FPSTR(FP_HTTP)][pass].as();
+ wgPrivKey = settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].as();
}
-void configRestorePasswords(JsonDocument& settings, String& wifiPass, String& mqttPass, String& httpPass)
+void configRestorePasswords(JsonDocument& settings, String& wifiPass, String& mqttPass, String& httpPass, String& wgPrivKey)
{
const char* pass = ("pass");
if(!settings[FPSTR(FP_WIFI)][pass].isNull()) settings[FPSTR(FP_WIFI)][pass] = wifiPass;
if(!settings[FPSTR(FP_MQTT)][pass].isNull()) settings[FPSTR(FP_MQTT)][pass] = mqttPass;
if(!settings[FPSTR(FP_HTTP)][pass].isNull()) settings[FPSTR(FP_HTTP)][pass] = httpPass;
+ if(!settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull()) settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)] = wgPrivKey;
}
void configMaskPasswords(JsonDocument& settings)
{
String passmask = F(D_PASSWORD_MASK);
- configRestorePasswords(settings, passmask, passmask, passmask);
+ configRestorePasswords(settings, passmask, passmask, passmask, passmask);
}
DeserializationError configParseFile(String& configFile, JsonDocument& settings)
@@ -254,7 +269,7 @@ DeserializationError configRead(JsonDocument& settings, bool setupdebug)
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
error = configParseFile(configFile, settings);
if(!error) {
- String output, wifiPass, mqttPass, httpPass;
+ String output, wifiPass, mqttPass, httpPass, wgPrivKey;
/* Load Debug params */
if(setupdebug) {
@@ -266,14 +281,14 @@ DeserializationError configRead(JsonDocument& settings, bool setupdebug)
}
LOG_TRACE(TAG_CONF, F(D_FILE_LOADING), configFile.c_str());
- configStorePasswords(settings, wifiPass, mqttPass, httpPass);
+ configStorePasswords(settings, wifiPass, mqttPass, httpPass, wgPrivKey);
// Output settings in log with masked passwords
configMaskPasswords(settings);
serializeJson(settings, output);
LOG_VERBOSE(TAG_CONF, output.c_str());
- configRestorePasswords(settings, wifiPass, mqttPass, httpPass);
+ configRestorePasswords(settings, wifiPass, mqttPass, httpPass, wgPrivKey);
LOG_INFO(TAG_CONF, F(D_FILE_LOADED), configFile.c_str());
// if(setupdebug) debugSetup();
@@ -382,6 +397,17 @@ void configWrite()
}
#endif
+#if HASP_USE_WIREGUARD > 0
+ module = FPSTR(FP_WG);
+ if(settings[module].as().isNull()) settings.createNestedObject(module);
+ changed = wgGetConfig(settings[module]);
+ if(changed) {
+ LOG_VERBOSE(TAG_WG, settingsChanged.c_str());
+ configOutput(settings[module], TAG_WG);
+ writefile = true;
+ }
+#endif
+
#if HASP_USE_MQTT > 0
module = FPSTR(FP_MQTT);
if(settings[module].as().isNull()) settings.createNestedObject(module);
@@ -549,6 +575,11 @@ void configSetup()
wifiSetConfig(settings[FPSTR(FP_WIFI)]);
#endif
+#if HASP_USE_WIREGUARD > 0
+ LOG_INFO(TAG_WG, F("Loading WireGuard settings"));
+ wgSetConfig(settings[FPSTR(FP_WG)]);
+#endif
+
#if HASP_USE_MQTT > 0
LOG_INFO(TAG_MQTT, F("Loading MQTT settings"));
mqttSetConfig(settings[FPSTR(FP_MQTT)]);
@@ -624,6 +655,14 @@ void configOutput(const JsonObject& settings, uint8_t tag)
output.replace(password, passmask);
}
+ if(!settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull()) {
+ password = F("\"privkey\":\"");
+ password += settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].as();
+ password += F("\"");
+ passmask = F("\"privkey\":\"" D_PASSWORD_MASK "\"");
+ output.replace(password, passmask);
+ }
+
LOG_VERBOSE(tag, output.c_str());
}
diff --git a/src/hasp_config.h b/src/hasp_config.h
index df547408..7effe4cd 100644
--- a/src/hasp_config.h
+++ b/src/hasp_config.h
@@ -31,6 +31,7 @@ bool configSet(uint8_t& value, const JsonVariant& setting, const __FlashStringHe
bool configSet(uint16_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(int32_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(lv_color_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
+bool configSet(char *value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name);
bool configSet(int8_t& value, const JsonVariant& setting, const char* fstr_name);
bool configSet(uint8_t& value, const JsonVariant& setting, const char* fstr_name);
@@ -71,6 +72,9 @@ const char FP_CONFIG_BROADCAST_TOPIC[] PROGMEM = "broadcast_t";
const char FP_CONFIG_BAUD[] PROGMEM = "baud";
const char FP_CONFIG_LOG[] PROGMEM = "log";
const char FP_CONFIG_PROTOCOL[] PROGMEM = "proto";
+const char FP_CONFIG_VPN_IP[] PROGMEM = "vpnip";
+const char FP_CONFIG_PRIVATE_KEY[] PROGMEM = "privkey";
+const char FP_CONFIG_PUBLIC_KEY[] PROGMEM = "pubkey";
const char FP_GUI_ROTATION[] PROGMEM = "rotate";
const char FP_GUI_INVERT[] PROGMEM = "invert";
const char FP_GUI_TICKPERIOD[] PROGMEM = "tick";
@@ -89,6 +93,7 @@ const char FP_GPIO_CONFIG[] PROGMEM = "config";
const char FP_HASP_CONFIG_FILE[] PROGMEM = "/config.json";
const char FP_WIFI[] PROGMEM = "wifi";
+const char FP_WG[] PROGMEM = "wg";
const char FP_MQTT[] PROGMEM = "mqtt";
const char FP_HTTP[] PROGMEM = "http";
const char FP_FTP[] PROGMEM = "ftp";
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index df523c19..52977625 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -321,6 +321,10 @@ void debug_get_tag(uint8_t tag, char* buffer)
memcpy_P(buffer, PSTR("CUST"), 5);
break;
+ case TAG_WG:
+ memcpy_P(buffer, PSTR("WG "), 5);
+ break;
+
default:
memcpy_P(buffer, PSTR("----"), 5);
break;
diff --git a/src/hasp_debug.h b/src/hasp_debug.h
index b805004e..425a7d97 100644
--- a/src/hasp_debug.h
+++ b/src/hasp_debug.h
@@ -194,6 +194,7 @@ enum {
TAG_FTP = 68,
TAG_TIME = 69,
TAG_NETW = 70,
+ TAG_WG = 71,
TAG_LVGL = 90,
TAG_LVFS = 91,
diff --git a/src/lang/en_US.h b/src/lang/en_US.h
index b24d806d..13df8dbc 100644
--- a/src/lang/en_US.h
+++ b/src/lang/en_US.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
#define D_HTTP_FTP_SETTINGS "FTP Settings"
#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Failed"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "MAC Address"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Weak"
#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Push Button"
#define D_GPIO_TOUCH "Capacitive Touch"
diff --git a/src/sys/net/hasp_network.cpp b/src/sys/net/hasp_network.cpp
index 5b20ad4a..395f3a2f 100644
--- a/src/sys/net/hasp_network.cpp
+++ b/src/sys/net/hasp_network.cpp
@@ -14,6 +14,11 @@ uint16_t network_reconnect_counter = 0;
#if HASP_USE_ETHERNET > 0 || HASP_USE_WIFI > 0
+bool network_is_connected()
+{
+ return current_network_state;
+}
+
void network_disconnected()
{
@@ -23,6 +28,9 @@ void network_disconnected()
// if(!current_network_state) return; // we were not connected
current_network_state = false; // now we are disconnected
+#if HASP_USE_WIREGUARD
+ wg_network_disconnected();
+#endif
network_reconnect_counter++;
// LOG_VERBOSE(TAG_NETW, F("Connected = %s"),
// WiFi.status() == WL_CONNECTED ? PSTR(D_NETWORK_ONLINE) : PSTR(D_NETWORK_OFFLINE));
@@ -32,10 +40,15 @@ void network_connected()
{
if(current_network_state) return; // already connected
+#if HASP_USE_WIREGUARD
+ wg_network_connected();
+#endif
+
current_network_state = true; // now we are connected
network_reconnect_counter = 0;
LOG_VERBOSE(TAG_NETW, F("Connected = %s"),
WiFi.status() == WL_CONNECTED ? PSTR(D_NETWORK_ONLINE) : PSTR(D_NETWORK_OFFLINE));
+
}
void network_run_scripts()
@@ -101,6 +114,10 @@ void networkSetup()
#if HASP_USE_WIFI > 0
wifiSetup();
#endif
+
+#if HASP_USE_WIREGUARD > 0
+ wg_setup();
+#endif
}
IRAM_ATTR void networkLoop(void)
@@ -178,10 +195,20 @@ void network_get_statusupdate(char* buffer, size_t len)
#if HASP_USE_WIFI > 0
wifi_get_statusupdate(buffer, len);
#endif
+
+#if HASP_USE_WIREGUARD > 0
+ size_t l = strlen(buffer);
+ wg_get_statusupdate(buffer + l, len - l);
+#endif
}
void network_get_ipaddress(char* buffer, size_t len)
{
+#if HASP_USE_WIREGUARD > 0
+ if (wg_get_ipaddress(buffer, len))
+ return;
+#endif
+
#if HASP_USE_ETHERNET > 0
#if defined(ARDUINO_ARCH_ESP32)
#if HASP_USE_ETHSPI > 0
@@ -222,6 +249,10 @@ void network_get_info(JsonDocument& doc)
#if HASP_USE_WIFI > 0
wifi_get_info(doc);
#endif
+
+#if HASP_USE_WIREGUARD > 0
+ wg_get_info(doc);
+#endif
}
#endif
diff --git a/src/sys/net/hasp_network.h b/src/sys/net/hasp_network.h
index 83f9b7b2..47ec456a 100644
--- a/src/sys/net/hasp_network.h
+++ b/src/sys/net/hasp_network.h
@@ -11,6 +11,7 @@ bool networkEvery5Seconds(void);
// bool networkEverySecond(void);
void networkStart(void);
void networkStop(void);
+bool network_is_connected();
/* ===== Special Event Processors ===== */
void network_connected();
diff --git a/src/sys/net/hasp_wireguard.cpp b/src/sys/net/hasp_wireguard.cpp
new file mode 100644
index 00000000..36b05515
--- /dev/null
+++ b/src/sys/net/hasp_wireguard.cpp
@@ -0,0 +1,131 @@
+/* MIT License - Copyright (c) 2023 Jaroslav Kysela
+ For full license information read the LICENSE file in the project folder */
+
+#include "hasplib.h"
+
+#if HASP_USE_WIREGUARD > 0
+
+#include "hal/hasp_hal.h"
+#include "hasp_debug.h"
+#include "hasp_network.h"
+#include "WireGuard-ESP32.h"
+
+char wg_ip[16] = WIREGUARD_IP;
+char wg_private_key[45] = WIREGUARD_PRIVATE_KEY;
+char wg_ep_ip[16] = WIREGUARD_EP_IP;
+uint16_t wg_ep_port = WIREGUARD_EP_PORT;
+char wg_ep_public_key[45] = WIREGUARD_EP_PUBLIC_KEY;
+static WireGuard wg;
+
+void wg_setup()
+{
+ Preferences preferences;
+ nvs_user_begin(preferences, FP_WG, true);
+ String privkey = preferences.getString(FP_CONFIG_PRIVATE_KEY, String(wg_private_key)); // Update from NVS if it exists
+ strncpy(wg_private_key, privkey.c_str(), sizeof(wg_private_key)-1);
+ wg_private_key[sizeof(wg_private_key)-1] = '\0';
+}
+
+int wg_config_valid()
+{
+ return strlen(wg_ip) > 7 && strlen(wg_ep_ip) > 7 &&
+ strlen(wg_private_key) == 44 && strlen(wg_ep_public_key) == 44 &&
+ wg_ep_port > 0;
+}
+
+void wg_network_disconnected()
+{
+ wg.end();
+}
+
+void wg_network_connected()
+{
+ IPAddress local_ip;
+ LOG_VERBOSE(TAG_WG, F("WireGuard connected"));
+ if (local_ip.fromString(wg_ip) && wg_config_valid()) {
+ LOG_INFO(TAG_WG, F("WireGuard begin (%s -> %s:%u)"), wg_ip, wg_ep_ip, wg_ep_port);
+ wg.begin(local_ip, wg_private_key, wg_ep_ip, wg_ep_public_key, wg_ep_port);
+ }
+}
+
+void wg_get_statusupdate(char* buffer, size_t len)
+{
+ snprintf_P(buffer, len, PSTR("\"wg\":\"%s\","), wg.is_initialized() ? "on" : "off");
+}
+
+int wg_get_ipaddress(char* buffer, size_t len)
+{
+ if (wg.is_initialized()) {
+ snprintf(buffer, len, "%s", wg_ip);
+ return 1;
+ }
+ return 0;
+}
+
+void wg_get_info(JsonDocument& doc)
+{
+ JsonObject info = doc.createNestedObject(F(D_INFO_WIREGUARD));
+ info[F(D_INFO_STATUS)] = wg.is_initialized() ? F(D_WG_INITIALIZED) : F(D_WG_BAD_CONFIG);
+ info[F(D_INFO_IP_ADDRESS)] = String(wg_ip);
+ info[F(D_INFO_ENDPOINT_IP)] = String(wg_ep_ip);
+ info[F(D_INFO_ENDPOINT_PORT)] = String(wg_ep_port);
+}
+
+#if HASP_USE_CONFIG > 0
+bool wgGetConfig(const JsonObject& settings)
+{
+ bool changed = false;
+
+ if(strcmp(wg_ip, settings[FPSTR(FP_CONFIG_VPN_IP)].as().c_str()) != 0) changed = true;
+ settings[FPSTR(FP_CONFIG_VPN_IP)] = wg_ip;
+
+ if(strcmp(wg_private_key, settings[FPSTR(FP_CONFIG_PRIVATE_KEY)].as().c_str()) != 0) changed = true;
+ //settings[FPSTR(FP_CONFIG_PRIVATE_KEY)] = wg_private_key;
+ settings[FPSTR(FP_CONFIG_PRIVATE_KEY)] = D_PASSWORD_MASK;
+
+ if(strcmp(wg_ep_ip, settings[FPSTR(FP_CONFIG_HOST)].as().c_str()) != 0) changed = true;
+ settings[FPSTR(FP_CONFIG_HOST)] = wg_ep_ip;
+
+ if(wg_ep_port != settings[FPSTR(FP_CONFIG_PORT)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_PORT)] = wg_ep_port;
+
+ if(strcmp(wg_ep_public_key, settings[FPSTR(FP_CONFIG_PUBLIC_KEY)].as().c_str()) != 0) changed = true;
+ settings[FPSTR(FP_CONFIG_PUBLIC_KEY)] = wg_ep_public_key;
+
+ if(changed) configOutput(settings, TAG_WG);
+ return changed;
+}
+
+bool wgSetConfig(const JsonObject& settings)
+{
+ Preferences preferences;
+ nvs_user_begin(preferences, "wg", false);
+
+ configOutput(settings, TAG_WG);
+ bool changed = false;
+ bool changed_privkey = false;
+
+ changed |= configSet((char *)wg_ip, sizeof(wg_ip), settings[FPSTR(FP_CONFIG_VPN_IP)], F("wgIp"));
+ if(!settings[FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull() &&
+ settings[FPSTR(FP_CONFIG_PRIVATE_KEY)].as() != String(FPSTR(D_PASSWORD_MASK))) {
+ changed |= strcmp(wg_private_key, settings[FPSTR(FP_CONFIG_PRIVATE_KEY)]) != 0;
+ strncpy(wg_private_key, settings[FPSTR(FP_CONFIG_PRIVATE_KEY)], sizeof(wg_private_key)-1);
+ wg_private_key[sizeof(wg_private_key)-1] = '\0';
+ nvsUpdateString(preferences, FP_CONFIG_PRIVATE_KEY, settings[FPSTR(FP_CONFIG_PRIVATE_KEY)]);
+ }
+ changed |= changed_privkey;
+ changed |= configSet((char *)wg_ep_ip, sizeof(wg_ep_ip), settings[FPSTR(FP_CONFIG_HOST)], F("wgEpIp"));
+ changed |= configSet(wg_ep_port, settings[FPSTR(FP_CONFIG_PORT)], F("wgEpPort"));
+ changed |= configSet((char *)wg_ep_public_key, sizeof(wg_ep_public_key), settings[FPSTR(FP_CONFIG_PUBLIC_KEY)], F("wgEpPubKey"));
+
+ if (changed && network_is_connected()) {
+ wg.end();
+ wg_network_connected();
+ }
+
+ return changed;
+}
+#endif
+
+
+#endif /* WIREGUARD */
diff --git a/src/sys/net/hasp_wireguard.h b/src/sys/net/hasp_wireguard.h
new file mode 100644
index 00000000..486c711e
--- /dev/null
+++ b/src/sys/net/hasp_wireguard.h
@@ -0,0 +1,40 @@
+/* MIT License - Copyright (c) 2023 Jaroslav Kysela
+ For full license information read the LICENSE file in the project folder */
+
+#ifndef HASP_WIREGUARD_H
+#define HASP_WIREGUARD_H
+
+void wg_setup();
+int wg_config_valid();
+void wg_network_disconnected();
+void wg_network_connected();
+void wg_get_statusupdate(char* buffer, size_t len);
+int wg_get_ipaddress(char* buffer, size_t len);
+void wg_get_info(JsonDocument& doc);
+
+#if HASP_USE_CONFIG > 0
+bool wgGetConfig(const JsonObject& settings);
+bool wgSetConfig(const JsonObject& settings);
+#endif
+
+#ifndef WIREGUARD_IP
+#define WIREGUARD_IP ""
+#endif
+
+#ifndef WIREGUARD_PRIVATE_KEY
+#define WIREGUARD_PRIVATE_KEY ""
+#endif
+
+#ifndef WIREGUARD_EP_IP
+#define WIREGUARD_EP_IP ""
+#endif
+
+#ifndef WIREGUARD_EP_PORT
+#define WIREGUARD_EP_PORT 51820
+#endif
+
+#ifndef WIREGUARD_EP_PUBLIC_KEY
+#define WIREGUARD_EP_PUBLIC_KEY ""
+#endif
+
+#endif
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index d9b12158..6139b177 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -408,6 +408,10 @@ bool http_save_config()
#if HASP_USE_WIFI > 0
} else if(save == FP_WIFI) {
updated = wifiSetConfig(settings.as());
+#endif
+#if HASP_USE_WIREGUARD > 0
+ } else if(save == FP_WG) {
+ updated = wgSetConfig(settings.as());
#endif
}
}
@@ -635,6 +639,10 @@ static void webHandleApi()
add_license(obj, "AceButton", "2018", "Brian T. Park", "mit");
obj = doc.createNestedObject();
add_license(obj, "QR Code generator", "", "Project Nayuki", "mit");
+#if HASP_USE_WIREGUARD > 0
+ obj = doc.createNestedObject();
+ add_license(obj, "WireGuard", "2021", "Kenta Ida fugafuga.org, Daniel Hope www.floorsense.nz", "bsd", 1);
+#endif
}
{
char output[HTTP_PAGE_SIZE];
@@ -688,6 +696,11 @@ static void webHandleApi()
settings.createNestedObject(module);
timeGetConfig(settings[module]);
#endif
+#if HASP_USE_WIREGUARD > 0
+ module = FPSTR(FP_WG);
+ settings.createNestedObject(module);
+ wgGetConfig(settings[module]);
+#endif
#if HASP_USE_MQTT > 0
module = FPSTR(FP_MQTT);
settings.createNestedObject(module);
@@ -790,6 +803,11 @@ static void webHandleApiConfig()
timeSetConfig(settings);
} else
#endif
+#if HASP_USE_WIREGUARD > 0
+ if(!strcasecmp(endpoint_key, FP_WG)) {
+ wgSetConfig(settings);
+ } else
+#endif
#if HASP_USE_MQTT > 0
if(!strcasecmp(endpoint_key, FP_MQTT)) {
mqttSetConfig(settings);
@@ -831,6 +849,11 @@ static void webHandleApiConfig()
timeGetConfig(settings);
} else
#endif
+#if HASP_USE_WIREGUARD > 0
+ if(!strcasecmp(endpoint_key, FP_WG)) {
+ wgGetConfig(settings);
+ } else
+#endif
#if HASP_USE_MQTT > 0
if(!strcasecmp(endpoint_key, FP_MQTT)) {
mqttGetConfig(settings);
@@ -937,6 +960,8 @@ static void http_handle_info()
{{ item }}
Wifi
{{ item }}
+WireGuard
+{{ item }}
Module
{{ item }}
)";
@@ -1415,6 +1440,9 @@ static void http_handle_config()
#if HASP_USE_WIFI > 0
html[min(i++, len)] = R"( )";
#endif
+#if HASP_USE_WIREGUARD > 0
+ html[min(i++, len)] = R"( )";
+#endif
#if HASP_USE_MQTT > 0
html[min(i++, len)] = R"( )";
#endif
@@ -2302,6 +2330,50 @@ static void http_handle_wifi()
#endif // HASP_USE_WIFI
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#if HASP_USE_WIREGUARD > 0
+static void http_handle_wireguard()
+{ // http://plate01/config/wireguard
+ if(!http_is_authenticated(F("config/wireguard"))) return;
+
+ const char* html[20];
+ int i = 0;
+ int len = (sizeof(html) / sizeof(html[0])) - 1;
+
+ html[min(i++, len)] = "";
+ html[min(i++, len)] = haspDevice.get_hostname();
+ html[min(i++, len)] = " ";
+ html[min(i++, len)] = R"(
+
+)";
+ html[min(i++, len)] = R"( )";
+ http_send_content(html, min(i, len));
+}
+
+#endif // HASP_USE_WIREGUARD
+
static inline int handleFirmwareFile(String path)
{
String contentType((char*)0);
@@ -2715,6 +2787,9 @@ void httpSetup()
#if HASP_USE_WIFI > 0
webServer.on("/config/wifi", http_handle_wifi);
#endif
+#if HASP_USE_WIREGUARD > 0
+ webServer.on("/config/wireguard", http_handle_wireguard);
+#endif
#if HASP_USE_GPIO > 0
webServer.on("/config/gpio", webHandleGpioConfig);
webServer.on("/config/gpio/options", webHandleGpioOutput);
diff --git a/src/sys/svc/hasp_http_async.cpp b/src/sys/svc/hasp_http_async.cpp
index 9232cf0d..d73f112f 100644
--- a/src/sys/svc/hasp_http_async.cpp
+++ b/src/sys/svc/hasp_http_async.cpp
@@ -1259,7 +1259,7 @@ void webHandleMqttConfig(AsyncWebServerRequest* request)
////////////////////////////////////////////////////////////////////////////////////////////////////
void webHandleGuiConfig(AsyncWebServerRequest* request)
-{ // http://plate01/config/wifi
+{ // http://plate01/config/gui
if(!httpIsAuthenticated(request, F("config/gui"))) return;
{
From 4714f2fe2eb25132594f1e10ecfa39bbf9f94f14 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:48 +0100
Subject: [PATCH 014/135] New translations en.json (Romanian)
---
data/ro_RO.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/ro_RO.json b/data/ro_RO.json
index 6c4269b8..bd92c3b8 100644
--- a/data/ro_RO.json
+++ b/data/ro_RO.json
@@ -85,6 +85,15 @@
"btn": "Setări WiFi",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "Setări MQTT",
"btn": "Setări MQTT",
From 099d75f7e0f460a31500cf59d0453b44c355e9d5 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:49 +0100
Subject: [PATCH 015/135] New translations en_us.h (Romanian)
---
src/lang/ro_RO.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h
index b24d806d..13df8dbc 100644
--- a/src/lang/ro_RO.h
+++ b/src/lang/ro_RO.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
#define D_HTTP_FTP_SETTINGS "FTP Settings"
#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Failed"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "MAC Address"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Weak"
#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Push Button"
#define D_GPIO_TOUCH "Capacitive Touch"
From 10f1ac0c9161947abf52a442c5933d5ade21a99a Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:50 +0100
Subject: [PATCH 016/135] New translations en.json (French)
---
data/fr_FR.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/fr_FR.json b/data/fr_FR.json
index a6deaa8b..7247c2f6 100644
--- a/data/fr_FR.json
+++ b/data/fr_FR.json
@@ -85,6 +85,15 @@
"btn": "Paramètres WiFi",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "Paramètres MQTT",
"btn": "Paramètres MQTT",
From 745b4157141ea9d67579f9735b210223ee9ca13c Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:51 +0100
Subject: [PATCH 017/135] New translations en_us.h (French)
---
src/lang/fr_FR.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h
index aa5748a1..f84d3995 100644
--- a/src/lang/fr_FR.h
+++ b/src/lang/fr_FR.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "Paramètres HTTP"
#define D_HTTP_FTP_SETTINGS "Paramètres FTP"
#define D_HTTP_WIFI_SETTINGS "Paramètres Wifi"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "Paramètres MQTT"
#define D_HTTP_GPIO_SETTINGS "Paramètres GPIO"
#define D_HTTP_MDNS_SETTINGS "Paramètres mDNS"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Échec"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Vitesse de liaison"
#define D_INFO_FULL_DUPLEX "Duplex intégral"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "Adresse MAC"
#define D_INFO_GATEWAY "Passerelle"
#define D_INFO_DNS_SERVER "Serveur DNS"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Touchez l'écran pour configurer le WiFi ou branchez ce point d'accès:"
#define D_OOBE_SCAN_TO_CONNECT "Scanner pour se connecter"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Faible"
#define D_WIFI_RSSI_BAD "Très mauvais"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Interrupteur"
#define D_GPIO_BUTTON "Bouton"
#define D_GPIO_TOUCH "Touche Capacitive"
From a256ae4ca511672c9d4c6a457a1b18410a4fedb5 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:52 +0100
Subject: [PATCH 018/135] New translations en.json (Spanish)
---
data/es_ES.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/es_ES.json b/data/es_ES.json
index ba317b90..fa1292a2 100644
--- a/data/es_ES.json
+++ b/data/es_ES.json
@@ -85,6 +85,15 @@
"btn": "Ajustes Wifi",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "Ajustes MQTT",
"btn": "Ajustes MQTT",
From b2d914f562967dcfc440a234e3ab3b5b678ce239 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:53 +0100
Subject: [PATCH 019/135] New translations en_us.h (Spanish)
---
src/lang/es_ES.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/es_ES.h b/src/lang/es_ES.h
index 45938eb1..613e47ba 100644
--- a/src/lang/es_ES.h
+++ b/src/lang/es_ES.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "Ajustes HTTP"
#define D_HTTP_HTTP_SETTINGS "Ajustes FTP"
#define D_HTTP_WIFI_SETTINGS "Ajustes Wifi"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "Ajustes MQTT"
#define D_HTTP_GPIO_SETTINGS "Ajustes GPIO"
#define D_HTTP_MDNS_SETTINGS "Ajustes mDNS"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Fallado"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Velocidad de enlace"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "Dirección MAC"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "Servidor DNS"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Toque la pantalla para ajustar WiFi o conectarse a un punto de acceso"
#define D_OOBE_SCAN_TO_CONNECT "Scanee para conectar"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Débil"
#define D_WIFI_RSSI_BAD "Muy baka"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Botón"
#define D_GPIO_TOUCH "Capacitive Touch" // new
From 27ccdef806246210696fcb639ac330672ffef8b7 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:54 +0100
Subject: [PATCH 020/135] New translations en.json (Danish)
---
data/da_DK.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/da_DK.json b/data/da_DK.json
index fb67c5d9..6e48f802 100644
--- a/data/da_DK.json
+++ b/data/da_DK.json
@@ -85,6 +85,15 @@
"btn": "WiFi Indstillinger",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "MQTT Indstillinger",
"btn": "MQTT Indstillinger",
From 86c7190660365354b685491617d204f42a219637 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:55 +0100
Subject: [PATCH 021/135] New translations en_us.h (Danish)
---
src/lang/da_DK.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/da_DK.h b/src/lang/da_DK.h
index b24d806d..13df8dbc 100644
--- a/src/lang/da_DK.h
+++ b/src/lang/da_DK.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
#define D_HTTP_FTP_SETTINGS "FTP Settings"
#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Failed"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "MAC Address"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Weak"
#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Push Button"
#define D_GPIO_TOUCH "Capacitive Touch"
From a81a4879ca70c898213f128a9d753e04b527e5ef Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:56 +0100
Subject: [PATCH 022/135] New translations en.json (German)
---
data/de_DE.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/de_DE.json b/data/de_DE.json
index d3f99e9e..0c494a69 100644
--- a/data/de_DE.json
+++ b/data/de_DE.json
@@ -85,6 +85,15 @@
"btn": "WiFi-Einstellungen",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "MQTT-Einstellungen",
"btn": "MQTT-Einstellungen",
From 472a5629a2e11327a2b505304e676025a4a8eb62 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:57 +0100
Subject: [PATCH 023/135] New translations en_us.h (German)
---
src/lang/de_DE.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/de_DE.h b/src/lang/de_DE.h
index b24d806d..13df8dbc 100644
--- a/src/lang/de_DE.h
+++ b/src/lang/de_DE.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
#define D_HTTP_FTP_SETTINGS "FTP Settings"
#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Failed"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "MAC Address"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Weak"
#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Push Button"
#define D_GPIO_TOUCH "Capacitive Touch"
From 646f21e76e227577ba557e4f9cbc734a964b1d4f Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:58 +0100
Subject: [PATCH 024/135] New translations en.json (Hungarian)
---
data/hu_HU.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/hu_HU.json b/data/hu_HU.json
index 7700a9f9..16a2e736 100644
--- a/data/hu_HU.json
+++ b/data/hu_HU.json
@@ -85,6 +85,15 @@
"btn": "WiFi beállÃtások",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "MQTT beállÃtások",
"btn": "MQTT beállÃtások",
From 132a074ea3aec505c59e6427ea334b0594a9cc68 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:54:59 +0100
Subject: [PATCH 025/135] New translations en_us.h (Hungarian)
---
src/lang/hu_HU.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h
index b24d806d..13df8dbc 100644
--- a/src/lang/hu_HU.h
+++ b/src/lang/hu_HU.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
#define D_HTTP_FTP_SETTINGS "FTP Settings"
#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Failed"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "MAC Address"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Weak"
#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Push Button"
#define D_GPIO_TOUCH "Capacitive Touch"
From 9f661511e247af28799f54e9bd26f65ac6ad0c5e Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:00 +0100
Subject: [PATCH 026/135] New translations en.json (Dutch)
---
data/nl_NL.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/nl_NL.json b/data/nl_NL.json
index 918de554..e99c54ed 100644
--- a/data/nl_NL.json
+++ b/data/nl_NL.json
@@ -85,6 +85,15 @@
"btn": "Wifi Instellingen",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "MQTT Instellingen",
"btn": "MQTT Instellingen",
From 9a27448372b9da77736462ab72005785db15932c Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:01 +0100
Subject: [PATCH 027/135] New translations en_us.h (Dutch)
---
src/lang/nl_NL.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h
index cafb4be1..9bec3fbd 100644
--- a/src/lang/nl_NL.h
+++ b/src/lang/nl_NL.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Instellingen"
#define D_HTTP_FTP_SETTINGS "FTP Instellingen"
#define D_HTTP_WIFI_SETTINGS "Wifi Instellingen"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Instellingen"
#define D_HTTP_GPIO_SETTINGS "GPIO Instellingen"
#define D_HTTP_MDNS_SETTINGS "mDNS Instellingen"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Mislukt"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Snelheid"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "Fysiek adres (MAC)"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Raak het scherm aan om WiFi in te stellen of meld je aan op AP:"
#define D_OOBE_SCAN_TO_CONNECT "Scan code"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Zwak"
#define D_WIFI_RSSI_BAD "Zeer Slecht"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Schakelaar"
#define D_GPIO_BUTTON "Drukknop"
#define D_GPIO_TOUCH "Aanraakknop"
From 3bb6b0b56ca0ff00fa4ec035298a8244c59a05e8 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:02 +0100
Subject: [PATCH 028/135] New translations en.json (Portuguese)
---
data/pt_PT.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/pt_PT.json b/data/pt_PT.json
index a92b91a5..64f447e7 100644
--- a/data/pt_PT.json
+++ b/data/pt_PT.json
@@ -85,6 +85,15 @@
"btn": "Configurar Wifi",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "Configurar MQTT",
"btn": "Configurar MQTT",
From d87f0f9eb24a4b7a82a3db980fbbc415bd63ed0a Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:03 +0100
Subject: [PATCH 029/135] New translations en_us.h (Portuguese)
---
src/lang/pt_PT.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h
index 56414b1b..265b26f0 100644
--- a/src/lang/pt_PT.h
+++ b/src/lang/pt_PT.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "Configurar HTTP"
#define D_HTTP_FTP_SETTINGS "Configurar FTP"
#define D_HTTP_WIFI_SETTINGS "Configurar Wifi"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "Configurar MQTT"
#define D_HTTP_GPIO_SETTINGS "Configurar GPIO"
#define D_HTTP_MDNS_SETTINGS "Configurar mDNS"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Em falha"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "Endereço MAC"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "Servidor DNS"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Toque no ecrã para configurar WiFi ou para se ligar a um access point"
#define D_OOBE_SCAN_TO_CONNECT "Procurar rede"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_BAD "Muito baixo"
#define D_WIFI_RSSI_FAIR "Decente"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Interruptor"
#define D_GPIO_BUTTON "Botão"
#define D_GPIO_TOUCH "Capacitive Touch" // new
From a6b660fb931764399f1c720c440b69a34041514d Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:04 +0100
Subject: [PATCH 030/135] New translations en.json (Chinese Simplified)
---
data/zh_CN.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/zh_CN.json b/data/zh_CN.json
index 34d310c4..146e267b 100644
--- a/data/zh_CN.json
+++ b/data/zh_CN.json
@@ -85,6 +85,15 @@
"btn": "Wifi 设置",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "MQTT 设置",
"btn": "MQTT 设置",
From a6ba5fdd7c076153c23f786c3e8b4ed3f213c059 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:05 +0100
Subject: [PATCH 031/135] New translations en_us.h (Chinese Simplified)
---
src/lang/zh_CN.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/zh_CN.h b/src/lang/zh_CN.h
index b24d806d..13df8dbc 100644
--- a/src/lang/zh_CN.h
+++ b/src/lang/zh_CN.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
#define D_HTTP_FTP_SETTINGS "FTP Settings"
#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Failed"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "MAC Address"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Weak"
#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Push Button"
#define D_GPIO_TOUCH "Capacitive Touch"
From b994f41a079fba1fe48555863bf063d5a5a62e60 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:06 +0100
Subject: [PATCH 032/135] New translations en.json (Portuguese, Brazilian)
---
data/pt_BR.json | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/data/pt_BR.json b/data/pt_BR.json
index 458b9ba5..2717d9ae 100644
--- a/data/pt_BR.json
+++ b/data/pt_BR.json
@@ -85,6 +85,15 @@
"btn": "Configurar Wifi",
"ssid": "SSID"
},
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
"mqtt": {
"title": "Configurar MQTT",
"btn": "Configurar MQTT",
From c7b7cd4f6a8e6dc2c4345fa32879e808e740a782 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Fri, 1 Dec 2023 23:55:06 +0100
Subject: [PATCH 033/135] New translations en_us.h (Portuguese, Brazilian)
---
src/lang/pt_BR.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lang/pt_BR.h b/src/lang/pt_BR.h
index 3c765fb9..169e3a8d 100644
--- a/src/lang/pt_BR.h
+++ b/src/lang/pt_BR.h
@@ -127,6 +127,7 @@
#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
#define D_HTTP_FTP_SETTINGS "FTP Settings"
#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
@@ -191,6 +192,7 @@
#define D_INFO_FAILED "Failed"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
#define D_INFO_LINK_SPEED "Link Speed"
#define D_INFO_FULL_DUPLEX "Full Duplex"
#define D_INFO_BSSID "BSSID"
@@ -200,6 +202,8 @@
#define D_INFO_MAC_ADDRESS "MAC Address"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
@@ -212,6 +216,9 @@
#define D_WIFI_RSSI_WEAK "Weak"
#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Push Button"
#define D_GPIO_TOUCH "Capacitive Touch"
From 20830101d28de2ad682579db2ffb692639c0e478 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 2 Dec 2023 22:12:47 +0100
Subject: [PATCH 034/135] Update to Ace JS v1.32.0
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index fd6b9350..2d2eec60 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
+openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index c7b61782..44b532f3 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.31.0")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.0")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 87e25de6175591c8bf2e341ff7c879d70e24db16 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 8 Dec 2023 00:33:21 +0100
Subject: [PATCH 035/135] Update to ArduinoJson 6.21.4
---
CHANGELOG.md | 3 ++-
platformio.ini | 2 +-
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 2 +-
user_setups/linux_sdl/linux_sdl_64bits.ini | 2 +-
user_setups/win32/windows_sdl_64bits.ini | 2 +-
5 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6c213e8..16a22aef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,7 @@
- Add service start/stop ftp
- Add configuration for NTP servers and timezone
- Add support system scripts executed when the idle level is changed
+- Add support for WireGuard (thanks @perexg)
### Devices
- Add Elecrow ESP32-Terminal 3.5" SPI and RGB
@@ -56,7 +57,7 @@
- Add support for ESP32-S3 and ESP32-C3 devices
- Deprecation of support for ESP32-S2 devices due to lack of sRAM
-Updated libraries to ArduinoJson 6.21.3, ArduinoStreamUtils 1.7.3, AceButton 1.10.1, TFT_eSPI 2.5.0, LovyanGFX 1.1.8 and SimpleFTPServer 2.1.5
+Updated libraries to ArduinoJson 6.21.4, ArduinoStreamUtils 1.7.3, AceButton 1.10.1, TFT_eSPI 2.5.0, LovyanGFX 1.1.8 and SimpleFTPServer 2.1.5
## v0.6.3
diff --git a/platformio.ini b/platformio.ini
index 2709870a..c28cea8c 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -82,7 +82,7 @@ build_flags =
; -- Shared library dependencies in all environments
; Warning : don't put comments after github links => causes infinite download loop
lib_deps =
- bblanchon/ArduinoJson@^6.21.3
+ bblanchon/ArduinoJson@^6.21.4
;git+https://github.com/fvanroie/ConsoleInput.git
;git+https://github.com/andrethomas/TasmotaSlave.git
;git+https://github.com/lvgl/lvgl.git
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 25f8d593..30819a31 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -67,7 +67,7 @@ lib_deps =
; lv_drivers@~7.9.1
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.3 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
git+https://github.com/lvgl/lv_lib_png.git#release/v7
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index e49d3447..e68c716b 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -62,7 +62,7 @@ lib_deps =
;lv_drivers@~7.9.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.3 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
lib_ignore =
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index 9bc1f7c7..babadf77 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -93,7 +93,7 @@ lib_deps =
;lv_drivers@~7.9.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.3 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
lib_ignore =
From 982ec0bfa6f1b3de92916d1e125d095513f7aa8e Mon Sep 17 00:00:00 2001
From: TheHexaMaster <129121144+TheHexaMaster@users.noreply.github.com>
Date: Fri, 8 Dec 2023 21:19:23 +0100
Subject: [PATCH 036/135] Create wz2432r028.ini
Support for Wizee 2,8" WZ2432R028 ESP32 Display
---
user_setups/esp32/wz2432r028.ini | 48 ++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 user_setups/esp32/wz2432r028.ini
diff --git a/user_setups/esp32/wz2432r028.ini b/user_setups/esp32/wz2432r028.ini
new file mode 100644
index 00000000..9e5c0c36
--- /dev/null
+++ b/user_setups/esp32/wz2432r028.ini
@@ -0,0 +1,48 @@
+;***************************************************;
+; Wizee WZ2432R028 ESP32-WROOM custom dev board ;
+; - ILI9341 TFT SPI 4-WIRE ;
+; - XPT2046 touch controller ;
+;***************************************************;
+
+[env:wz2432r028]
+extends = arduino_esp32_v2, flash_4mb
+board = denky32
+upload_speed = 921600
+
+build_flags =
+ ${arduino_esp32_v2.build_flags}
+ ${esp32.no_ps_ram}
+
+;region -- TFT_eSPI build options ------------------------
+ ${esp32.hspi}
+ -D USER_SETUP_LOADED=1
+ -D ILI9341_DRIVER=1
+ -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=320
+
+ -D TFT_DC=2
+ -D TFT_CS=15
+ -D TFT_SCLK=14
+ -D TFT_MOSI=13
+ -D TFT_MISO=12
+ -D TFT_BCKL=27
+ -D SUPPORT_TRANSACTIONS
+ -D SPI_FREQUENCY=65000000
+ -D SPI_READ_FREQUENCY=20000000
+ -D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
+ -D HASP_USE_LGFX_TOUCH=1
+ -D TOUCH_CS=33
+ -D TOUCH_SCLK=25
+ -D TOUCH_MOSI=32
+ -D TOUCH_MISO=39
+ -D TOUCH_SDA=-1
+ -D TOUCH_SCL=-1
+ -D TOUCH_IRQ=36
+ -D SPI_TOUCH_FREQUENCY=2500000
+
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
+lib_deps =
+ ${arduino_esp32_v2.lib_deps}
+ ${tft_espi.lib_deps}
From 62b858fc03ea050f595087de168c99c1da739383 Mon Sep 17 00:00:00 2001
From: TheHexaMaster <129121144+TheHexaMaster@users.noreply.github.com>
Date: Fri, 8 Dec 2023 21:20:12 +0100
Subject: [PATCH 037/135] Update platformio_override-template.ini
Added wz2432r028
---
platformio_override-template.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index c9ed61f1..dcd3918e 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -70,6 +70,7 @@ extra_default_envs =
; wt32-sc01-plus_8MB
; wt-86-32-3zw1
; yeacreate-nscreen32
+ ; wz2432r028
;endregion
;region -- Define your local COM ports for each environment ---
From 4de8f4953eb0b75e17800a707da0ad76f06b783f Mon Sep 17 00:00:00 2001
From: Alvaro Lobato
Date: Fri, 22 Dec 2023 00:02:05 +0100
Subject: [PATCH 038/135] Fix mac build: - Change compiler version so it works
with newer MacOS - Fix library paths - Exclude freetype which creates a build
error
---
tools/osx_build_extra.py | 3 ++-
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 7 +++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/tools/osx_build_extra.py b/tools/osx_build_extra.py
index 3f445946..ae726458 100644
--- a/tools/osx_build_extra.py
+++ b/tools/osx_build_extra.py
@@ -1,6 +1,7 @@
Import("env")
-env.Replace(CC="gcc-10", CXX="g++-10")
+#env.Replace(CC="gcc-10", CXX="g++-10")
+env.Replace(CC="gcc-12", CXX="g++-12")
env.Replace(BUILD_SCRIPT="tools/osx_build_script.py")
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 30819a31..a1e64062 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -58,8 +58,10 @@ build_flags =
-lm
-lpthread
; MacOS with Homebrew
- -I/usr/local/include
- -L/usr/local/lib
+ ;-I/usr/local/include
+ ;-L/usr/local/lib
+ -I/opt/homebrew/include
+ -L/opt/homebrew/lib
-DTARGET_OS_MAC=1
lib_deps =
@@ -77,6 +79,7 @@ lib_ignore =
ArduinoLog
lv_lib_qrcode
ETHSPI
+ freetype
build_src_filter =
+<*>
From e756b4b4e2877a974dcf4900139415da8ccaa326 Mon Sep 17 00:00:00 2001
From: Alvaro Lobato
Date: Fri, 22 Dec 2023 00:02:05 +0100
Subject: [PATCH 039/135] Fix mac build: - Change compiler version so it works
with newer MacOS - Fix library paths - Exclude freetype which creates a build
error
---
tools/osx_build_extra.py | 3 ++-
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 7 +++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/tools/osx_build_extra.py b/tools/osx_build_extra.py
index 3f445946..ae726458 100644
--- a/tools/osx_build_extra.py
+++ b/tools/osx_build_extra.py
@@ -1,6 +1,7 @@
Import("env")
-env.Replace(CC="gcc-10", CXX="g++-10")
+#env.Replace(CC="gcc-10", CXX="g++-10")
+env.Replace(CC="gcc-12", CXX="g++-12")
env.Replace(BUILD_SCRIPT="tools/osx_build_script.py")
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 30819a31..a1e64062 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -58,8 +58,10 @@ build_flags =
-lm
-lpthread
; MacOS with Homebrew
- -I/usr/local/include
- -L/usr/local/lib
+ ;-I/usr/local/include
+ ;-L/usr/local/lib
+ -I/opt/homebrew/include
+ -L/opt/homebrew/lib
-DTARGET_OS_MAC=1
lib_deps =
@@ -77,6 +79,7 @@ lib_ignore =
ArduinoLog
lv_lib_qrcode
ETHSPI
+ freetype
build_src_filter =
+<*>
From 8b3451a1346ab4db2fe0d60b9a610785a1e704d6 Mon Sep 17 00:00:00 2001
From: tbxmb
Date: Tue, 2 Jan 2024 19:17:09 +0100
Subject: [PATCH 040/135] Add: Pin configuration for esp32-s3-4848S040 #603
---
user_setups/esp32s3/esp32-s3-4848S040.ini | 85 +++++++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 user_setups/esp32s3/esp32-s3-4848S040.ini
diff --git a/user_setups/esp32s3/esp32-s3-4848S040.ini b/user_setups/esp32s3/esp32-s3-4848S040.ini
new file mode 100644
index 00000000..d620c21c
--- /dev/null
+++ b/user_setups/esp32s3/esp32-s3-4848S040.ini
@@ -0,0 +1,85 @@
+;***************************************************;
+; Generic T3E with TFT 3.95" ;
+; - Custom esp32-s3 board ;
+; - st7701s TFT ;
+; - gt911 touch controller ;
+;***************************************************;
+
+[esp32-s3-4848S040]
+extends = arduino_esp32s3_v2
+board = esp32-s3-devkitc-1
+board_build.arduino.memory_type = qio_opi
+
+build_flags =
+ -D HASP_MODEL="ESP32-S3 4848S040"
+ ${arduino_esp32s3_v2.build_flags}
+ ${esp32s3.ps_ram}
+ ;-DARDUINO_USB_CDC_ON_BOOT
+ ;-DUSE_USB_CDC_CONSOLE
+
+;region -- ArduinoGFX build options ------------------------
+ -D HASP_USE_ARDUINOGFX=1
+ -D ST7701_DRIVER=1
+ -D TFT_WIDTH=480
+ -D TFT_HEIGHT=480
+ ; Bus Settings
+ -D TFT_CS=39
+ -D TFT_SCLK=48
+ -D TFT_MOSI=47
+ -D TFT_DE=18
+ -D TFT_VSYNC=17
+ -D TFT_HSYNC=16
+ -D TFT_PCLK=21
+ -D TFT_R0=11
+ -D TFT_R1=12
+ -D TFT_R2=13
+ -D TFT_R3=14
+ -D TFT_R4=0
+ -D TFT_G0=8
+ -D TFT_G1=20
+ -D TFT_G2=3
+ -D TFT_G3=46
+ -D TFT_G4=9
+ -D TFT_G5=10
+ -D TFT_B0=4
+ -D TFT_B1=5
+ -D TFT_B2=6
+ -D TFT_B3=7
+ -D TFT_B4=15
+ -D TFT_DC=-1
+ -D TFT_MISO=-1
+ -D TFT_RST=-1
+ -D TFT_BUSY=-1
+ -D TFT_BCKL=38
+ ; Panel Settings
+ -D TFT_HSYNC_POLARITY=1
+ -D TFT_HSYNC_FRONT_PORCH=10
+ -D TFT_HSYNC_PULSE_WIDTH=8
+ -D TFT_HSYNC_BACK_PORCH=50
+ -D TFT_VSYNC_POLARITY=1
+ -D TFT_VSYNC_FRONT_PORCH=10
+ -D TFT_VSYNC_PULSE_WIDTH=8
+ -D TFT_VSYNC_BACK_PORCH=20
+ -D TFT_PCLK_ACTIVE_NEG=1
+ -D TFT_PREFER_SPEED=12000000
+ -D TFT_AUTO_FLUSH=1
+ ; Touch Settings
+ -D TOUCH_DRIVER=0x911
+ -D TOUCH_WIDTH=480
+ -D TOUCH_HEIGHT=480
+ -D TOUCH_SDA=19
+ -D TOUCH_SCL=45
+ -D TOUCH_RST=-1
+ -D TOUCH_IRQ=-1
+ -D I2C_TOUCH_FREQUENCY=400000
+ -D I2C_TOUCH_ADDRESS=0x5D ; or 0x14
+ -D I2C_TOUCH_PORT=1
+;endregion
+
+lib_deps =
+ ${arduino_esp32s3_v2.lib_deps}
+ ${arduinogfx.lib_deps}
+ ${goodix.lib_deps}
+
+[env:esp32-s3-4848S040]
+extends = esp32-s3-4848S040, flash_16mb
\ No newline at end of file
From 7af48cff375fc0c73ffa10230f0dc45a7c1a2354 Mon Sep 17 00:00:00 2001
From: tbxmb
Date: Wed, 3 Jan 2024 02:37:14 +0100
Subject: [PATCH 041/135] Add modified init operations for esp32-s3-4848S040
#603
---
.../Arduino_RGB_Display_mod.h | 119 ++++++++++++++++++
platformio_override-template.ini | 1 +
src/drv/tft/tft_driver_arduinogfx.cpp | 10 ++
user_setups/esp32s3/esp32-s3-4848S040.ini | 1 +
4 files changed, 131 insertions(+)
diff --git a/lib/Arduino_RPi_DPI_RGBPanel_mod/Arduino_RGB_Display_mod.h b/lib/Arduino_RPi_DPI_RGBPanel_mod/Arduino_RGB_Display_mod.h
index 982da439..ae343534 100644
--- a/lib/Arduino_RPi_DPI_RGBPanel_mod/Arduino_RGB_Display_mod.h
+++ b/lib/Arduino_RPi_DPI_RGBPanel_mod/Arduino_RGB_Display_mod.h
@@ -11,6 +11,125 @@
#include "Arduino_GFX.h"
#include "Arduino_RGBPanel_mod.h"
+static const uint8_t st7701_4848S040_init_operations[] = {
+ BEGIN_WRITE,
+ WRITE_COMMAND_8, 0xFF,
+ WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x10,
+
+ WRITE_C8_D16, 0xC0, 0x3B, 0x00,
+ WRITE_C8_D16, 0xC1, 0x0D, 0x02,
+ WRITE_C8_D16, 0xC2, 0x31, 0x05,
+ WRITE_C8_D8, 0xCD, 0x00,//0x08
+
+ WRITE_COMMAND_8, 0xB0, // Positive Voltage Gamma Control
+ WRITE_BYTES, 16,
+ 0x00, 0x11, 0x18, 0x0E,
+ 0x11, 0x06, 0x07, 0x08,
+ 0x07, 0x22, 0x04, 0x12,
+ 0x0F, 0xAA, 0x31, 0x18,
+
+ WRITE_COMMAND_8, 0xB1, // Negative Voltage Gamma Control
+ WRITE_BYTES, 16,
+ 0x00, 0x11, 0x19, 0x0E,
+ 0x12, 0x07, 0x08, 0x08,
+ 0x08, 0x22, 0x04, 0x11,
+ 0x11, 0xA9, 0x32, 0x18,
+
+ // PAGE1
+ WRITE_COMMAND_8, 0xFF,
+ WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x11,
+
+ WRITE_C8_D8, 0xB0, 0x60, // Vop=4.7375v
+ WRITE_C8_D8, 0xB1, 0x32, // VCOM=32
+ WRITE_C8_D8, 0xB2, 0x07, // VGH=15v
+ WRITE_C8_D8, 0xB3, 0x80,
+ WRITE_C8_D8, 0xB5, 0x49, // VGL=-10.17v
+ WRITE_C8_D8, 0xB7, 0x85,
+ WRITE_C8_D8, 0xB8, 0x21, // AVDD=6.6 & AVCL=-4.6
+ WRITE_C8_D8, 0xC1, 0x78,
+ WRITE_C8_D8, 0xC2, 0x78,
+
+ WRITE_COMMAND_8, 0xE0,
+ WRITE_BYTES, 3, 0x00, 0x1B, 0x02,
+
+ WRITE_COMMAND_8, 0xE1,
+ WRITE_BYTES, 11,
+ 0x08, 0xA0, 0x00, 0x00,
+ 0x07, 0xA0, 0x00, 0x00,
+ 0x00, 0x44, 0x44,
+
+ WRITE_COMMAND_8, 0xE2,
+ WRITE_BYTES, 12,
+ 0x11, 0x11, 0x44, 0x44,
+ 0xED, 0xA0, 0x00, 0x00,
+ 0xEC, 0xA0, 0x00, 0x00,
+
+ WRITE_COMMAND_8, 0xE3,
+ WRITE_BYTES, 4, 0x00, 0x00, 0x11, 0x11,
+
+ WRITE_C8_D16, 0xE4, 0x44, 0x44,
+
+ WRITE_COMMAND_8, 0xE5,
+ WRITE_BYTES, 16,
+ 0x0A, 0xE9, 0xD8, 0xA0,
+ 0x0C, 0xEB, 0xD8, 0xA0,
+ 0x0E, 0xED, 0xD8, 0xA0,
+ 0x10, 0xEF, 0xD8, 0xA0,
+
+ WRITE_COMMAND_8, 0xE6,
+ WRITE_BYTES, 4, 0x00, 0x00, 0x11, 0x11,
+
+ WRITE_C8_D16, 0xE7, 0x44, 0x44,
+
+ WRITE_COMMAND_8, 0xE8,
+ WRITE_BYTES, 16,
+ 0x09, 0xE8, 0xD8, 0xA0,
+ 0x0B, 0xEA, 0xD8, 0xA0,
+ 0x0D, 0xEC, 0xD8, 0xA0,
+ 0x0F, 0xEE, 0xD8, 0xA0,
+
+ WRITE_COMMAND_8, 0xEB,
+ WRITE_BYTES, 7,
+ 0x02, 0x00, 0xE4, 0xE4,
+ 0x88, 0x00, 0x40,
+
+ WRITE_C8_D16, 0xEC, 0x3C, 0x00,
+
+ WRITE_COMMAND_8, 0xED,
+ WRITE_BYTES, 16,
+ 0xAB, 0x89, 0x76, 0x54,
+ 0x02, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x20,
+ 0x45, 0x67, 0x98, 0xBA,
+
+ //-----------VAP & VAN---------------
+ WRITE_COMMAND_8, 0xFF,
+ WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x13,
+
+ WRITE_C8_D8, 0xE5, 0xE4,
+
+ WRITE_COMMAND_8, 0xFF,
+ WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x00,
+
+ WRITE_COMMAND_8, 0x21, // 0x20 normal, 0x21 IPS
+ WRITE_C8_D8, 0x3A, 0x60, // 0x70 RGB888, 0x60 RGB666, 0x50 RGB565
+
+ //WRITE_COMMAND_8, 0x21,0X00,
+ //END_WRITE,
+
+ WRITE_COMMAND_8, 0x11, // Sleep Out
+ END_WRITE,
+
+ DELAY, 120,
+
+ BEGIN_WRITE,
+ WRITE_COMMAND_8, 0x29, // Display On
+ END_WRITE,
+
+ BEGIN_WRITE,
+ WRITE_COMMAND_8, 0x20, // Invert display
+ END_WRITE
+};
static const uint8_t st7701_sensecap_indicator_init_operations[] = {
BEGIN_WRITE,
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index dcd3918e..8de29970 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -71,6 +71,7 @@ extra_default_envs =
; wt-86-32-3zw1
; yeacreate-nscreen32
; wz2432r028
+ ; esp32-s3-4848S040
;endregion
;region -- Define your local COM ports for each environment ---
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index 69084b6a..ff6f0835 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -63,6 +63,16 @@ void ArduinoGfx::init(int w, int h)
tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST,
gc9503v_type1_init_operations, sizeof(gc9503v_type1_init_operations));
+#elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER) && defined(ST7701_4848S040)
+ Arduino_DataBus* bus = new Arduino_SWSPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO);
+ Arduino_ESP32RGBPanel* rgbpanel = new Arduino_ESP32RGBPanel(
+ TFT_DE, TFT_VSYNC, TFT_HSYNC, TFT_PCLK, TFT_R0, TFT_R1, TFT_R2, TFT_R3, TFT_R4, TFT_G0, TFT_G1, TFT_G2, TFT_G3,
+ TFT_G4, TFT_G5, TFT_B0, TFT_B1, TFT_B2, TFT_B3, TFT_B4, TFT_HSYNC_POLARITY, TFT_HSYNC_FRONT_PORCH,
+ TFT_HSYNC_PULSE_WIDTH, TFT_HSYNC_BACK_PORCH, TFT_VSYNC_POLARITY, TFT_VSYNC_FRONT_PORCH, TFT_VSYNC_PULSE_WIDTH,
+ TFT_VSYNC_BACK_PORCH);
+
+ tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST,
+ st7701_4848S040_init_operations, sizeof(st7701_4848S040_init_operations));
#elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER)
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus* bus = new Arduino_SWSPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO);
diff --git a/user_setups/esp32s3/esp32-s3-4848S040.ini b/user_setups/esp32s3/esp32-s3-4848S040.ini
index d620c21c..db5a5b6e 100644
--- a/user_setups/esp32s3/esp32-s3-4848S040.ini
+++ b/user_setups/esp32s3/esp32-s3-4848S040.ini
@@ -20,6 +20,7 @@ build_flags =
;region -- ArduinoGFX build options ------------------------
-D HASP_USE_ARDUINOGFX=1
-D ST7701_DRIVER=1
+ -D ST7701_4848S040=1
-D TFT_WIDTH=480
-D TFT_HEIGHT=480
; Bus Settings
From 9864ae7a87a7cbd1d09b0c4c685763c038336f98 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Thu, 4 Jan 2024 03:09:40 +0100
Subject: [PATCH 042/135] Revert "sleep state - run idle scripts and allow to
control the backlight"
---
src/hasp/hasp.cpp | 14 +++++++-------
src/hasp/hasp.h | 2 +-
src/hasp/hasp_dispatch.cpp | 9 ++++++---
3 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index ad9cc5fd..9187f4ad 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -119,17 +119,20 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state()
if(sleepTimeLong > 0 && idle >= (sleepTimeShort + sleepTimeLong)) {
if(hasp_sleep_state != HASP_SLEEP_LONG) {
gui_hide_pointer(true);
- hasp_set_sleep_state(HASP_SLEEP_LONG, TAG_MAIN);
+ hasp_sleep_state = HASP_SLEEP_LONG;
+ dispatch_idle_state(HASP_SLEEP_LONG);
}
} else if(sleepTimeShort > 0 && idle >= sleepTimeShort) {
if(hasp_sleep_state != HASP_SLEEP_SHORT) {
gui_hide_pointer(true);
- hasp_set_sleep_state(HASP_SLEEP_SHORT, TAG_MAIN);
+ hasp_sleep_state = HASP_SLEEP_SHORT;
+ dispatch_idle_state(HASP_SLEEP_SHORT);
}
} else {
if(hasp_sleep_state != HASP_SLEEP_OFF) {
gui_hide_pointer(false);
- hasp_set_sleep_state(HASP_SLEEP_OFF, TAG_MAIN);
+ hasp_sleep_state = HASP_SLEEP_OFF;
+ dispatch_idle_state(HASP_SLEEP_OFF);
}
}
}
@@ -144,21 +147,18 @@ uint8_t hasp_get_sleep_state()
return hasp_sleep_state;
}
-void hasp_set_sleep_state(uint8_t state, uint8_t source)
+void hasp_set_sleep_state(uint8_t state)
{
switch(state) {
case HASP_SLEEP_LONG:
hasp_set_sleep_offset(sleepTimeShort + sleepTimeLong);
- dispatch_run_script(NULL, "L:/idle_long.cmd", source);
break;
case HASP_SLEEP_SHORT:
hasp_set_sleep_offset(sleepTimeShort);
- dispatch_run_script(NULL, "L:/idle_short.cmd", source);
break;
case HASP_SLEEP_OFF:
hasp_set_sleep_offset(0);
// hasp_set_wakeup_touch(false);
- dispatch_run_script(NULL, "L:/idle_off.cmd", source);
break;
default:
return;
diff --git a/src/hasp/hasp.h b/src/hasp/hasp.h
index cf30abed..4b9b5217 100644
--- a/src/hasp/hasp.h
+++ b/src/hasp/hasp.h
@@ -79,7 +79,7 @@ lv_font_t* hasp_get_font(uint8_t fontid);
HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state();
void hasp_get_sleep_payload(uint8_t state, char* payload);
uint8_t hasp_get_sleep_state();
-void hasp_set_sleep_state(uint8_t state, uint8_t source);
+void hasp_set_sleep_state(uint8_t state);
void hasp_get_sleep_time(uint16_t& short_time, uint16_t& long_time);
void hasp_set_sleep_time(uint16_t short_time, uint16_t long_time);
void hasp_set_sleep_offset(uint32_t offset);
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 38548264..3ffe667f 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -1364,11 +1364,14 @@ void dispatch_idle(const char*, const char* payload, uint8_t source)
if(payload && strlen(payload)) {
uint8_t state = HASP_SLEEP_LAST;
if(!strcmp_P(payload, "off")) {
- hasp_set_sleep_state(HASP_SLEEP_OFF, source);
+ hasp_set_sleep_state(HASP_SLEEP_OFF);
+ dispatch_run_script(NULL, "L:/idle_off.cmd", source);
} else if(!strcmp_P(payload, "short")) {
- hasp_set_sleep_state(HASP_SLEEP_SHORT, source);
+ hasp_set_sleep_state(HASP_SLEEP_SHORT);
+ dispatch_run_script(NULL, "L:/idle_short.cmd", source);
} else if(!strcmp_P(payload, "long")) {
- hasp_set_sleep_state(HASP_SLEEP_LONG, source);
+ hasp_set_sleep_state(HASP_SLEEP_LONG);
+ dispatch_run_script(NULL, "L:/idle_long.cmd", source);
} else {
LOG_WARNING(TAG_MSGR, F("Invalid idle value %s"), payload);
return;
From a5e348e499dcfe58ee6f772865e3dbcba08a9f59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20St=C3=BCck?=
Date: Mon, 15 Jan 2024 15:52:11 -0500
Subject: [PATCH 043/135] Add Adafruit TSC2007 library from
https://github.com/adafruit/Adafruit_TSC2007
---
.gitmodules | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.gitmodules b/.gitmodules
index 90d1c1d0..7706a667 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,7 @@
[submodule "lib/freetype"]
path = lib/freetype
url = https://github.com/fvanroie/freetype
-
\ No newline at end of file
+
+[submodule "lib/Adafruit_TSC2007"]
+ path = lib/Adafruit_TSC2007
+ url = https://github.com/adafruit/Adafruit_TSC2007.git
From ab4664b4b8e6b01c0c9b5ae4d939f492f26ab2de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20St=C3=BCck?=
Date: Mon, 15 Jan 2024 15:53:04 -0500
Subject: [PATCH 044/135] Add support for TSC2007 touch controller
---
platformio.ini | 4 ++
src/drv/touch/touch_driver.h | 3 +
src/drv/touch/touch_driver_tsc2007.h | 104 +++++++++++++++++++++++++++
3 files changed, 111 insertions(+)
create mode 100644 src/drv/touch/touch_driver_tsc2007.h
diff --git a/platformio.ini b/platformio.ini
index c28cea8c..dc0edda8 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -124,6 +124,10 @@ lib_deps =
lib_deps =
git+https://github.com/aselectroworks/Arduino-FT6336U.git
+[tsc2007]
+lib_deps =
+ git+https://github.com/adafruit/Adafruit_TSC2007.git
+
[gsl1680]
lib_deps =
git+https://github.com/arovak/GSL2038.git
diff --git a/src/drv/touch/touch_driver.h b/src/drv/touch/touch_driver.h
index 674558f7..7e729180 100644
--- a/src/drv/touch/touch_driver.h
+++ b/src/drv/touch/touch_driver.h
@@ -84,6 +84,9 @@ class BaseTouch {
#elif TOUCH_DRIVER == 0x1680
#warning Building for GSL1680
#include "touch_driver_gslx680.h"
+#elif TOUCH_DRIVER == 0x2007
+#warning Building for TSC2007
+#include "touch_driver_tsc2007.h"
#elif defined(LGFX_USE_V1)
#warning Building for LovyanGfx Touch
#include "touch_driver_lovyangfx.h"
diff --git a/src/drv/touch/touch_driver_tsc2007.h b/src/drv/touch/touch_driver_tsc2007.h
new file mode 100644
index 00000000..7688842c
--- /dev/null
+++ b/src/drv/touch/touch_driver_tsc2007.h
@@ -0,0 +1,104 @@
+/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+ For full license information read the LICENSE file in the project folder */
+
+#ifndef HASP_TSC2007_TOUCH_DRIVER_H
+#define HASP_TSC2007_TOUCH_DRIVER_H
+
+#if defined(ARDUINO) && !defined(HASP_USE_LGFX_TOUCH)
+#include
+#include "ArduinoLog.h"
+#include "hasp_conf.h"
+
+#include
+#include "Adafruit_TSC2007.h"
+
+#include "touch_driver.h" // base class
+#include "touch_helper.h" // i2c scanner
+
+#include "hasp_debug.h"
+
+#include "../../hasp/hasp.h" // for hasp_sleep_state
+extern uint8_t hasp_sleep_state;
+
+// This is calibration data for the raw touch data to the screen coordinates
+#define TS_MINX 150
+#define TS_MINY 130
+#define TS_MAXX 3800
+#define TS_MAXY 4000
+#define TS_MIN_PRESSURE 100
+
+namespace dev {
+
+class TouchTsc2007 : public BaseTouch {
+ public:
+ Adafruit_TSC2007* ts;
+
+ IRAM_ATTR bool read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data)
+ {
+ uint16_t x, y, z1, z2;
+ if (ts->read_touch(&x, &y, &z1, &z2) && (z1 > TS_MIN_PRESSURE)) {
+ if(hasp_sleep_state != HASP_SLEEP_OFF) hasp_update_sleep_state(); // update Idle
+
+ data->state = LV_INDEV_STATE_PR;
+ hasp_set_sleep_offset(0); // Reset the offset
+
+ // Scale from ~0->4000 to tft.width using the calibration #'s
+ x = map(x, TS_MINX, TS_MAXX, 0, TFT_WIDTH);
+ y = map(y, TS_MINY, TS_MAXY, 0, TFT_HEIGHT);
+
+ // LOG_INFO(TAG_DRVR, F("Touch point: %i, %i"), x, y);
+
+#if defined(TOUCH_SWAP_XY) && (TOUCH_SWAP_XY)
+ data->point.x = y;
+ data->point.y = x;
+#else
+ data->point.x = x;
+ data->point.y = y;
+#endif
+
+#if defined(TOUCH_INVERSE_X) && (TOUCH_INVERSE_X)
+ data->point.x = _width_max - x;
+#endif
+#if defined(TOUCH_INVERSE_Y) && (TOUCH_INVERSE_Y)
+ data->point.y = _height_max - y;
+#endif
+
+ } else {
+ data->state = LV_INDEV_STATE_REL;
+ }
+
+ /*Return `false` because we are not buffering and no more data to read*/
+ return false;
+ }
+
+ void init(int w, int h)
+ {
+ _height_max = h - 1;
+ _width_max = w - 1;
+
+ // tsc2007_touch = new Adafruit_TSC2007();
+ LOG_VERBOSE(TAG_DRVR, F("%s %d"), __FILE__, __LINE__);
+
+ ts = new Adafruit_TSC2007();
+
+ // Startup sequence CONTROLLER parT
+ if (!ts->begin()) {
+ LOG_INFO(TAG_DRVR, F("Failed to find Adafruit TSC2007 chip"));
+ while (1) { delay(10); }
+ }
+ LOG_INFO(TAG_DRVR, F("Found Adafruit TSC2007 chip"));
+ }
+
+ private:
+ uint16_t _width_max;
+ uint16_t _height_max;
+};
+
+} // namespace dev
+
+using dev::TouchTsc2007;
+dev::TouchTsc2007 haspTouch;
+
+#endif // ARDUINO
+
+#endif // HASP_TSC2007_TOUCH_DRIVER_H
\ No newline at end of file
From a0ed65c4ce8493c85849552ac77a2d0c397bfcbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20St=C3=BCck?=
Date: Mon, 15 Jan 2024 16:15:54 -0500
Subject: [PATCH 045/135] Add support for updated Adafruit 2.4 and 3.5 TFT
FeatherWings and HUZZAH32 boards
Support added for the following displays:
- [Adafruit TFT FeatherWing - 2.4" 320x240 Touchscreen For All Feathers - V2](https://www.adafruit.com/product/3315)
- [Adafruit TFT FeatherWing - 3.5" 480x320 Touchscreen for Feathers - V2 with TSC2007](https://www.adafruit.com/product/3651)
Support added for the following board:
- [Adafruit HUZZAH32 ESP32 Feather V2 - 8MB Flash + 2 MB PSRAM - STEMMA QT](https://www.adafruit.com/product/5400)
---
.github/workflows/build.yaml | 2 +-
.github/workflows/release.yml | 2 +-
platformio_override-template.ini | 6 +++
.../esp32/huzzah32-featherwing-24-v2.ini | 31 ++++++++++++++
.../esp32/huzzah32-featherwing-35-v2.ini | 32 +++++++++++++++
.../esp32/huzzah32-v2-featherwing-24-v2.ini | 31 ++++++++++++++
.../esp32/huzzah32-v2-featherwing-35-v2.ini | 31 ++++++++++++++
.../esp32s2/esp32s2-featherwing-24-v2.ini | 40 +++++++++++++++++++
.../esp32s2/esp32s2-featherwing-35-v2.ini | 40 +++++++++++++++++++
user_setups/lcd_config.ini | 23 +++++++++++
10 files changed, 236 insertions(+), 2 deletions(-)
create mode 100644 user_setups/esp32/huzzah32-featherwing-24-v2.ini
create mode 100644 user_setups/esp32/huzzah32-featherwing-35-v2.ini
create mode 100644 user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini
create mode 100644 user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini
create mode 100644 user_setups/esp32s2/esp32s2-featherwing-24-v2.ini
create mode 100644 user_setups/esp32s2/esp32s2-featherwing-35-v2.ini
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index abcec923..d57b3061 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -21,7 +21,7 @@ jobs:
matrix:
environment:
- out: adafruit
- env: "huzzah32-featherwing-24 -e huzzah32-featherwing-35"
+ env: "huzzah32-featherwing-24 -e huzzah32-featherwing-35 -e huzzah32-featherwing-24-v2 -e huzzah32-featherwing-35-v2 -e huzzah32-v2-featherwing-24-v2 -e huzzah32-v2-featherwing-35-v2"
- out: az-touch
env: "az-touch-mod-esp32_ili9341_4MB -e az-touch-mod-esp32_ili9341_8MB"
- env: d1-mini-esp32_ili9341
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b47c2d78..62ef57b4 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -63,7 +63,7 @@ jobs:
- name: Run PlatformIO
run: pio run -e esp32-touchdown -e freetouchdeck_4MB -e freetouchdeck_8MB
- name: Run PlatformIO
- run: pio run -e huzzah32-featherwing-24 -e huzzah32-featherwing-35
+ run: pio run -e huzzah32-featherwing-24 -e huzzah32-featherwing-35 -e huzzah32-featherwing-24-v2 -e huzzah32-featherwing-35-v2 -e huzzah32-v2-featherwing-24-v2 -e huzzah32-v2-featherwing-35-v2
- name: Run PlatformIO
run: pio run -e lanbon_l8
- name: Run PlatformIO
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index 8de29970..941fe815 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -29,6 +29,8 @@ extra_default_envs =
; d1-r32-unoshield_ili9341_adc
; d1-r32-unoshield_ili9486_adc
; d1-r32-waveshare_ili9486
+ ; esp32s2-featherwing-24-v2
+ ; esp32s2-featherwing-35-v2
; esp32-2432s028r_4MB
; esp32-3248s035c_4MB
; esp32-3248s035c_4MB_lovyan
@@ -44,7 +46,11 @@ extra_default_envs =
; freetouchdeck-s3_8MB
; gs-t3e_16MB
; huzzah32-featherwing-24
+ ; huzzah32-featherwing-24-v2
+ ; huzzah32-v2-featherwing-24-v2
; huzzah32-featherwing-35
+ ; huzzah32-featherwing-35-v2
+ ; huzzah32-v2-featherwing-35-v2
; lanbon_l8
; lanbon_l8_eth
; lilygo-lily-pi_ili9481
diff --git a/user_setups/esp32/huzzah32-featherwing-24-v2.ini b/user_setups/esp32/huzzah32-featherwing-24-v2.ini
new file mode 100644
index 00000000..8c97b591
--- /dev/null
+++ b/user_setups/esp32/huzzah32-featherwing-24-v2.ini
@@ -0,0 +1,31 @@
+;***************************************************;
+; HUZZAH32 ESP32 with Featherwing TFT 2.4" V2 ;
+; - HUZZAH32 esp32 board ;
+; - ili9341 TFT Featherwing 2.4" V2 ;
+; - TSC2007 touch controller ;
+;***************************************************;
+
+[env:huzzah32-featherwing-24-v2]
+extends = arduino_esp32_v2, flash_4mb
+board = featheresp32
+
+build_flags =
+ -D HASP_MODEL="Adafruit HUZZAH32 ESP32 Featherwing 2.4 V2"
+ ${arduino_esp32_v2.build_flags}
+ ${esp32.no_ps_ram}
+
+;region -- TFT_eSPI build options ------------------------
+ ${lcd.featherwing-24-v2}
+ -D TFT_MISO=19
+ -D TFT_MOSI=18
+ -D TFT_SCLK=5
+ -D TFT_DC=33
+ -D TFT_CS=15
+ -D TFT_RST=-1 ; RST
+ -D TFT_BCKL=21 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21
+;endregion
+
+lib_deps =
+ ${arduino_esp32_v2.lib_deps}
+ ${tft_espi.lib_deps}
+ ${tsc2007.lib_deps}
\ No newline at end of file
diff --git a/user_setups/esp32/huzzah32-featherwing-35-v2.ini b/user_setups/esp32/huzzah32-featherwing-35-v2.ini
new file mode 100644
index 00000000..8b17d1bf
--- /dev/null
+++ b/user_setups/esp32/huzzah32-featherwing-35-v2.ini
@@ -0,0 +1,32 @@
+;***************************************************;
+; HUZZAH32 ESP32 with Featherwing TFT 3.5" V2 ;
+; - HUZZAH32 esp32 board ;
+; - HX8357D TFT Featherwing 3.5" V2 ;
+; - TSC2007 touch controller ;
+;***************************************************;
+
+[env:huzzah32-featherwing-35-v2]
+extends = arduino_esp32_v2, flash_4mb
+board = featheresp32
+
+build_flags =
+ -D HASP_MODEL="Adafruit HUZZAH32 ESP32 Featherwing 3.5 V2"
+ ${arduino_esp32_v2.build_flags}
+ ${esp32.no_ps_ram}
+
+ -D LV_INDEV_DEF_READ_PERIOD=30
+;region -- TFT_eSPI build options ------------------------
+ ${lcd.featherwing-35-v2}
+ -D TFT_MISO=19
+ -D TFT_MOSI=18
+ -D TFT_SCLK=5
+ -D TFT_DC=10
+ -D TFT_CS=9
+ -D TFT_RST=-1 ; RST
+ -D TFT_BCKL=21 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21
+;endregion
+
+lib_deps =
+ ${arduino_esp32_v2.lib_deps}
+ ${tft_espi.lib_deps}
+ ${tsc2007.lib_deps}
diff --git a/user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini b/user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini
new file mode 100644
index 00000000..29261680
--- /dev/null
+++ b/user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini
@@ -0,0 +1,31 @@
+;***************************************************;
+; HUZZAH32 V2 ESP32 with Featherwing TFT 2.4" V2 ;
+; - HUZZAH32 V2 w/ 2 MB PSRAM board ;
+; - ili9341 TFT Featherwing 2.4" V2 ;
+; - TSC2007 touch controller ;
+;***************************************************;
+
+[env:huzzah32-featherwing-24-v2]
+extends = arduino_esp32_v2, flash_4mb
+board = featheresp32
+
+build_flags =
+ -D HASP_MODEL="Adafruit HUZZAH32 V2 ESP32 Featherwing 2.4 V2"
+ ${arduino_esp32_v2.build_flags}
+ ${esp32.ps_ram}
+
+;region -- TFT_eSPI build options ------------------------
+ ${lcd.featherwing-24-v2}
+ -D TFT_MISO=19
+ -D TFT_MOSI=18
+ -D TFT_SCLK=5
+ -D TFT_DC=33
+ -D TFT_CS=15
+ -D TFT_RST=-1 ; RST
+ -D TFT_BCKL=21 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21
+;endregion
+
+lib_deps =
+ ${arduino_esp32_v2.lib_deps}
+ ${tft_espi.lib_deps}
+ ${tsc2007.lib_deps}
\ No newline at end of file
diff --git a/user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini b/user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini
new file mode 100644
index 00000000..c2a6b4c2
--- /dev/null
+++ b/user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini
@@ -0,0 +1,31 @@
+;***************************************************;
+; HUZZAH32 V2 ESP32 with Featherwing TFT 3.5" V2 ;
+; - HUZZAH32 V2 w/ 2 MB PSRAM board ;
+; - HX8357D TFT Featherwing 3.5" V2 ;
+; - TSC2007 touch controller ;
+;***************************************************;
+
+[env:huzzah32-v2-featherwing-35]
+extends = arduino_esp32_v2, flash_4mb
+board = featheresp32
+
+build_flags =
+ -D HASP_MODEL="Adafruit HUZZAH32 V2 ESP32 Featherwing 3.5 V2"
+ ${arduino_esp32_v2.build_flags}
+ ${esp32.ps_ram}
+ -D LV_INDEV_DEF_READ_PERIOD=30
+;region -- TFT_eSPI build options ------------------------
+ ${lcd.featherwing-35-v2}
+ -D TFT_MISO=19
+ -D TFT_MOSI=18
+ -D TFT_SCLK=5
+ -D TFT_DC=10
+ -D TFT_CS=9
+ -D TFT_RST=-1 ; RST
+ -D TFT_BCKL=21 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21
+;endregion
+
+lib_deps =
+ ${arduino_esp32_v2.lib_deps}
+ ${tft_espi.lib_deps}
+ ${tsc2007.lib_deps}
diff --git a/user_setups/esp32s2/esp32s2-featherwing-24-v2.ini b/user_setups/esp32s2/esp32s2-featherwing-24-v2.ini
new file mode 100644
index 00000000..cb102e00
--- /dev/null
+++ b/user_setups/esp32s2/esp32s2-featherwing-24-v2.ini
@@ -0,0 +1,40 @@
+;***************************************************;
+; Adafruit ESP32-S2 with Featherwing TFT 2.4" V2 ;
+; - ESP32-S2 w/ 2 MB PSRAM board ;
+; - ili9341 TFT Featherwing 2.4" V2 ;
+; - TSC2007 touch controller ;
+;***************************************************;
+
+[env:esp32s2-featherwing-24-v2]
+extends = esp32s2_4mb_v2
+board = esp32s2
+
+build_flags =
+ ${env.build_flags}
+ ${esp32s2.build_flags}
+ ${esp32.ps_ram}
+ -D HASP_MODEL="Adafruit ESP32-S2 Featherwing 2.4 V2"
+ -D USE_HSPI_PORT
+
+;region -- TFT_eSPI build options ------------------------
+ ${lcd.featherwing-24-v2}
+ -D LGFX_USE_V1=1
+ -D TFT_MISO=19
+ -D TFT_MOSI=18
+ -D TFT_SCLK=5
+ -D TFT_DC=33
+ -D TFT_CS=15
+ -D TFT_RST=-1 ; RST
+ -D TFT_BCKL=21 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21
+;endregion
+
+lib_deps =
+ ${env.lib_deps}
+ ${esp32s2.lib_deps}
+ ${lovyangfx.lib_deps}
+ ${tsc2007.lib_deps}
+
+lib_ignore =
+ ${env.lib_ignore}
+ ${esp32s2.lib_ignore}
+ TFT_eSPI
diff --git a/user_setups/esp32s2/esp32s2-featherwing-35-v2.ini b/user_setups/esp32s2/esp32s2-featherwing-35-v2.ini
new file mode 100644
index 00000000..b781f449
--- /dev/null
+++ b/user_setups/esp32s2/esp32s2-featherwing-35-v2.ini
@@ -0,0 +1,40 @@
+;***************************************************;
+; Adafruit ESP32-S2 with Featherwing TFT 3.5" V2 ;
+; - ESP32-S2 w/ 2 MB PSRAM board ;
+; - HX8357D TFT Featherwing 3.5" V2 ;
+; - TSC2007 touch controller ;
+;***************************************************;
+
+[env:esp32s2-featherwing-24-v2]
+extends = esp32s2_4mb_v2
+board = esp32s2
+
+build_flags =
+ ${env.build_flags}
+ ${esp32s2.build_flags}
+ ${esp32.ps_ram}
+ -D HASP_MODEL="Adafruit ESP32-S2 Featherwing 3.5 V2"
+ -D USE_HSPI_PORT
+
+;region -- TFT_eSPI build options ------------------------
+ ${lcd.featherwing-35-v2}
+ -D LGFX_USE_V1=1
+ -D TFT_MISO=19
+ -D TFT_MOSI=18
+ -D TFT_SCLK=5
+ -D TFT_DC=10
+ -D TFT_CS=9
+ -D TFT_RST=-1 ; RST
+ -D TFT_BCKL=21 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21
+;endregion
+
+lib_deps =
+ ${env.lib_deps}
+ ${esp32s2.lib_deps}
+ ${tsc2007.lib_deps}
+ ${lovyangfx.lib_deps}
+
+lib_ignore =
+ ${env.lib_ignore}
+ ${esp32s2.lib_ignore}
+ TFT_eSPI
diff --git a/user_setups/lcd_config.ini b/user_setups/lcd_config.ini
index ce4e272b..8b5df106 100644
--- a/user_setups/lcd_config.ini
+++ b/user_setups/lcd_config.ini
@@ -122,6 +122,18 @@ featherwing-35 =
-D TOUCH_DRIVER=0x0610 ;STMPE610
;-D SUPPORT_TRANSACTIONS ; Default on ESP32
+featherwing-35-v2 =
+ -D HX8357D_DRIVER=1
+ -D TFT_WIDTH=320
+ -D TFT_HEIGHT=480
+ -D TFT_ROTATION=0 ; Use default, see TFT_ROTATION values
+ -D SPI_FREQUENCY=27000000
+ -D SPI_TOUCH_FREQUENCY=2500000
+ -D SPI_READ_FREQUENCY=20000000
+ -D USER_SETUP_LOADED=1
+ -D TOUCH_DRIVER=0x2007 ;TSC2007
+ ;-D SUPPORT_TRANSACTIONS ; Default on ESP32
+
featherwing-24 =
-D ILI9341_DRIVER=1
-D TFT_WIDTH=240
@@ -132,4 +144,15 @@ featherwing-24 =
-D SPI_READ_FREQUENCY=20000000
-D USER_SETUP_LOADED=1
-D TOUCH_DRIVER=0x0610 ;STMPE610
+ ;-D SUPPORT_TRANSACTIONS ; Default on ESP32
+
+featherwing-24-v2 =
+ -D ILI9341_DRIVER=1
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=320
+ -D TFT_ROTATION=0 ; Use default, see TFT_ROTATION values
+ -D SPI_FREQUENCY=27000000
+ -D SPI_READ_FREQUENCY=20000000
+ -D USER_SETUP_LOADED=1
+ -D TOUCH_DRIVER=0x2007 ;TSC2007
;-D SUPPORT_TRANSACTIONS ; Default on ESP32
\ No newline at end of file
From c411f2c3b0f8822d6df0e66e3aa6dc8fb9388342 Mon Sep 17 00:00:00 2001
From: tbxMb
Date: Wed, 17 Jan 2024 14:21:18 +0100
Subject: [PATCH 046/135] Add esp32-s3-4848s040 to build.yaml
---
.github/workflows/build.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index abcec923..4c9a3ccf 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -60,6 +60,8 @@ jobs:
env: "wt32-sc01_4MB -e wt32-sc01_16MB -e wt-86-32-3zw1 -e wt32-sc01-plus_8MB -e wt32-sc01-plus_16MB"
- out: yeacreate
env: yeacreate-nscreen32
+ - out: guition
+ env: esp32-s3-4848S040
steps:
- uses: actions/checkout@v3
From 0218736d1d67f4ded98a7762a7f732518cd7cb9f Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 17 Jan 2024 14:29:19 +0100
Subject: [PATCH 047/135] Update .gitmodules
---
.gitmodules | 3 ---
1 file changed, 3 deletions(-)
diff --git a/.gitmodules b/.gitmodules
index 7706a667..c1197372 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,6 +2,3 @@
path = lib/freetype
url = https://github.com/fvanroie/freetype
-[submodule "lib/Adafruit_TSC2007"]
- path = lib/Adafruit_TSC2007
- url = https://github.com/adafruit/Adafruit_TSC2007.git
From 79f8ed0c3355f7e3a32ad22ed200d1540683328a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20St=C3=BCck?=
Date: Wed, 17 Jan 2024 10:11:52 -0500
Subject: [PATCH 048/135] Corrected environment names for huzzah32-v2-* boards
---
user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini | 2 +-
user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini b/user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini
index 29261680..457dc5aa 100644
--- a/user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini
+++ b/user_setups/esp32/huzzah32-v2-featherwing-24-v2.ini
@@ -5,7 +5,7 @@
; - TSC2007 touch controller ;
;***************************************************;
-[env:huzzah32-featherwing-24-v2]
+[env:huzzah32-v2-featherwing-24-v2]
extends = arduino_esp32_v2, flash_4mb
board = featheresp32
diff --git a/user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini b/user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini
index c2a6b4c2..1cb762f8 100644
--- a/user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini
+++ b/user_setups/esp32/huzzah32-v2-featherwing-35-v2.ini
@@ -5,7 +5,7 @@
; - TSC2007 touch controller ;
;***************************************************;
-[env:huzzah32-v2-featherwing-35]
+[env:huzzah32-v2-featherwing-35-v2]
extends = arduino_esp32_v2, flash_4mb
board = featheresp32
From db7c9ddf7bac85b3106010323c69b63e4774f14d Mon Sep 17 00:00:00 2001
From: TheHexaMaster <129121144+TheHexaMaster@users.noreply.github.com>
Date: Wed, 24 Jan 2024 12:12:59 +0100
Subject: [PATCH 049/135] Update sunton-esp32-s3-tft.ini
Fixed display flickering settings while using wifi for sunton-8048s070c_16MB display
---
user_setups/esp32s3/sunton-esp32-s3-tft.ini | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/user_setups/esp32s3/sunton-esp32-s3-tft.ini b/user_setups/esp32s3/sunton-esp32-s3-tft.ini
index 7cbb14d8..f9bbe24c 100644
--- a/user_setups/esp32s3/sunton-esp32-s3-tft.ini
+++ b/user_setups/esp32s3/sunton-esp32-s3-tft.ini
@@ -228,15 +228,15 @@ build_flags =
-D TFT_B4=4
; Panel Settings
-D TFT_HSYNC_POLARITY=0
- -D TFT_HSYNC_FRONT_PORCH=240 ; Maximum HSYNC Front Porch
- -D TFT_HSYNC_PULSE_WIDTH=30 ; Typical HSYNC Pulse Width
- -D TFT_HSYNC_BACK_PORCH=16 ; Typical HSYNC Back Porch
+ -D TFT_HSYNC_FRONT_PORCH=8 ; Maximum HSYNC Front Porch / 8 GOOD
+ -D TFT_HSYNC_PULSE_WIDTH=10 ; Typical HSYNC Pulse Width / 10 GOOD
+ -D TFT_HSYNC_BACK_PORCH=43 ; Typical HSYNC Back Porch / 43 GOOD
-D TFT_VSYNC_POLARITY=0
- -D TFT_VSYNC_FRONT_PORCH=32 ; Maximum VSYNC Front Porch
- -D TFT_VSYNC_PULSE_WIDTH=13 ; Typical VSYNC Pulse Width
- -D TFT_VSYNC_BACK_PORCH=10 ; Typical VSYNC Back Porch
+ -D TFT_VSYNC_FRONT_PORCH=8 ; Maximum VSYNC Front Porch / 8 GOOD
+ -D TFT_VSYNC_PULSE_WIDTH=8 ; Typical VSYNC Pulse Width / 8 GOOD
+ -D TFT_VSYNC_BACK_PORCH=12 ; Typical VSYNC Back Porch / 12 GOOD
-D TFT_PCLK_ACTIVE_NEG=1
- -D TFT_PREFER_SPEED=16000000 ; 1/2 of Typical DCLK Frequency
+ -D TFT_PREFER_SPEED=14500000 ; 1/2 of Typical DCLK Frequency / 12000000 GOOD
-D TFT_AUTO_FLUSH=1
; Touch Settings
-D TOUCH_WIDTH=800
@@ -250,4 +250,4 @@ build_flags =
-D I2C_TOUCH_FREQUENCY=400000
lib_deps =
${sunton-esp32-s3-tft.lib_deps}
- ${goodix.lib_deps}
\ No newline at end of file
+ ${goodix.lib_deps}
From 6bfdcd47a11c3cf43da7b32c1172f22daa415f24 Mon Sep 17 00:00:00 2001
From: hans boot
Date: Sat, 27 Jan 2024 14:03:59 +0100
Subject: [PATCH 050/135] Allow more time for http get
---
src/hasp/hasp_attribute.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp
index f0934fb7..105cefce 100644
--- a/src/hasp/hasp_attribute.cpp
+++ b/src/hasp/hasp_attribute.cpp
@@ -1346,7 +1346,7 @@ static hasp_attribute_type_t special_attribute_src(lv_obj_t* obj, const char* pa
#if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0
HTTPClient http;
http.begin(payload);
- http.setTimeout(1000);
+ http.setTimeout(5000);
http.setConnectTimeout(5000);
// const char* hdrs[] = {"Content-Type"};
From 03cd25edd27ed483666a858d4b606e4deb06078f Mon Sep 17 00:00:00 2001
From: hans boot
Date: Sat, 27 Jan 2024 14:40:48 +0100
Subject: [PATCH 051/135] re-enable idle_* scripts
---
src/hasp/hasp.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index 9187f4ad..34ba04f8 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -121,18 +121,21 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state()
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_LONG;
dispatch_idle_state(HASP_SLEEP_LONG);
+ dispatch_run_script(NULL, "L:/idle_long.cmd", TAG_MAIN);
}
} else if(sleepTimeShort > 0 && idle >= sleepTimeShort) {
if(hasp_sleep_state != HASP_SLEEP_SHORT) {
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_SHORT;
dispatch_idle_state(HASP_SLEEP_SHORT);
+ dispatch_run_script(NULL, "L:/idle_short.cmd", TAG_MAIN);
}
} else {
if(hasp_sleep_state != HASP_SLEEP_OFF) {
gui_hide_pointer(false);
hasp_sleep_state = HASP_SLEEP_OFF;
dispatch_idle_state(HASP_SLEEP_OFF);
+ dispatch_run_script(NULL, "L:/idle_off.cmd", TAG_MAIN);
}
}
}
From 8436bb6493066ce433c92cb35fc5dfabd1dfd22b Mon Sep 17 00:00:00 2001
From: hans boot
Date: Sat, 27 Jan 2024 14:45:49 +0100
Subject: [PATCH 052/135] revert re-enable idle_* scripts
---
src/hasp/hasp.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index 34ba04f8..9187f4ad 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -121,21 +121,18 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state()
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_LONG;
dispatch_idle_state(HASP_SLEEP_LONG);
- dispatch_run_script(NULL, "L:/idle_long.cmd", TAG_MAIN);
}
} else if(sleepTimeShort > 0 && idle >= sleepTimeShort) {
if(hasp_sleep_state != HASP_SLEEP_SHORT) {
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_SHORT;
dispatch_idle_state(HASP_SLEEP_SHORT);
- dispatch_run_script(NULL, "L:/idle_short.cmd", TAG_MAIN);
}
} else {
if(hasp_sleep_state != HASP_SLEEP_OFF) {
gui_hide_pointer(false);
hasp_sleep_state = HASP_SLEEP_OFF;
dispatch_idle_state(HASP_SLEEP_OFF);
- dispatch_run_script(NULL, "L:/idle_off.cmd", TAG_MAIN);
}
}
}
From 889682d49b30c7e3f9611aa164ce199a79953ec2 Mon Sep 17 00:00:00 2001
From: hans boot
Date: Sat, 27 Jan 2024 15:05:34 +0100
Subject: [PATCH 053/135] re-enable idle scripts
---
src/hasp/hasp.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index 9187f4ad..34ba04f8 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -121,18 +121,21 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state()
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_LONG;
dispatch_idle_state(HASP_SLEEP_LONG);
+ dispatch_run_script(NULL, "L:/idle_long.cmd", TAG_MAIN);
}
} else if(sleepTimeShort > 0 && idle >= sleepTimeShort) {
if(hasp_sleep_state != HASP_SLEEP_SHORT) {
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_SHORT;
dispatch_idle_state(HASP_SLEEP_SHORT);
+ dispatch_run_script(NULL, "L:/idle_short.cmd", TAG_MAIN);
}
} else {
if(hasp_sleep_state != HASP_SLEEP_OFF) {
gui_hide_pointer(false);
hasp_sleep_state = HASP_SLEEP_OFF;
dispatch_idle_state(HASP_SLEEP_OFF);
+ dispatch_run_script(NULL, "L:/idle_off.cmd", TAG_MAIN);
}
}
}
From c190cf94b54e551eb3adc38d70ceb7fd63de007e Mon Sep 17 00:00:00 2001
From: hans boot
Date: Sat, 27 Jan 2024 15:51:33 +0100
Subject: [PATCH 054/135] update to TAG_HASP, as requested
---
src/hasp/hasp.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index 34ba04f8..1a3336ee 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -121,21 +121,21 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state()
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_LONG;
dispatch_idle_state(HASP_SLEEP_LONG);
- dispatch_run_script(NULL, "L:/idle_long.cmd", TAG_MAIN);
+ dispatch_run_script(NULL, "L:/idle_long.cmd", TAG_HASP);
}
} else if(sleepTimeShort > 0 && idle >= sleepTimeShort) {
if(hasp_sleep_state != HASP_SLEEP_SHORT) {
gui_hide_pointer(true);
hasp_sleep_state = HASP_SLEEP_SHORT;
dispatch_idle_state(HASP_SLEEP_SHORT);
- dispatch_run_script(NULL, "L:/idle_short.cmd", TAG_MAIN);
+ dispatch_run_script(NULL, "L:/idle_short.cmd", TAG_HASP);
}
} else {
if(hasp_sleep_state != HASP_SLEEP_OFF) {
gui_hide_pointer(false);
hasp_sleep_state = HASP_SLEEP_OFF;
dispatch_idle_state(HASP_SLEEP_OFF);
- dispatch_run_script(NULL, "L:/idle_off.cmd", TAG_MAIN);
+ dispatch_run_script(NULL, "L:/idle_off.cmd", TAG_HASP);
}
}
}
From 91faf614749757a7c122386afe5022e0c21bf727 Mon Sep 17 00:00:00 2001
From: Ryan Press
Date: Mon, 29 Jan 2024 03:15:29 -0800
Subject: [PATCH 055/135] On ESP32 fade the backlight
---
src/dev/esp32/esp32.cpp | 28 +++++++++++++++++++++-------
src/dev/esp32/esp32.h | 4 +++-
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp
index 88d34460..049f3c1b 100644
--- a/src/dev/esp32/esp32.cpp
+++ b/src/dev/esp32/esp32.cpp
@@ -9,6 +9,7 @@
#include "esp_system.h"
#include // needed to get the ResetInfo
#include "driver/adc.h"
+#include "driver/ledc.h"
#include "esp_adc_cal.h"
#include "esp_efuse.h"
@@ -253,7 +254,8 @@ void Esp32Device::set_backlight_pin(uint8_t pin)
ledcSetup(BACKLIGHT_CHANNEL, BACKLIGHT_FREQUENCY, 10);
#endif
ledcAttachPin(pin, BACKLIGHT_CHANNEL);
- update_backlight();
+ ledc_fade_func_install(0);
+ update_backlight(false);
} else {
LOG_VERBOSE(TAG_GUI, F("Backlight : Pin not set"));
}
@@ -262,7 +264,7 @@ void Esp32Device::set_backlight_pin(uint8_t pin)
void Esp32Device::set_backlight_invert(bool invert)
{
_backlight_invert = invert;
- update_backlight();
+ update_backlight(false);
}
bool Esp32Device::get_backlight_invert()
@@ -273,7 +275,7 @@ bool Esp32Device::get_backlight_invert()
void Esp32Device::set_backlight_level(uint8_t level)
{
_backlight_level = level;
- update_backlight();
+ update_backlight(true);
}
uint8_t Esp32Device::get_backlight_level()
@@ -284,7 +286,7 @@ uint8_t Esp32Device::get_backlight_level()
void Esp32Device::set_backlight_power(bool power)
{
_backlight_power = power;
- update_backlight();
+ update_backlight(true);
}
bool Esp32Device::get_backlight_power()
@@ -292,18 +294,30 @@ bool Esp32Device::get_backlight_power()
return _backlight_power != 0;
}
-void Esp32Device::update_backlight()
+void Esp32Device::update_backlight(bool fade)
{
+ static uint32_t last_duty = 0;
if(_backlight_pin < GPIO_NUM_MAX) {
#if !defined(CONFIG_IDF_TARGET_ESP32S2)
uint32_t duty = _backlight_power ? map(_backlight_level, 0, 255, 0, 1023) : 0;
if(_backlight_invert) duty = 1023 - duty;
- ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ if(fade) {
+ ledcWrite(BACKLIGHT_CHANNEL, last_duty); // this will stop an in-progress fade
+ ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE, (ledc_channel_t) BACKLIGHT_CHANNEL, duty, BACKLIGHT_FADEMS, LEDC_FADE_NO_WAIT);
+ } else {
+ ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ }
#else
uint32_t duty = _backlight_power ? map(_backlight_level, 0, 255, 0, 1023) : 0;
if(_backlight_invert) duty = 1023 - duty;
- ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ if(fade) {
+ ledcWrite(BACKLIGHT_CHANNEL, last_duty); // this will stop an in-progress fade
+ ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE, (ledc_channel_t) BACKLIGHT_CHANNEL, duty, BACKLIGHT_FADEMS, LEDC_FADE_NO_WAIT);
+ } else {
+ ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ }
#endif
+ last_duty = duty;
}
// haspTft.tft.writecommand(0x53); // Write CTRL Display
diff --git a/src/dev/esp32/esp32.h b/src/dev/esp32/esp32.h
index 7dec242d..660d0df8 100644
--- a/src/dev/esp32/esp32.h
+++ b/src/dev/esp32/esp32.h
@@ -13,6 +13,8 @@
#define BACKLIGHT_FREQUENCY 20000
#endif
+#define BACKLIGHT_FADEMS 200
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -67,7 +69,7 @@ class Esp32Device : public BaseDevice {
uint8_t _backlight_power;
uint8_t _backlight_invert;
- void update_backlight();
+ void update_backlight(bool fade);
};
} // namespace dev
From e95b91615703edd6514ff3c7d01be7b74fc05b60 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 2 Feb 2024 16:36:57 +0100
Subject: [PATCH 056/135] Downgrade to Tasmota core 2023.10.02
---
CHANGELOG.md | 1 +
platformio.ini | 2 +-
src/hasp/hasp_mem.cpp | 5 +++++
src/sys/net/hasp_time.cpp | 18 ++++++++++++++----
src/sys/svc/hasp_ota.cpp | 11 ++++++-----
user_setups/esp32/_esp32.ini | 4 +++-
6 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16a22aef..fa53d7b7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,6 +46,7 @@
- Add Sunton ESP32-2432S028R ESP32-3248S035C ESP32-3248S035R
- Add support for Wireless-Tag WT32-SC01 Plus and WT32S3-86V
- Deprecate support for WT-86-32-3ZW1 with ESP32-S2
+- Fade backlight on ESP32 devices (thanks @presslab-us)
## Bug fixes
- Fix for first touch not working properly
diff --git a/platformio.ini b/platformio.ini
index c28cea8c..62acd29b 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -75,7 +75,7 @@ build_flags =
-D HASP_VER_MAJ=0
-D HASP_VER_MIN=7
;-D HASP_VER_REV=4
- -D HASP_VER_REV=0-rc9
+ -D HASP_VER_REV=0-rc10
;-D HASP_VER_REV=4-rc1
${override.build_flags}
diff --git a/src/hasp/hasp_mem.cpp b/src/hasp/hasp_mem.cpp
index 51942271..f0859a36 100644
--- a/src/hasp/hasp_mem.cpp
+++ b/src/hasp/hasp_mem.cpp
@@ -53,6 +53,11 @@ void* lodepng_malloc(size_t size)
if(size > LODEPNG_MAX_ALLOC) return 0;
#endif
+ // void* ptr = hasp_malloc(size);
+ // if(ptr) return ptr;
+
+ // /* PSram was full retry after clearing cache*/
+ // lv_img_cache_invalidate_src(NULL);
return hasp_malloc(size);
}
diff --git a/src/sys/net/hasp_time.cpp b/src/sys/net/hasp_time.cpp
index 37beca4e..0087a35c 100644
--- a/src/sys/net/hasp_time.cpp
+++ b/src/sys/net/hasp_time.cpp
@@ -18,6 +18,7 @@
#include "Preferences.h"
#include "nvs.h"
#include "nvs_flash.h"
+#include "esp_sntp.h"
#endif
#if defined(ARDUINO_ARCH_ESP32)
@@ -26,6 +27,11 @@ String mytz((char*)0);
String ntp1((char*)0);
String ntp2((char*)0);
String ntp3((char*)0);
+
+void timeSyncCallback(struct timeval* tv)
+{
+ LOG_VERBOSE(TAG_TIME, "NTP Synced: %s", ctime(&tv->tv_sec));
+}
#endif
void timeSetup()
@@ -41,15 +47,19 @@ void timeSetup()
String zone((char*)0);
zone = preferences.getString("zone", TIMEZONE);
- mytz = time_zone_to_possix(zone.c_str());
- ntp1 = preferences.getString("ntp1", NTPSERVER1);
- ntp2 = preferences.getString("ntp2", NTPSERVER2);
- ntp3 = preferences.getString("ntp3", NTPSERVER3);
+ mytz = time_zone_to_possix(zone.c_str());
+ ntp1 = preferences.getString("ntp1", NTPSERVER1);
+ ntp2 = preferences.getString("ntp2", NTPSERVER2);
+ ntp3 = preferences.getString("ntp3", NTPSERVER3);
+ bool enable = preferences.getBool("enable", true);
+ bool dhcp = preferences.getBool("dhcp", true);
LOG_VERBOSE(TAG_TIME, F("%s => %s"), zone.c_str(), mytz.c_str());
LOG_VERBOSE(TAG_TIME, F("NTP: %s %s %s"), ntp1.c_str(), ntp2.c_str(), ntp3.c_str());
+ sntp_set_time_sync_notification_cb(timeSyncCallback);
configTzTime(mytz.c_str(), ntp1.c_str(), ntp2.c_str(), ntp3.c_str());
+ sntp_servermode_dhcp(enable && dhcp ? 1 : 0);
preferences.end();
#endif
}
diff --git a/src/sys/svc/hasp_ota.cpp b/src/sys/svc/hasp_ota.cpp
index 48d9fb9e..f4c18f12 100644
--- a/src/sys/svc/hasp_ota.cpp
+++ b/src/sys/svc/hasp_ota.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
#ifndef HASP_ARDUINOOTA_PORT
#define HASP_ARDUINOOTA_PORT 3232
@@ -76,14 +77,14 @@ extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_b
#endif // ARDUINO_ARCH_ESP32
static WiFiClientSecure secureClient;
-std::string otaUrl = "http://ota.netwize.be";
+/*std::string otaUrl = "http://ota.netwize.be";*/
uint16_t arduinoOtaPort = HASP_ARDUINOOTA_PORT;
int8_t otaPrecentageComplete = -1;
bool otaUpdateCheck()
{ // firmware update check
- WiFiClientSecure wifiUpdateClientSecure;
+ /*WiFiClientSecure wifiUpdateClientSecure;
HTTPClient updateClient;
LOG_TRACE(TAG_OTA, F(D_OTA_CHECK_UPDATE), otaUrl.c_str());
@@ -115,7 +116,7 @@ bool otaUpdateCheck()
// }
}
LOG_VERBOSE(TAG_OTA, F(D_OTA_CHECK_COMPLETE));
- }
+ }*/
return true;
}
@@ -210,9 +211,9 @@ void otaSetup(void)
secureClient.setTimeout(12); // timeout argument is defined in seconds
#if HASP_USE_ARDUINOOTA > 0
- if(strlen(otaUrl.c_str())) {
+ /*if(strlen(otaUrl.c_str())) {
LOG_INFO(TAG_OTA, otaUrl.c_str());
- }
+ }*/
if(arduinoOtaPort > 0) {
ArduinoOTA.onStart(ota_on_start);
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index 5c17abc8..a7440eae 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -141,7 +141,9 @@ extends = esp32
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+;;;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
+platform = https://github.com/Jason2866/platform-espressif32/releases/download/2023.10.02/platform-espressif32-2023.10.02.zip
lib_ignore =
${esp32.lib_ignore}
From 9a97c35df1c69ec5f6677aaccf539d647646b98d Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 2 Feb 2024 18:26:42 +0100
Subject: [PATCH 057/135] Update Copyright to include 2024
---
LICENSE | 2 +-
platformio.ini | 2 +-
src/dev/esp32/esp32.h | 2 +-
src/drv/tft/tft_driver_arduinogfx.cpp | 2 +-
src/drv/tft/tft_driver_lovyangfx.cpp | 2 +-
src/drv/touch/touch_driver_gt911.cpp | 2 +-
src/drv/touch/touch_driver_gt911.h | 2 +-
src/drv/touch/touch_driver_tftespi.h | 2 +-
src/hasp/hasp.cpp | 2 +-
src/hasp/hasp.h | 2 +-
src/hasp/hasp_attribute.cpp | 2 +-
src/hasp/hasp_dispatch.cpp | 2 +-
src/hasp/hasp_font.cpp | 2 +-
src/hasp/hasp_nvs.cpp | 2 +-
src/hasp/hasp_nvs.h | 2 +-
src/hasp/hasp_object.h | 2 +-
src/hasp/hasp_task.cpp | 2 +-
src/hasp_config.cpp | 2 +-
src/hasp_config.h | 2 +-
src/hasp_debug.cpp | 2 +-
src/hasp_filesystem.cpp | 2 +-
src/hasp_filesystem.h | 2 +-
src/hasp_gui.cpp | 2 +-
src/hasp_oobe.cpp | 2 +-
src/hasp_oobe.h | 2 +-
src/hasplib.h | 2 +-
src/main_arduino.cpp | 2 +-
src/mqtt/hasp_mqtt.h | 2 +-
src/mqtt/hasp_mqtt_esp.cpp | 2 +-
src/mqtt/hasp_mqtt_paho_single.cpp | 2 +-
src/mqtt/hasp_mqtt_pubsubclient.cpp | 2 +-
src/sys/gpio/hasp_gpio.cpp | 2 +-
src/sys/gpio/hasp_gpio.h | 2 +-
src/sys/net/hasp_time.cpp | 2 +-
src/sys/net/hasp_time.h | 2 +-
src/sys/net/hasp_wifi.cpp | 2 +-
src/sys/net/hasp_wifi.h | 2 +-
src/sys/svc/hasp_console.cpp | 2 +-
src/sys/svc/hasp_console.h | 2 +-
src/sys/svc/hasp_ftp.cpp | 2 +-
src/sys/svc/hasp_ftp.h | 2 +-
src/sys/svc/hasp_http.cpp | 4 ++--
src/sys/svc/hasp_http.h | 2 +-
src/sys/svc/hasp_http_async.cpp | 2 +-
src/sys/svc/hasp_mdns.h | 2 +-
src/sys/svc/hasp_ota.cpp | 2 +-
src/sys/svc/hasp_telnet.cpp | 2 +-
47 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/LICENSE b/LICENSE
index c212742b..85f9577f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019-2023 Francis Van Roie
+Copyright (c) 2019-2024 Francis Van Roie
Copyright (c) 2018-2019 Allen Derusha allen@derusha.org
Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/platformio.ini b/platformio.ini
index ba38d320..7d61dc60 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -1,4 +1,4 @@
-; MIT License - Copyright (c) 2019-2023 Francis Van Roie
+; MIT License - Copyright (c) 2019-2024 Francis Van Roie
; For full license information read the LICENSE file in the project folder
;
; PlatformIO Project Configuration File
diff --git a/src/dev/esp32/esp32.h b/src/dev/esp32/esp32.h
index 660d0df8..e3a8bd17 100644
--- a/src/dev/esp32/esp32.h
+++ b/src/dev/esp32/esp32.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_ESP32_H
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index ff6f0835..c946120a 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(ARDUINO) && defined(HASP_USE_ARDUINOGFX)
diff --git a/src/drv/tft/tft_driver_lovyangfx.cpp b/src/drv/tft/tft_driver_lovyangfx.cpp
index d6ba0892..e4f73ea4 100644
--- a/src/drv/tft/tft_driver_lovyangfx.cpp
+++ b/src/drv/tft/tft_driver_lovyangfx.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(ARDUINO) && defined(LGFX_USE_V1)
diff --git a/src/drv/touch/touch_driver_gt911.cpp b/src/drv/touch/touch_driver_gt911.cpp
index c3da9ef0..1ff67cad 100644
--- a/src/drv/touch/touch_driver_gt911.cpp
+++ b/src/drv/touch/touch_driver_gt911.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(ARDUINO) && (TOUCH_DRIVER == 0x0911) && !defined(HASP_USE_LGFX_TOUCH)
diff --git a/src/drv/touch/touch_driver_gt911.h b/src/drv/touch/touch_driver_gt911.h
index ac5447d4..983e696e 100644
--- a/src/drv/touch/touch_driver_gt911.h
+++ b/src/drv/touch/touch_driver_gt911.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_GT911_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_driver_tftespi.h b/src/drv/touch/touch_driver_tftespi.h
index 4762844a..fc5895c8 100644
--- a/src/drv/touch/touch_driver_tftespi.h
+++ b/src/drv/touch/touch_driver_tftespi.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TFTESPI_TOUCH_DRIVER_H
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index 1a3336ee..e2e49f0f 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/hasp/hasp.h b/src/hasp/hasp.h
index 4b9b5217..bc786c50 100644
--- a/src/hasp/hasp.h
+++ b/src/hasp/hasp.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_H
diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp
index 105cefce..f99a6e14 100644
--- a/src/hasp/hasp_attribute.cpp
+++ b/src/hasp/hasp_attribute.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 3ffe667f..f478fa62 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include
diff --git a/src/hasp/hasp_font.cpp b/src/hasp/hasp_font.cpp
index 1f50c81a..98a20c46 100644
--- a/src/hasp/hasp_font.cpp
+++ b/src/hasp/hasp_font.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include
diff --git a/src/hasp/hasp_nvs.cpp b/src/hasp/hasp_nvs.cpp
index a2fd0b23..1ce54e93 100644
--- a/src/hasp/hasp_nvs.cpp
+++ b/src/hasp/hasp_nvs.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifdef ESP32
diff --git a/src/hasp/hasp_nvs.h b/src/hasp/hasp_nvs.h
index 809f65ca..ef87e5a6 100644
--- a/src/hasp/hasp_nvs.h
+++ b/src/hasp/hasp_nvs.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_NVS_H
diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h
index cd1a0a20..5bfe157a 100644
--- a/src/hasp/hasp_object.h
+++ b/src/hasp/hasp_object.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_OBJECT_H
diff --git a/src/hasp/hasp_task.cpp b/src/hasp/hasp_task.cpp
index 23fb2027..a6d01900 100644
--- a/src/hasp/hasp_task.cpp
+++ b/src/hasp/hasp_task.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index 09ceea05..d3e55b1e 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if HASP_USE_CONFIG > 0
diff --git a/src/hasp_config.h b/src/hasp_config.h
index 7effe4cd..8a667ed6 100644
--- a/src/hasp_config.h
+++ b/src/hasp_config.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if HASP_USE_CONFIG > 0
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index 52977625..672c0ba2 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/hasp_filesystem.cpp b/src/hasp_filesystem.cpp
index 56c96cc3..ac39a344 100644
--- a/src/hasp_filesystem.cpp
+++ b/src/hasp_filesystem.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifdef ARDUINO
diff --git a/src/hasp_filesystem.h b/src/hasp_filesystem.h
index 3bb3d490..0299fc7f 100644
--- a/src/hasp_filesystem.h
+++ b/src/hasp_filesystem.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_FILESYSTEM_H
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 3d05a80e..b69a1ee5 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/hasp_oobe.cpp b/src/hasp_oobe.cpp
index f816afbd..1e9cb932 100644
--- a/src/hasp_oobe.cpp
+++ b/src/hasp_oobe.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if HASP_USE_CONFIG > 0
diff --git a/src/hasp_oobe.h b/src/hasp_oobe.h
index 931ab220..b5b5ad0e 100644
--- a/src/hasp_oobe.h
+++ b/src/hasp_oobe.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if HASP_USE_CONFIG > 0
diff --git a/src/hasplib.h b/src/hasplib.h
index 1cd8691b..05ce613c 100644
--- a/src/hasplib.h
+++ b/src/hasplib.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifdef ARDUINO
diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp
index 86b53902..8fc378b2 100644
--- a/src/main_arduino.cpp
+++ b/src/main_arduino.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if !(defined(WINDOWS) || defined(POSIX))
diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h
index 63e9ed9e..f5d57196 100644
--- a/src/mqtt/hasp_mqtt.h
+++ b/src/mqtt/hasp_mqtt.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_MQTT_H
diff --git a/src/mqtt/hasp_mqtt_esp.cpp b/src/mqtt/hasp_mqtt_esp.cpp
index 0b1c42ea..9fbac1e0 100644
--- a/src/mqtt/hasp_mqtt_esp.cpp
+++ b/src/mqtt/hasp_mqtt_esp.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_conf.h"
diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp
index 0811e29d..17804f89 100644
--- a/src/mqtt/hasp_mqtt_paho_single.cpp
+++ b/src/mqtt/hasp_mqtt_paho_single.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* Single threaded synchronous paho client */
diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp
index 8821fc59..29e11b2f 100644
--- a/src/mqtt/hasp_mqtt_pubsubclient.cpp
+++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_conf.h"
diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp
index b27e3594..0094f80b 100644
--- a/src/sys/gpio/hasp_gpio.cpp
+++ b/src/sys/gpio/hasp_gpio.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "lv_conf.h" // For timing defines
diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h
index 43a68376..df093048 100644
--- a/src/sys/gpio/hasp_gpio.h
+++ b/src/sys/gpio/hasp_gpio.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_GPIO_H
diff --git a/src/sys/net/hasp_time.cpp b/src/sys/net/hasp_time.cpp
index 0087a35c..3ad66a0f 100644
--- a/src/sys/net/hasp_time.cpp
+++ b/src/sys/net/hasp_time.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include
diff --git a/src/sys/net/hasp_time.h b/src/sys/net/hasp_time.h
index 5d1b3e26..0448fd29 100644
--- a/src/sys/net/hasp_time.h
+++ b/src/sys/net/hasp_time.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TIME_H
diff --git a/src/sys/net/hasp_wifi.cpp b/src/sys/net/hasp_wifi.cpp
index 36f69b26..dc6041e7 100644
--- a/src/sys/net/hasp_wifi.cpp
+++ b/src/sys/net/hasp_wifi.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include
diff --git a/src/sys/net/hasp_wifi.h b/src/sys/net/hasp_wifi.h
index 1418efa0..03c98e06 100644
--- a/src/sys/net/hasp_wifi.h
+++ b/src/sys/net/hasp_wifi.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_WIFI_H
diff --git a/src/sys/svc/hasp_console.cpp b/src/sys/svc/hasp_console.cpp
index 9e7f1632..66312569 100644
--- a/src/sys/svc/hasp_console.cpp
+++ b/src/sys/svc/hasp_console.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/sys/svc/hasp_console.h b/src/sys/svc/hasp_console.h
index ac2e4223..10c17b69 100644
--- a/src/sys/svc/hasp_console.h
+++ b/src/sys/svc/hasp_console.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_CONSOLE_H
diff --git a/src/sys/svc/hasp_ftp.cpp b/src/sys/svc/hasp_ftp.cpp
index 0e1e8ef3..9b1e11ac 100644
--- a/src/sys/svc/hasp_ftp.cpp
+++ b/src/sys/svc/hasp_ftp.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/sys/svc/hasp_ftp.h b/src/sys/svc/hasp_ftp.h
index 11571a95..35f6b69f 100644
--- a/src/sys/svc/hasp_ftp.h
+++ b/src/sys/svc/hasp_ftp.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_FTP_H
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index 6139b177..e3737309 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
@@ -920,7 +920,7 @@ static void http_handle_about()
-openHASP Copyright 2019-2023 Francis Van RoieMIT License
+openHASP Copyright 2019-2024 Francis Van RoieMIT License
diff --git a/src/sys/svc/hasp_http.h b/src/sys/svc/hasp_http.h
index bdbe13c4..388bb67c 100644
--- a/src/sys/svc/hasp_http.h
+++ b/src/sys/svc/hasp_http.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_HTTP_H
diff --git a/src/sys/svc/hasp_http_async.cpp b/src/sys/svc/hasp_http_async.cpp
index d73f112f..2c8ec707 100644
--- a/src/sys/svc/hasp_http_async.cpp
+++ b/src/sys/svc/hasp_http_async.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
//#include "webServer.h"
diff --git a/src/sys/svc/hasp_mdns.h b/src/sys/svc/hasp_mdns.h
index 2f472814..82893e16 100644
--- a/src/sys/svc/hasp_mdns.h
+++ b/src/sys/svc/hasp_mdns.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_MDNS_H
diff --git a/src/sys/svc/hasp_ota.cpp b/src/sys/svc/hasp_ota.cpp
index f4c18f12..d42ccf61 100644
--- a/src/sys/svc/hasp_ota.cpp
+++ b/src/sys/svc/hasp_ota.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
diff --git a/src/sys/svc/hasp_telnet.cpp b/src/sys/svc/hasp_telnet.cpp
index da8f2e85..1f3d8a09 100644
--- a/src/sys/svc/hasp_telnet.cpp
+++ b/src/sys/svc/hasp_telnet.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
From 71c20b88d6bfa37a6d2a438df726f9a1610649cf Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 2 Feb 2024 19:46:55 +0100
Subject: [PATCH 058/135] Update to ace.js v1.32.5
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 2d2eec60..4a38aacd 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
+openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 44b532f3..32b4159e 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.0")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.5")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 1364795f98c5e64e5958728df2b3e2d727da779b Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 5 Feb 2024 19:15:22 +0100
Subject: [PATCH 059/135] Downgrade to Tasmota core 2023.10.02
---
user_setups/esp32s2/_esp32s2.ini | 3 ++-
user_setups/esp32s3/_esp32s3.ini | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/user_setups/esp32s2/_esp32s2.ini b/user_setups/esp32s2/_esp32s2.ini
index f21817b8..88bcf8a7 100644
--- a/user_setups/esp32s2/_esp32s2.ini
+++ b/user_setups/esp32s2/_esp32s2.ini
@@ -83,7 +83,8 @@ platform = https://github.com/tasmota/platform-espressif32/releases/download/202
[arduino_esp32s2-solo_v2]
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.01.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+platform = https://github.com/Jason2866/platform-espressif32/releases/download/2023.10.02/platform-espressif32-2023.10.02.zip
board_build.embed_files = ${esp32.board_build.embed_files}
board_build.filesystem = littlefs
; ----- crash reporter
diff --git a/user_setups/esp32s3/_esp32s3.ini b/user_setups/esp32s3/_esp32s3.ini
index 198975ba..13f7a122 100644
--- a/user_setups/esp32s3/_esp32s3.ini
+++ b/user_setups/esp32s3/_esp32s3.ini
@@ -17,4 +17,5 @@ extends = esp32s3
framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.05.01/platform-espressif32.zip
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+platform = https://github.com/Jason2866/platform-espressif32/releases/download/2023.10.02/platform-espressif32-2023.10.02.zip
\ No newline at end of file
From b1716fbca1e4d7d8c84e80fb958506fee0f7dc69 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 6 Feb 2024 02:34:26 +0100
Subject: [PATCH 060/135] Prevent concurrently running scripts
---
src/hasp/hasp_dispatch.cpp | 63 +++++++++++++++++++++++++++++++++++---
src/hasp/hasp_dispatch.h | 9 ++++++
2 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index f478fa62..2dacba77 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -269,6 +269,42 @@ static void dispatch_output(const char* topic, const char* payload)
#endif
}
+// static inline size_t dispatch_msg_length(size_t len)
+// {
+// return (len / 64) * 64 + 64;
+// }
+
+// void dispatch_enqueue_message(const char* topic, const char* payload, size_t payload_len, uint8_t source)
+// {
+// // Add new message to the queue
+// dispatch_message_t data;
+
+// size_t topic_len = strlen(topic);
+// data.topic = (char*)hasp_calloc(sizeof(char), dispatch_msg_length(topic_len + 1));
+// data.payload = (char*)hasp_calloc(sizeof(char), dispatch_msg_length(payload_len + 1));
+// data.source = source;
+
+// if(!data.topic || !data.payload) {
+// LOG_ERROR(TAG_MQTT_RCV, D_ERROR_OUT_OF_MEMORY);
+// hasp_free(data.topic);
+// hasp_free(data.payload);
+// return;
+// }
+// memcpy(data.topic, topic, topic_len);
+// memcpy(data.payload, payload, payload_len);
+
+// {
+// size_t attempt = 0;
+// while(xQueueSend(message_queue, &data, (TickType_t)0) == errQUEUE_FULL && attempt < 100) {
+// delay(5);
+// attempt++;
+// };
+// if(attempt >= 100) {
+// LOG_ERROR(TAG_MSGR, D_ERROR_OUT_OF_MEMORY);
+// }
+// }
+// }
+
// objectattribute=value
static void dispatch_command(const char* topic, const char* payload, bool update, uint8_t source)
{
@@ -765,6 +801,11 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
return;
}
+ if(!gui_acquire(pdMS_TO_TICKS(500))) {
+ LOG_ERROR(TAG_MSGR, F(D_FILE_LOAD_FAILED), payload);
+ return;
+ }
+
// char buffer[512]; // use stack
String buffer((char*)0); // use heap
buffer.reserve(512);
@@ -788,6 +829,7 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
}
}
+ gui_release();
cmdfile.close();
LOG_INFO(TAG_MSGR, F(D_FILE_LOADED), payload);
#else
@@ -1321,8 +1363,8 @@ void dispatch_current_state(uint8_t source)
bool dispatch_factory_reset()
{
bool formatted = true;
- bool erased = true;
- bool cleared = true;
+ bool erased = true;
+ bool cleared = true;
#if ESP32
erased = nvs_clear_user_config();
@@ -1519,7 +1561,20 @@ void dispatchSetup()
}
IRAM_ATTR void dispatchLoop()
-{}
+{
+ // UBaseType_t msg_count = uxQueueMessagesWaiting(message_queue));
+ // if(msg_count == 0) return;
+
+ // dispatch_message_t data;
+ // while(xQueueReceive(message_queue, &data, (TickType_t)0)) {
+ // LOG_WARNING(TAG_MSGR, F("[%d] QUE %s => %s"), msg_count, data.topic, data.payload);
+ // size_t length = strlen(data.payload);
+ // dispatch_topic_payload(data.topic, data.payload, length > 0, data.source);
+ // hasp_free(data.topic);
+ // hasp_free(data.payload);
+ // // delay(1);
+ // }
+}
#if 1 || ARDUINO
void dispatchEverySecond()
@@ -1551,7 +1606,7 @@ void everySecond()
{
if(dispatch_setings.teleperiod > 0) {
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
- std::chrono::seconds elapsed = std::chrono::duration_cast(end - begin);
+ std::chrono::seconds elapsed = std::chrono::duration_cast(end - begin);
if(elapsed.count() >= dispatch_setings.teleperiod) {
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h
index 245da30c..13967871 100644
--- a/src/hasp/hasp_dispatch.h
+++ b/src/hasp/hasp_dispatch.h
@@ -5,6 +5,15 @@
#define HASP_DISPATCH_H
#include "hasplib.h"
+// #include "freertos/queue.h"
+
+// QueueHandle_t message_queue;
+// typedef struct
+// {
+// char* topic; //[64];
+// char* payload; //[512];
+// uint source;
+// } dispatch_message_t;
struct dispatch_conf_t
{
From a7b558eb3381012a182c5ceed75a5bd9d1d29b31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Tue, 6 Feb 2024 19:52:00 +0100
Subject: [PATCH 061/135] Rename SDL2 port to PC
---
src/{main_sdl2.cpp => main_pc.cpp} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/{main_sdl2.cpp => main_pc.cpp} (100%)
diff --git a/src/main_sdl2.cpp b/src/main_pc.cpp
similarity index 100%
rename from src/main_sdl2.cpp
rename to src/main_pc.cpp
From 246f5e3ac270f1709f9beac2e49af6ab6f7ccfb7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Tue, 6 Feb 2024 19:52:23 +0100
Subject: [PATCH 062/135] Only enable SDL2 driver with USE_MONITOR
---
include/hasp_conf.h | 4 ++++
src/dev/win32/hasp_win32.cpp | 8 +++++++-
src/dev/win32/hasp_win32.h | 2 +-
src/drv/tft/tft_driver.h | 2 +-
src/drv/tft/tft_driver_sdl2.cpp | 4 ++--
src/drv/tft/tft_driver_sdl2.h | 2 +-
src/hasp_gui.cpp | 2 +-
src/main_pc.cpp | 18 +++++++++++-------
8 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index 448b66a3..ef832b69 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -371,7 +371,9 @@ static WiFiSpiClass WiFi;
#include
#include
#include
+#if USE_MONITOR
#include
+#endif
#define snprintf_P snprintf
#define memcpy_P memcpy
@@ -380,7 +382,9 @@ static WiFiSpiClass WiFi;
#define strcpy_P strcpy
#define strstr_P strstr
#define halRestartMcu()
+#if USE_MONITOR
#define millis SDL_GetTicks
+#endif
#define DEC 10
#define HEX 16
diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp
index 61fce87d..f089307c 100644
--- a/src/dev/win32/hasp_win32.cpp
+++ b/src/dev/win32/hasp_win32.cpp
@@ -11,7 +11,9 @@
#include "hasp_conf.h"
#include "hasp_debug.h"
+#if USE_MONITOR
#include "display/monitor.h"
+#endif
namespace dev {
@@ -48,8 +50,10 @@ const char* Win32Device::get_hostname()
void Win32Device::set_hostname(const char* hostname)
{
_hostname = hostname;
+#if USE_MONITOR
monitor_title(hostname);
// SDL_SetWindowTitle(monitor.window, hostname);
+#endif
}
const char* Win32Device::get_core_version()
{
@@ -112,7 +116,9 @@ void Win32Device::update_backlight()
{
uint8_t level = _backlight_power ? _backlight_level : 0;
if(_backlight_invert) level = 255 - level;
+#if USE_MONITOR
monitor_backlight(level);
+#endif
}
size_t Win32Device::get_free_max_block()
@@ -152,4 +158,4 @@ long Win32Device::get_uptime()
dev::Win32Device haspDevice;
-#endif // WINDOWS
\ No newline at end of file
+#endif // WINDOWS
diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h
index 3c2edb23..0c64e1f9 100644
--- a/src/dev/win32/hasp_win32.h
+++ b/src/dev/win32/hasp_win32.h
@@ -96,4 +96,4 @@ extern dev::Win32Device haspDevice;
#endif // WINDOWS
-#endif // HASP_DEVICE_WINDOWS_H
\ No newline at end of file
+#endif // HASP_DEVICE_WINDOWS_H
diff --git a/src/drv/tft/tft_driver.h b/src/drv/tft/tft_driver.h
index 913be18f..0c0d5814 100644
--- a/src/drv/tft/tft_driver.h
+++ b/src/drv/tft/tft_driver.h
@@ -77,7 +77,7 @@ class BaseTft {
#elif defined(STM32F7)
#warning Building for STM32F7xx Tfts
#include "tft_driver_tftespi.h"
-#elif defined(WINDOWS) || defined(POSIX)
+#elif USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
// #warning Building for SDL2
#include "tft_driver_sdl2.h"
#else
diff --git a/src/drv/tft/tft_driver_sdl2.cpp b/src/drv/tft/tft_driver_sdl2.cpp
index a2b44233..98461f5b 100644
--- a/src/drv/tft/tft_driver_sdl2.cpp
+++ b/src/drv/tft/tft_driver_sdl2.cpp
@@ -1,7 +1,7 @@
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
For full license information read the LICENSE file in the project folder */
-#if defined(WINDOWS) || defined(POSIX)
+#if USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
#include "hasplib.h"
#include "lvgl.h"
@@ -115,4 +115,4 @@ const char* TftSdl::get_tft_model()
dev::TftSdl haspTft;
-#endif // WINDOWS || POSIX
\ No newline at end of file
+#endif // WINDOWS || POSIX
diff --git a/src/drv/tft/tft_driver_sdl2.h b/src/drv/tft/tft_driver_sdl2.h
index 85b32ee0..d0aaa114 100644
--- a/src/drv/tft/tft_driver_sdl2.h
+++ b/src/drv/tft/tft_driver_sdl2.h
@@ -6,7 +6,7 @@
#include "tft_driver.h"
-#if defined(WINDOWS) || defined(POSIX)
+#if USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
// #warning Building H driver TFT SDL2
#include "lvgl.h"
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index b69a1ee5..5fc3eb74 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -309,7 +309,7 @@ void guiSetup()
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
-#if defined(WINDOWS) || defined(POSIX)
+#if USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
indev_drv.read_cb = mouse_read;
#else
indev_drv.read_cb = gui_touch_read;
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index d2942333..4a32377d 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -25,7 +25,9 @@
#include "hasplib.h"
// #include "app_hal.h"
+#if USE_MONITOR
#include "display/monitor.h"
+#endif
#include "hasp_debug.h"
#include "hasp_gui.h"
@@ -258,12 +260,14 @@ int main(int argc, char* argv[])
}
#endif
- SDL_Init(0); // Needs to be initialized for GetPerfPath
char buf[4096]; // never know how much is needed
std::cout << "CWD: " << cwd(buf, sizeof buf) << std::endl;
+#if USE_MONITOR
+ SDL_Init(0); // Needs to be initialized for GetPerfPath
cd(SDL_GetPrefPath("hasp", "hasp"));
- std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl;
SDL_Quit(); // We'll properly init later
+#endif
+ std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl;
// Change to preferences dir
std::cout << "\nCommand-line arguments:\n";
@@ -376,11 +380,11 @@ int main(int argc, char* argv[])
LOG_TRACE(TAG_MAIN, "main loop completed");
#if defined(WINDOWS)
- WriteConsole(std_out, "bye\n\n", 3, NULL, NULL);
- std::cout << std::endl << std::flush;
- fflush(stdout);
- FreeConsole();
- exit(0);
+ WriteConsole(std_out, "bye\n\n", 3, NULL, NULL);
+ std::cout << std::endl << std::flush;
+ fflush(stdout);
+ FreeConsole();
+ exit(0);
#endif
return 0;
From a2d97204f80ccf8f901af726f456c28792c4d1f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Tue, 6 Feb 2024 19:52:39 +0100
Subject: [PATCH 063/135] Fix storage root path with LV_USE_FS_IF
---
include/lv_conf_v7.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h
index 0b094c3f..14ec75fa 100644
--- a/include/lv_conf_v7.h
+++ b/include/lv_conf_v7.h
@@ -227,7 +227,9 @@ typedef void* lv_fs_drv_user_data_t;
//# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash
#endif
#endif /*LV_USE_FS_IF*/
+#if !(defined(WINDOWS) || defined(POSIX))
#define LV_FS_PC_PATH "/littlefs"
+#endif
#endif
From 9b3bbcc1079e53cd6e34f8761e510fcdade2c521 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Tue, 6 Feb 2024 19:52:57 +0100
Subject: [PATCH 064/135] Fix PC building with MQTT disabled
---
src/main_pc.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 4a32377d..ff155bcb 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -152,7 +152,9 @@ void setup()
void loop()
{
haspLoop();
+#if HASP_USE_MQTT
mqttLoop();
+#endif
// debugLoop(); // Console
haspDevice.loop();
@@ -190,7 +192,7 @@ void loop()
haspDevice.loop_5s();
gpioEvery5Seconds();
-#if defined(HASP_USE_MQTT)
+#if HASP_USE_MQTT
mqttEvery5Seconds(true);
#endif
@@ -363,7 +365,9 @@ int main(int argc, char* argv[])
serializeJson(settings, buffer, sizeof(buffer));
std::cout << buffer << std::endl << std::flush;
fflush(stdout);
+#if HASP_USE_MQTT
mqttSetConfig(settings["mqtt"]);
+#endif
// printf("%s %d\n", __FILE__, __LINE__);
// fflush(stdout);
From 76b9be4d9795c54743760f36a2476d483b2d075f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Tue, 6 Feb 2024 19:53:58 +0100
Subject: [PATCH 065/135] Add Win32Drv GDI port
---
include/hasp_conf.h | 2 +
include/lv_drv_conf.h | 6 +-
src/dev/win32/hasp_win32.cpp | 10 +-
src/dev/win32/hasp_win32.h | 2 +
src/drv/tft/tft_driver.h | 3 +
src/drv/tft/tft_driver_win32drv.cpp | 109 +++++++++++++++++++
src/drv/tft/tft_driver_win32drv.h | 44 ++++++++
src/main_pc.cpp | 20 +++-
user_setups/win32/windows_gdi_64bits.ini | 131 +++++++++++++++++++++++
9 files changed, 321 insertions(+), 6 deletions(-)
create mode 100644 src/drv/tft/tft_driver_win32drv.cpp
create mode 100644 src/drv/tft/tft_driver_win32drv.h
create mode 100644 user_setups/win32/windows_gdi_64bits.ini
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index ef832b69..a5619c46 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -384,6 +384,8 @@ static WiFiSpiClass WiFi;
#define halRestartMcu()
#if USE_MONITOR
#define millis SDL_GetTicks
+#elif USE_WIN32DRV
+#define millis Win32Millis
#endif
#define DEC 10
diff --git a/include/lv_drv_conf.h b/include/lv_drv_conf.h
index cb5bd603..3afc0d92 100644
--- a/include/lv_drv_conf.h
+++ b/include/lv_drv_conf.h
@@ -125,7 +125,11 @@
#define USE_WINDOWS 0
#endif
-#if USE_WINDOWS
+#ifndef USE_WIN32DRV
+#define USE_WINDOWS 0
+#endif
+
+#if USE_WINDOWS || USE_WIN32DRV
#define WINDOW_HOR_RES 480
#define WINDOW_VER_RES 320
#endif
diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp
index f089307c..46051804 100644
--- a/src/dev/win32/hasp_win32.cpp
+++ b/src/dev/win32/hasp_win32.cpp
@@ -13,6 +13,8 @@
#if USE_MONITOR
#include "display/monitor.h"
+#elif USE_WIN32DRV
+#include "win32drv/win32drv.h"
#endif
namespace dev {
@@ -52,7 +54,8 @@ void Win32Device::set_hostname(const char* hostname)
_hostname = hostname;
#if USE_MONITOR
monitor_title(hostname);
- // SDL_SetWindowTitle(monitor.window, hostname);
+#elif USE_WIN32DRV
+ lv_win32_set_title(hostname);
#endif
}
const char* Win32Device::get_core_version()
@@ -156,6 +159,11 @@ long Win32Device::get_uptime()
} // namespace dev
+long Win32Millis()
+{
+ return GetTickCount64();
+}
+
dev::Win32Device haspDevice;
#endif // WINDOWS
diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h
index 0c64e1f9..5e59ea73 100644
--- a/src/dev/win32/hasp_win32.h
+++ b/src/dev/win32/hasp_win32.h
@@ -91,6 +91,8 @@ class Win32Device : public BaseDevice {
} // namespace dev
+extern long Win32Millis();
+
using dev::Win32Device;
extern dev::Win32Device haspDevice;
diff --git a/src/drv/tft/tft_driver.h b/src/drv/tft/tft_driver.h
index 0c0d5814..18eaa756 100644
--- a/src/drv/tft/tft_driver.h
+++ b/src/drv/tft/tft_driver.h
@@ -80,6 +80,9 @@ class BaseTft {
#elif USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
// #warning Building for SDL2
#include "tft_driver_sdl2.h"
+#elif USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX))
+// #warning Building for Win32Drv
+#include "tft_driver_win32drv.h"
#else
// #warning Building for Generic Tfts
using dev::BaseTft;
diff --git a/src/drv/tft/tft_driver_win32drv.cpp b/src/drv/tft/tft_driver_win32drv.cpp
new file mode 100644
index 00000000..709ed054
--- /dev/null
+++ b/src/drv/tft/tft_driver_win32drv.cpp
@@ -0,0 +1,109 @@
+/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+ For full license information read the LICENSE file in the project folder */
+
+#if USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX))
+
+#include "hasplib.h"
+#include "lvgl.h"
+
+#include "win32drv/win32drv.h"
+
+#include "drv/tft/tft_driver.h"
+#include "tft_driver_win32drv.h"
+
+#include "dev/device.h"
+#include "hasp_debug.h"
+
+#ifdef HASP_CUSTOMIZE_BOOTLOGO
+#include "custom/bootlogo.h" // Sketch tab header for xbm images
+#else
+#include "custom/bootlogo_template.h" // Sketch tab header for xbm images
+#endif
+
+namespace dev {
+
+/**
+ * A task to measure the elapsed time for LittlevGL
+ * @param data unused
+ * @return never return
+ */
+static DWORD tick_thread(void* data)
+{
+ (void)data;
+
+ while(1) {
+ Sleep(5); /*Sleep for 5 millisecond*/
+ lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
+ }
+
+ return 0;
+}
+
+int32_t TftWin32Drv::width()
+{
+ return _width;
+}
+int32_t TftWin32Drv::height()
+{
+ return _height;
+}
+
+void TftWin32Drv::init(int32_t w, int h)
+{
+ _width = w;
+ _height = h;
+
+ /* Add a display
+ * Use the 'win32drv' driver which creates window on PC's monitor to simulate a display
+ * The following input devices are handled: mouse, keyboard, mousewheel */
+ lv_win32_init(0, SW_SHOWNORMAL, w, h, 0);
+ lv_win32_set_title(haspDevice.get_hostname());
+
+ /* Tick init.
+ * You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed
+ * Create a Windows thread to do this*/
+ CreateThread(NULL, 0, tick_thread, NULL, 0, NULL);
+}
+void TftWin32Drv::show_info()
+{
+ splashscreen();
+
+ unsigned long version = GetVersion();
+ unsigned long major = LOBYTE(LOWORD(version));
+ unsigned long minor = HIBYTE(LOWORD(version));
+ unsigned long build = 0;
+ if(version < 0x80000000) build = HIWORD(version);
+ LOG_VERBOSE(TAG_TFT, F("Driver : Win32Drv"));
+ LOG_VERBOSE(TAG_TFT, F("Windows Version: %d.%d.%d"), major, minor, build);
+}
+
+void TftWin32Drv::splashscreen()
+{
+ uint8_t fg[] = logoFgColor;
+ uint8_t bg[] = logoBgColor;
+ lv_color_t fgColor = lv_color_make(fg[0], fg[1], fg[2]);
+ lv_color_t bgColor = lv_color_make(bg[0], bg[1], bg[2]);
+ lv_win32_splashscreen(logoImage, logoWidth, logoHeight, lv_color_to32(fgColor), lv_color_to32(bgColor));
+}
+void TftWin32Drv::set_rotation(uint8_t rotation)
+{}
+void TftWin32Drv::set_invert(bool invert)
+{}
+void TftWin32Drv::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
+{
+ lv_disp_flush_ready(disp);
+}
+bool TftWin32Drv::is_driver_pin(uint8_t pin)
+{
+ return false;
+}
+const char* TftWin32Drv::get_tft_model()
+{
+ return "Win32Drv";
+}
+
+} // namespace dev
+
+dev::TftWin32Drv haspTft;
+
+#endif // WINDOWS || POSIX
diff --git a/src/drv/tft/tft_driver_win32drv.h b/src/drv/tft/tft_driver_win32drv.h
new file mode 100644
index 00000000..89dd4223
--- /dev/null
+++ b/src/drv/tft/tft_driver_win32drv.h
@@ -0,0 +1,44 @@
+/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+ For full license information read the LICENSE file in the project folder */
+
+#ifndef HASP_WIN32DRV_DRIVER_H
+#define HASP_WIN32DRV_DRIVER_H
+
+#include "tft_driver.h"
+
+#if USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX))
+// #warning Building H driver WIN32DRV
+
+#include "lvgl.h"
+
+namespace dev {
+
+class TftWin32Drv : BaseTft {
+ public:
+ void init(int w, int h);
+ void show_info();
+ void splashscreen();
+
+ void set_rotation(uint8_t rotation);
+ void set_invert(bool invert);
+
+ void flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
+ bool is_driver_pin(uint8_t pin);
+
+ const char* get_tft_model();
+
+ int32_t width();
+ int32_t height();
+
+ private:
+ int32_t _width, _height;
+};
+
+} // namespace dev
+
+using dev::TftWin32Drv;
+extern dev::TftWin32Drv haspTft;
+
+#endif // defined(WINDOWS) || defined(POSIX)
+
+#endif // HASP_SDL2_DRIVER_H
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index ff155bcb..322fb24b 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -7,6 +7,8 @@
#include
#include
+#include
+#include
// MSDN recommends against using getcwd & chdir names
#define cwd _getcwd
#define cd _chdir
@@ -35,7 +37,6 @@
#include "dev/device.h"
bool isConnected;
-bool isRunning = 1;
uint8_t mainLoopCounter = 0;
unsigned long mainLastLoopTime = 0;
@@ -268,6 +269,12 @@ int main(int argc, char* argv[])
SDL_Init(0); // Needs to be initialized for GetPerfPath
cd(SDL_GetPrefPath("hasp", "hasp"));
SDL_Quit(); // We'll properly init later
+#elif USE_WIN32DRV
+ if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, buf))) {
+ PathAppendA(buf, "hasp");
+ PathAppendA(buf, "hasp");
+ cd(buf);
+ }
#endif
std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl;
@@ -377,11 +384,16 @@ int main(int argc, char* argv[])
setup();
- LOG_TRACE(TAG_MAIN, "loop started");
- while(isRunning) {
+#if USE_MONITOR
+ while(1) {
loop();
}
- LOG_TRACE(TAG_MAIN, "main loop completed");
+#elif USE_WIN32DRV
+ extern bool lv_win32_quit_signal;
+ while(!lv_win32_quit_signal) {
+ loop();
+ }
+#endif
#if defined(WINDOWS)
WriteConsole(std_out, "bye\n\n", 3, NULL, NULL);
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
new file mode 100644
index 00000000..38d8b4c3
--- /dev/null
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -0,0 +1,131 @@
+[env:windows_gdi_64bits]
+platform = native@^1.1.4
+extra_scripts =
+ tools/sdl2_build_extra.py
+ tools/windows_build_extra.py
+build_flags =
+ ${env.build_flags}
+ -D HASP_MODEL="Windows App"
+
+ ; ----- Monitor
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=320
+ ; SDL drivers options
+ ;-D LV_LVGL_H_INCLUDE_SIMPLE
+ ;-D LV_DRV_NO_CONF
+ -D USE_WIN32DRV
+ ; ----- ArduinoJson
+ -D ARDUINOJSON_DECODE_UNICODE=1
+ -D HASP_NUM_PAGES=12
+ -D HASP_USE_SPIFFS=0
+ -D HASP_USE_LITTLEFS=0
+ -D HASP_USE_EEPROM=0
+ -D HASP_USE_GPIO=1
+ -D HASP_USE_CONFIG=0 ; Standalone application, as library
+ -D HASP_USE_DEBUG=1
+ -D HASP_USE_PNGDECODE=1
+ -D HASP_USE_BMPDECODE=1
+ -D HASP_USE_GIFDECODE=0
+ -D HASP_USE_JPGDECODE=0
+ -D HASP_USE_MQTT=1
+ -D HASP_USE_SYSLOG=0
+ -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_ATTRIBUTE_FAST_MEM=
+ -D IRAM_ATTR= ; No IRAM_ATTR available
+ -D PROGMEM= ; No PROGMEM available
+
+ ; -- FreeType build options ------------------------
+ -D LV_USE_FT_CACHE_MANAGER=1 ; crashes without cache
+ -D LVGL_FREETYPE_MAX_FACES=64 ; max number of FreeType faces in cache
+ -D LVGL_FREETYPE_MAX_SIZES=4 ; max number of sizes in cache
+ -D LVGL_FREETYPE_MAX_BYTES=16384 ; max bytes in cache
+ -D LVGL_FREETYPE_MAX_BYTES_PSRAM=65536 ; max bytes in cache when using PSRAM
+
+ ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
+ ;-D LV_LOG_PRINTF=1
+ ; Add recursive dirs for hal headers search
+ -D _WIN64
+ -D WINDOWS ; We add this ourselves for code branching in hasp
+ -D WIN32_LEAN_AND_MEAN ; exclude a bunch of Windows header files from windows.h
+ -D PAHO_MQTT_STATIC
+ -DPAHO_WITH_SSL=TRUE
+ -DPAHO_BUILD_DOCUMENTATION=FALSE
+ -DPAHO_BUILD_SAMPLES=FALSE
+ -DCMAKE_BUILD_TYPE=Release
+ -DCMAKE_VERBOSE_MAKEFILE=TRUE
+ ;-D NO_PERSISTENCE
+ -I.pio/libdeps/windows_gdi_64bits/paho/src
+ -I.pio/libdeps/windows_gdi_64bits/ArduinoJson/src
+ -I lib/lv_fs_if
+ -I lib/lv_datetime
+ -mconsole
+ ; ----- Statically linked libraries --------------------
+ -l"ws2_32" ;windsock2
+ -lrpcrt4
+ -lcrypt32
+ -lmingw32
+ -mwindows
+ -lm
+ -ldinput8
+ ;-ldxguid
+ ;-ldxerr8
+ ;-luser32
+ ;-lgdi32
+ -lwinmm
+ -limm32
+ -lole32
+ -loleaut32
+ ;-lshell32
+ -lversion
+ ;-luuid
+ -lsetupapi
+ -lshlwapi
+ ;-lhid
+
+lib_deps =
+ ${env.lib_deps}
+ ;lv_drivers@~7.9.0
+ ;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
+ https://github.com/eclipse/paho.mqtt.c.git
+ bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
+ https://github.com/fvanroie/lv_drivers
+
+lib_ignore =
+ paho
+ AXP192
+ ArduinoLog
+ lv_lib_qrcode
+ ETHSPI
+
+build_src_filter =
+ +<*>
+ -<*.h>
+ +<../hal/sdl2>
+ +<../.pio/libdeps/windows_gdi_64bits/paho/src/*.c>
+ +<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTClient.c>
+ -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsync.c>
+ -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/windows_gdi_64bits/paho/src/SSLSocket.c>
+ +
+ -
+ -
+ -
+ -
+ -
+ +
+ -
+ +
+ -
+ +
+ +
+ -
+ -
+ -
+ +
+ +
+ +
+ -
+ +
+ +<../.pio/libdeps/windows_gdi_64bits/ArduinoJson/src/ArduinoJson.h>
+ +
From b738c22c679d05f4ba882761014c4e3ec7f4f7c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Tue, 6 Feb 2024 19:59:28 +0100
Subject: [PATCH 066/135] Disable app_hal.c if not using SDL2
---
hal/sdl2/app_hal.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hal/sdl2/app_hal.c b/hal/sdl2/app_hal.c
index fd062ada..c7524836 100644
--- a/hal/sdl2/app_hal.c
+++ b/hal/sdl2/app_hal.c
@@ -1,3 +1,4 @@
+#if USE_MONITOR
#include
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
#include
@@ -53,3 +54,4 @@ void hal_loop(void)
// lv_task_handler();
// }
}
+#endif
From 96bfbf397baeeda39697bfce6c6774b5a1f51b3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Wed, 7 Feb 2024 11:11:15 +0100
Subject: [PATCH 067/135] Add HASP_TARGET_ARDUINO and HASP_TARGET_PC macros
---
include/hasp_conf.h | 81 +++++++++++---------
include/hasp_macro.h | 6 +-
include/lv_conf_v7.h | 2 +-
lib/lv_lib_zifont/lv_zifont.cpp | 2 +-
src/dev/device.h | 2 +-
src/drv/tft/tft_driver.h | 4 +-
src/drv/tft/tft_driver_sdl2.cpp | 2 +-
src/drv/tft/tft_driver_sdl2.h | 4 +-
src/drv/tft/tft_driver_win32drv.cpp | 2 +-
src/drv/tft/tft_driver_win32drv.h | 6 +-
src/hasp/hasp.cpp | 2 +-
src/hasp/hasp_dispatch.cpp | 6 +-
src/hasp/hasp_font.cpp | 2 +-
src/hasp/hasp_object.cpp | 2 +-
src/hasp_debug.cpp | 4 +-
src/hasp_debug.h | 2 +-
src/hasp_gui.cpp | 6 +-
src/main_arduino.cpp | 2 +-
src/main_pc.cpp | 2 +-
src/mqtt/hasp_mqtt_ha.cpp | 4 +-
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 3 +-
user_setups/esp32/_esp32.ini | 1 +
user_setups/esp8266/_esp8266.ini | 1 +
user_setups/linux_sdl/linux_sdl_64bits.ini | 1 +
user_setups/stm32f4xx/_stm32f4.ini | 3 +-
user_setups/stm32f7xx/_stm32f7.ini | 1 +
user_setups/win32/windows_gdi_64bits.ini | 1 +
user_setups/win32/windows_sdl_64bits.ini | 1 +
28 files changed, 86 insertions(+), 69 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index a5619c46..59ef00c1 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -33,6 +33,11 @@
#define HASP_USE_APP 1
+/* Validate that build target was specified */
+#if HASP_TARGET_ARDUINO + HASP_TARGET_PC != 1
+#error "Build target invalid! Set *one* of: HASP_TARGET_ARDUINO, HASP_TARGET_PC"
+#endif
+
#ifndef HASP_USE_DEBUG
#define HASP_USE_DEBUG 1
#endif
@@ -190,6 +195,41 @@
#define HASP_OBJECT_NOTATION "p%ub%u"
+#ifndef HASP_ATTRIBUTE_FAST_MEM
+#define HASP_ATTRIBUTE_FAST_MEM
+#endif
+
+#ifndef IRAM_ATTR
+#define IRAM_ATTR
+#endif
+
+#ifndef FPSTR
+#define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
+#endif
+
+#ifndef PGM_P
+#define PGM_P const char*
+#endif
+
+/* Workarounds for PC build */
+#if HASP_TARGET_PC
+#ifndef __FlashStringHelper
+#define __FlashStringHelper char
+#endif
+
+#ifndef F
+#define F(x) (x)
+#endif
+
+#ifndef PSTR
+#define PSTR(x) x
+#endif
+
+#ifndef PROGMEM
+#define PROGMEM
+#endif
+#endif
+
/* Includes */
#ifdef WINDOWS
#include "winsock2.h"
@@ -281,7 +321,7 @@ static WiFiSpiClass WiFi;
#if HASP_USE_MQTT > 0
#include "mqtt/hasp_mqtt.h"
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
#define HASP_USE_PAHO
#else
#define HASP_USE_ESP_MQTT
@@ -326,51 +366,20 @@ static WiFiSpiClass WiFi;
#include "sys/svc/hasp_slave.h"
#endif
-#ifndef HASP_ATTRIBUTE_FAST_MEM
-#define HASP_ATTRIBUTE_FAST_MEM
-#endif
-
-#ifndef IRAM_ATTR
-#define IRAM_ATTR
-#endif
-
-#ifndef FPSTR
-#define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
-#endif
-
-#ifndef PGM_P
-#define PGM_P const char*
-#endif
-
-#if defined(WINDOWS) || defined(POSIX)
-#ifndef __FlashStringHelper
-#define __FlashStringHelper char
-#endif
-
-#ifndef F
-#define F(x) (x)
-#endif
-
-#ifndef PSTR
-#define PSTR(x) x
-#endif
-
-#ifndef PROGMEM
-#define PROGMEM
-#endif
-#endif
-
#if defined(WINDOWS)
#include
#define delay Sleep
#endif
+
#if defined(POSIX)
#define delay SDL_Delay
#endif
-#if defined(WINDOWS) || defined(POSIX)
+
+#if HASP_TARGET_PC
#include
#include
#include
+
#if USE_MONITOR
#include
#endif
diff --git a/include/hasp_macro.h b/include/hasp_macro.h
index f1f937b9..7dc1f82b 100644
--- a/include/hasp_macro.h
+++ b/include/hasp_macro.h
@@ -12,15 +12,15 @@
#include "user_config_override.h"
#endif
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
#define HASP_RANDOM(x) rand() % x
-#elif defined(ARDUINO)
+#elif HASP_TARGET_ARDUINO
#define HASP_RANDOM(x) random(x)
#else
#define HASP_RANDOM(x) random() % x
#endif
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
#define LOG_OUTPUT(x, ...) printf(__VA_ARGS__)
#else
diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h
index 14ec75fa..e2adf67e 100644
--- a/include/lv_conf_v7.h
+++ b/include/lv_conf_v7.h
@@ -227,7 +227,7 @@ typedef void* lv_fs_drv_user_data_t;
//# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash
#endif
#endif /*LV_USE_FS_IF*/
-#if !(defined(WINDOWS) || defined(POSIX))
+#if HASP_TARGET_ARDUINO
#define LV_FS_PC_PATH "/littlefs"
#endif
diff --git a/lib/lv_lib_zifont/lv_zifont.cpp b/lib/lv_lib_zifont/lv_zifont.cpp
index 43f7e340..3db55627 100644
--- a/lib/lv_lib_zifont/lv_zifont.cpp
+++ b/lib/lv_lib_zifont/lv_zifont.cpp
@@ -5,7 +5,7 @@
* INCLUDES
*********************/
-#if !(defined(WINDOWS) || defined(POSIX) || defined(STM32F7xx))
+#if !(HASP_TARGET_PC || defined(STM32F7xx))
#include
#include
diff --git a/src/dev/device.h b/src/dev/device.h
index 32ad1dc7..75039f34 100644
--- a/src/dev/device.h
+++ b/src/dev/device.h
@@ -8,7 +8,7 @@
#include "Arduino.h"
#endif
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
#include
#endif
#if defined(POSIX)
diff --git a/src/drv/tft/tft_driver.h b/src/drv/tft/tft_driver.h
index 18eaa756..914597a8 100644
--- a/src/drv/tft/tft_driver.h
+++ b/src/drv/tft/tft_driver.h
@@ -77,10 +77,10 @@ class BaseTft {
#elif defined(STM32F7)
#warning Building for STM32F7xx Tfts
#include "tft_driver_tftespi.h"
-#elif USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
+#elif USE_MONITOR && HASP_TARGET_PC
// #warning Building for SDL2
#include "tft_driver_sdl2.h"
-#elif USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX))
+#elif USE_WIN32DRV && HASP_TARGET_PC
// #warning Building for Win32Drv
#include "tft_driver_win32drv.h"
#else
diff --git a/src/drv/tft/tft_driver_sdl2.cpp b/src/drv/tft/tft_driver_sdl2.cpp
index 98461f5b..82ca964d 100644
--- a/src/drv/tft/tft_driver_sdl2.cpp
+++ b/src/drv/tft/tft_driver_sdl2.cpp
@@ -1,7 +1,7 @@
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
For full license information read the LICENSE file in the project folder */
-#if USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
+#if USE_MONITOR && HASP_TARGET_PC
#include "hasplib.h"
#include "lvgl.h"
diff --git a/src/drv/tft/tft_driver_sdl2.h b/src/drv/tft/tft_driver_sdl2.h
index d0aaa114..32ce9e6d 100644
--- a/src/drv/tft/tft_driver_sdl2.h
+++ b/src/drv/tft/tft_driver_sdl2.h
@@ -6,7 +6,7 @@
#include "tft_driver.h"
-#if USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
+#if USE_MONITOR && HASP_TARGET_PC
// #warning Building H driver TFT SDL2
#include "lvgl.h"
@@ -40,6 +40,6 @@ class TftSdl : BaseTft {
using dev::TftSdl;
extern dev::TftSdl haspTft;
-#endif // defined(WINDOWS) || defined(POSIX)
+#endif // HASP_TARGET_PC
#endif // HASP_SDL2_DRIVER_H
diff --git a/src/drv/tft/tft_driver_win32drv.cpp b/src/drv/tft/tft_driver_win32drv.cpp
index 709ed054..911cae2e 100644
--- a/src/drv/tft/tft_driver_win32drv.cpp
+++ b/src/drv/tft/tft_driver_win32drv.cpp
@@ -1,7 +1,7 @@
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
For full license information read the LICENSE file in the project folder */
-#if USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX))
+#if USE_WIN32DRV && HASP_TARGET_PC
#include "hasplib.h"
#include "lvgl.h"
diff --git a/src/drv/tft/tft_driver_win32drv.h b/src/drv/tft/tft_driver_win32drv.h
index 89dd4223..eefcd4eb 100644
--- a/src/drv/tft/tft_driver_win32drv.h
+++ b/src/drv/tft/tft_driver_win32drv.h
@@ -6,7 +6,7 @@
#include "tft_driver.h"
-#if USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX))
+#if USE_WIN32DRV && HASP_TARGET_PC
// #warning Building H driver WIN32DRV
#include "lvgl.h"
@@ -39,6 +39,6 @@ class TftWin32Drv : BaseTft {
using dev::TftWin32Drv;
extern dev::TftWin32Drv haspTft;
-#endif // defined(WINDOWS) || defined(POSIX)
+#endif // HASP_TARGET_PC
-#endif // HASP_SDL2_DRIVER_H
+#endif // HASP_WIN32DRV_DRIVER_H
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index e2e49f0f..35388570 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -11,7 +11,7 @@
#include "ArduinoLog.h"
#endif
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
#include
#include
#include
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index f478fa62..80c699ab 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -16,7 +16,7 @@
#include "../hasp_debug.h"
#include "hasp_gui.h" // for screenshot
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
#include
#include
#include
@@ -1113,7 +1113,7 @@ void dispatch_reboot(bool saveConfig)
LOG_VERBOSE(TAG_MSGR, F("-------------------------------------"));
LOG_TRACE(TAG_MSGR, F(D_DISPATCH_REBOOT));
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
fflush(stdout);
#else
Serial.flush();
@@ -1217,7 +1217,7 @@ void dispatch_send_discovery(const char*, const char*, uint8_t source)
#if HASP_USE_HTTP > 0
network_get_ipaddress(buffer, sizeof(buffer));
doc[F("uri")] = String(F("http://")) + String(buffer);
-#elif defined(WINDOWS) || defined(POSIX)
+#elif HASP_TARGET_PC
doc[F("uri")] = "http://google.pt";
#endif
diff --git a/src/hasp/hasp_font.cpp b/src/hasp/hasp_font.cpp
index 98a20c46..d86a4f14 100644
--- a/src/hasp/hasp_font.cpp
+++ b/src/hasp/hasp_font.cpp
@@ -68,7 +68,7 @@ void font_setup()
} else {
LOG_ERROR(TAG_FONT, F("FreeType " D_SERVICE_START_FAILED));
}
-#elif defined(WINDOWS) || defined(POSIX)
+#elif HASP_TARGET_PC
#else
#endif
diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp
index 08fd170e..f7e436cf 100644
--- a/src/hasp/hasp_object.cpp
+++ b/src/hasp/hasp_object.cpp
@@ -179,7 +179,7 @@ int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc)
{
int i = 0;
-#if defined(WINDOWS) || defined(POSIX) || defined(ESP32)
+#if HASP_TARGET_PC || defined(ESP32)
std::string v;
v.reserve(64);
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index 672c0ba2..fa2f5406 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -99,7 +99,7 @@ static inline void debug_flush()
HASP_SERIAL.flush();
#endif
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
fflush(stdout);
#endif
}
@@ -116,7 +116,7 @@ void debugEverySecond()
void debugStart(void)
{
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
debug_newline();
debugPrintHaspHeader(NULL);
debug_newline();
diff --git a/src/hasp_debug.h b/src/hasp_debug.h
index 425a7d97..c025ff99 100644
--- a/src/hasp_debug.h
+++ b/src/hasp_debug.h
@@ -17,7 +17,7 @@
#include "lang/lang.h"
-#if(!defined(WINDOWS)) && (!defined(POSIX))
+#if HASP_TARGET_ARDUINO
/* ===== Default Event Processors ===== */
void debugSetup(JsonObject settings);
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 5fc3eb74..68a51d1c 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -309,7 +309,7 @@ void guiSetup()
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
-#if USE_MONITOR && (defined(WINDOWS) || defined(POSIX))
+#if USE_MONITOR && HASP_TARGET_PC
indev_drv.read_cb = mouse_read;
#else
indev_drv.read_cb = gui_touch_read;
@@ -345,7 +345,7 @@ void guiSetup()
gui_hide_pointer(false);
lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
-#if !(defined(WINDOWS) || defined(POSIX))
+#if HASP_TARGET_ARDUINO
// drv_touch_init(gui_settings.rotation); // Touch driver
haspTouch.init(tft_width, tft_height);
haspTouch.set_calibration(gui_settings.cal_data);
@@ -386,7 +386,7 @@ IRAM_ATTR void guiLoop(void)
// tick.update();
#endif
-#if !(defined(WINDOWS) || defined(POSIX))
+#if HASP_TARGET_ARDUINO
// haspTouch.loop();
#endif
}
diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp
index 8fc378b2..b383531c 100644
--- a/src/main_arduino.cpp
+++ b/src/main_arduino.cpp
@@ -1,7 +1,7 @@
/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
-#if !(defined(WINDOWS) || defined(POSIX))
+#if HASP_TARGET_ARDUINO
/*
#ifdef CORE_DEBUG_LEVEL
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 322fb24b..c4988771 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -1,7 +1,7 @@
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
For full license information read the LICENSE file in the project folder */
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
#if defined(WINDOWS)
diff --git a/src/mqtt/hasp_mqtt_ha.cpp b/src/mqtt/hasp_mqtt_ha.cpp
index bf6edb1c..f7040e07 100644
--- a/src/mqtt/hasp_mqtt_ha.cpp
+++ b/src/mqtt/hasp_mqtt_ha.cpp
@@ -16,7 +16,7 @@
#define RETAINED true
-#if defined(WINDOWS) || defined(POSIX)
+#if HASP_TARGET_PC
extern std::string mqttNodeTopic;
extern std::string mqttGroupTopic;
#else
@@ -35,7 +35,7 @@ const char FP_MQTT_HA_NAME[] PROGMEM = "name";
const char FP_MQTT_HA_MODEL[] PROGMEM = "mdl";
const char FP_MQTT_HA_MANUFACTURER[] PROGMEM = "mf";
-#if !(defined(WINDOWS) || defined(POSIX))
+#if HASP_TARGET_ARDUINO
#include "hal/hasp_hal.h"
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index a1e64062..1cae860e 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -6,7 +6,8 @@ extra_scripts =
tools/linux_build_extra.py
build_flags =
${env.build_flags}
- -D HASP_MODEL="MacOS X App"
+ -D HASP_MODEL="MacOS X App"
+ -D HASP_TARGET_PC=1
; ----- Monitor
-D TFT_WIDTH=240
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index a7440eae..1a12c95d 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -35,6 +35,7 @@ files =
build_flags =
${env.build_flags}
+ -D HASP_TARGET_ARDUINO=1
-D HTTP_UPLOAD_BUFLEN=1024 ; lower http upload buffer
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
-D HASP_CONSOLE_BUFFER=256 ; maximum length of a console/telnet command
diff --git a/user_setups/esp8266/_esp8266.ini b/user_setups/esp8266/_esp8266.ini
index ad231166..e9ffe212 100644
--- a/user_setups/esp8266/_esp8266.ini
+++ b/user_setups/esp8266/_esp8266.ini
@@ -12,6 +12,7 @@ board_build.f_cpu = 160000000L ; set frequency to 160MHz
monitor_filters = esp8266_exception_decoder
build_flags=
+ -D HASP_TARGET_ARDUINO=1
-D HTTP_UPLOAD_BUFLEN=512 ; lower http upload buffer
-D MQTT_MAX_PACKET_SIZE=1024 ; longer PubSubClient messages
-D HASP_CONSOLE_BUFFER=160 ; maximum length of a console/telnet command
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index e68c716b..dbe7f24c 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -6,6 +6,7 @@ extra_scripts =
build_flags =
${env.build_flags}
-D HASP_MODEL="Linux App"
+ -D HASP_TARGET_PC=1
; ----- Monitor
-D TFT_WIDTH=240
diff --git a/user_setups/stm32f4xx/_stm32f4.ini b/user_setups/stm32f4xx/_stm32f4.ini
index 20a755d3..7ec27e01 100644
--- a/user_setups/stm32f4xx/_stm32f4.ini
+++ b/user_setups/stm32f4xx/_stm32f4.ini
@@ -3,6 +3,7 @@
framework = arduino
platform = ststm32
build_flags=
+ -D HASP_TARGET_ARDUINO=1
-I include/stm32f4
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
-D HASP_CONSOLE_BUFFER=220 ; maximum length of a console/telnet command
@@ -21,4 +22,4 @@ build_flags=
lib_deps =
stm32duino/STM32duino LwIP @ ^2.1.2
- ;https://github.com/stm32duino/LwIP.git
\ No newline at end of file
+ ;https://github.com/stm32duino/LwIP.git
diff --git a/user_setups/stm32f7xx/_stm32f7.ini b/user_setups/stm32f7xx/_stm32f7.ini
index 192119d5..17fa84a6 100644
--- a/user_setups/stm32f7xx/_stm32f7.ini
+++ b/user_setups/stm32f7xx/_stm32f7.ini
@@ -3,6 +3,7 @@
framework = arduino
platform = ststm32
build_flags=
+ -D HASP_TARGET_ARDUINO=1
; -I include/stm32f4
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
-D HASP_CONSOLE_BUFFER=220 ; maximum length of a console/telnet command
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index 38d8b4c3..87a24f4e 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -6,6 +6,7 @@ extra_scripts =
build_flags =
${env.build_flags}
-D HASP_MODEL="Windows App"
+ -D HASP_TARGET_PC=1
; ----- Monitor
-D TFT_WIDTH=240
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index babadf77..e7b7b082 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -6,6 +6,7 @@ extra_scripts =
build_flags =
${env.build_flags}
-D HASP_MODEL="Windows App"
+ -D HASP_TARGET_PC=1
; ----- Monitor
-D TFT_WIDTH=240
From 62f567773dca1c53c1dc5453c0878a2ac2574cbe Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Wed, 7 Feb 2024 14:28:14 +0100
Subject: [PATCH 068/135] Disable fade #626
---
src/dev/esp32/esp32.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp
index 049f3c1b..7e20d8ba 100644
--- a/src/dev/esp32/esp32.cpp
+++ b/src/dev/esp32/esp32.cpp
@@ -275,7 +275,8 @@ bool Esp32Device::get_backlight_invert()
void Esp32Device::set_backlight_level(uint8_t level)
{
_backlight_level = level;
- update_backlight(true);
+ // update_backlight(true);
+ update_backlight(false);
}
uint8_t Esp32Device::get_backlight_level()
@@ -286,7 +287,8 @@ uint8_t Esp32Device::get_backlight_level()
void Esp32Device::set_backlight_power(bool power)
{
_backlight_power = power;
- update_backlight(true);
+ // update_backlight(true);
+ update_backlight(false);
}
bool Esp32Device::get_backlight_power()
From b9a435f0a460943f50162c4d2e6b8ef9d9d97a61 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Wed, 7 Feb 2024 14:29:13 +0100
Subject: [PATCH 069/135] Update to ace?js 1.32.6
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 4a38aacd..ea1228a3 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
+openHASP File Editor
New File Upload Files Edit Preview Download Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 32b4159e..baca1bb2 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.5")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.6")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML=' ',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+" ",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 0e87f52c1fcdf938efd23c9b77ab87e7e6d7cbca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Wed, 7 Feb 2024 14:24:11 +0100
Subject: [PATCH 070/135] Support config file on PC build
---
include/hasp_conf.h | 7 +-
src/hasp/hasp_dispatch.cpp | 6 +-
src/hasp_config.cpp | 86 +++++++++++++++++++-----
src/hasp_config.h | 8 ++-
src/hasp_debug.cpp | 19 +++++-
src/hasp_gui.cpp | 14 ----
src/main_pc.cpp | 10 +--
src/mqtt/hasp_mqtt_paho_single.cpp | 28 ++++++++
user_setups/win32/windows_gdi_64bits.ini | 2 +-
user_setups/win32/windows_sdl_64bits.ini | 2 +-
10 files changed, 138 insertions(+), 44 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index 59ef00c1..723b070d 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -214,7 +214,12 @@
/* Workarounds for PC build */
#if HASP_TARGET_PC
#ifndef __FlashStringHelper
-#define __FlashStringHelper char
+typedef char __FlashStringHelper;
+#endif
+
+#if defined(__cplusplus) && !defined(String)
+#include
+using String = std::string;
#endif
#ifndef F
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 80c699ab..db7ffdf4 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -460,10 +460,12 @@ void dispatch_config(const char* topic, const char* payload, uint8_t source)
}
if(strcasecmp_P(topic, PSTR("debug")) == 0) {
+#if HASP_TARGET_ARDUINO
if(update)
debugSetConfig(settings);
else
debugGetConfig(settings);
+#endif
}
else if(strcasecmp_P(topic, PSTR("gui")) == 0) {
@@ -734,7 +736,7 @@ void dispatch_parse_jsonl(std::istream& stream, uint8_t& saved_page_id)
void dispatch_parse_jsonl(const char*, const char* payload, uint8_t source)
{
if(source != TAG_MQTT) saved_jsonl_page = haspPages.get();
-#if HASP_USE_CONFIG > 0
+#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO
CharStream stream((char*)payload);
// stream.setTimeout(10);
dispatch_parse_jsonl(stream, saved_jsonl_page);
@@ -1510,7 +1512,7 @@ void dispatchSetup()
dispatch_add_command(PSTR("unzip"), filesystemUnzip);
#endif
#endif
-#if HASP_USE_CONFIG > 0
+#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO
dispatch_add_command(PSTR("setupap"), oobeFakeSetup);
#endif
/* WARNING: remember to expand the commands array when adding new commands */
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index d3e55b1e..559c3f0a 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -8,7 +8,9 @@
#include "hasp_config.h"
#include "hasp_debug.h"
#include "hasp_gui.h"
+#if HASP_TARGET_ARDUINO
#include "hal/hasp_hal.h"
+#endif
// #include "hasp_ota.h" included in conf
// #include "hasp_filesystem.h" included in conf
@@ -21,7 +23,9 @@
#include "EEPROM.h"
#endif
+#if HASP_USE_EEPROM > 0
#include "StreamUtils.h" // For EEPromStream
+#endif
extern uint16_t dispatchTelePeriod;
extern uint32_t dispatchLastMillis;
@@ -29,6 +33,7 @@ extern uint32_t dispatchLastMillis;
extern gui_conf_t gui_settings;
extern dispatch_conf_t dispatch_settings;
+#if HASP_TARGET_ARDUINO
void confDebugSet(const __FlashStringHelper* fstr_name)
{
/*char buffer[128];
@@ -36,6 +41,7 @@ void confDebugSet(const __FlashStringHelper* fstr_name)
debugPrintln(buffer);*/
LOG_VERBOSE(TAG_CONF, F(D_BULLET "%S set"), fstr_name);
}
+#endif
void confDebugSet(const char* fstr_name)
{
/*char buffer[128];
@@ -44,6 +50,7 @@ void confDebugSet(const char* fstr_name)
LOG_VERBOSE(TAG_CONF, F(D_BULLET "%s set"), fstr_name);
}
+#if HASP_TARGET_ARDUINO
bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name)
{
if(!setting.isNull()) {
@@ -130,6 +137,7 @@ bool configSet(char *value, size_t size, const JsonVariant& setting, const __Fla
}
return false;
}
+#endif
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name)
{
@@ -207,7 +215,9 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n
void configSetupDebug(JsonDocument& settings)
{
+#if HASP_TARGET_ARDUINO
debugSetup(settings[FPSTR(FP_DEBUG)]);
+#endif
debugStart(); // Debug started, now we can use it; HASP header sent
}
@@ -239,9 +249,9 @@ void configMaskPasswords(JsonDocument& settings)
DeserializationError configParseFile(String& configFile, JsonDocument& settings)
{
+ DeserializationError result = DeserializationError::InvalidInput;
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
File file = HASP_FS.open(configFile, "r");
- DeserializationError result;
if(file) {
// size_t size = file.size();
@@ -254,30 +264,51 @@ DeserializationError configParseFile(String& configFile, JsonDocument& settings)
return result;
}
return DeserializationError::InvalidInput;
+#elif HASP_TARGET_PC
+ lv_fs_if_init();
+ lv_fs_file_t f;
+ lv_fs_res_t res;
+ lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
+ if(res == LV_FS_RES_OK) {
+ uint32_t size = 0, read = 0;
+ if(lv_fs_size(&f, &size) == LV_FS_RES_OK && size != 0) {
+ char* buf = (char*)malloc(size + 1);
+ if(lv_fs_read(&f, buf, size, &read) == LV_FS_RES_OK && read == size) {
+ result = deserializeJson(settings, buf);
+ }
+ }
+ lv_fs_close(&f);
+ return result;
+ }
+ LOG_ERROR(TAG_HASP, F("Opening config.json from FS failed %d"), res);
+ return result;
#else
- return DeserializationError::InvalidInput;
+ return result;
#endif
}
DeserializationError configRead(JsonDocument& settings, bool setupdebug)
{
- String configFile((char*)0);
+ String configFile;
configFile.reserve(32);
configFile = String(FPSTR(FP_HASP_CONFIG_FILE));
DeserializationError error;
-#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
+ if(setupdebug) configSetupDebug(settings); // Now we can use log
+
+#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 || HASP_TARGET_PC
error = configParseFile(configFile, settings);
if(!error) {
String output, wifiPass, mqttPass, httpPass, wgPrivKey;
/* Load Debug params */
if(setupdebug) {
- configSetupDebug(settings); // Now we can use log
LOG_INFO(TAG_CONF, F("SPI flash FS mounted"));
+#if HASP_TARGET_ARDUINO
filesystemInfo();
filesystemList();
+#endif
}
LOG_TRACE(TAG_CONF, F(D_FILE_LOADING), configFile.c_str());
@@ -304,9 +335,6 @@ DeserializationError configRead(JsonDocument& settings, bool setupdebug)
#endif
- // File does not exist or error reading file
- if(setupdebug) configSetupDebug(settings); // Now we can use log
-
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
LOG_ERROR(TAG_CONF, F(D_FILE_LOAD_FAILED), configFile.c_str());
#endif
@@ -360,11 +388,11 @@ void configBackupToEeprom()
*/
void configWrite()
{
- String configFile((char*)0);
+ String configFile;
configFile.reserve(32);
configFile = String(FPSTR(FP_HASP_CONFIG_FILE));
- String settingsChanged((char*)0);
+ String settingsChanged;
settingsChanged.reserve(128);
settingsChanged = F(D_CONFIG_CHANGED);
@@ -462,6 +490,7 @@ void configWrite()
}
#endif
+#if HASP_TARGET_ARDUINO
module = FPSTR(FP_DEBUG);
if(settings[module].as().isNull()) settings.createNestedObject(module);
changed = debugGetConfig(settings[module]);
@@ -470,6 +499,7 @@ void configWrite()
configOutput(settings[module], TAG_DEBG);
writefile = true;
}
+#endif
if(settings[FPSTR(FP_GUI)].as().isNull()) settings.createNestedObject(FPSTR(FP_GUI));
changed = guiGetConfig(settings[FPSTR(FP_GUI)]);
@@ -561,9 +591,10 @@ void configSetup()
configRead(settings, true);
}
- // #if HASP_USE_SPIFFS > 0
+#if HASP_TARGET_ARDUINO
LOG_INFO(TAG_DEBG, F("Loading debug settings"));
debugSetConfig(settings[FPSTR(FP_DEBUG)]);
+#endif
LOG_INFO(TAG_GPIO, F("Loading GUI settings"));
guiSetConfig(settings[FPSTR(FP_GUI)]);
LOG_INFO(TAG_HASP, F("Loading HASP settings"));
@@ -615,15 +646,15 @@ void configLoop(void)
void configOutput(const JsonObject& settings, uint8_t tag)
{
- String output((char*)0);
+ String output;
output.reserve(128);
serializeJson(settings, output);
- String passmask((char*)0);
+ String passmask;
passmask.reserve(128);
passmask = F("\"pass\":\"" D_PASSWORD_MASK "\"");
- String password((char*)0);
+ String password;
password.reserve(128);
String pass = F("pass");
@@ -631,28 +662,48 @@ void configOutput(const JsonObject& settings, uint8_t tag)
password = F("\"pass\":\"");
password += settings[pass].as();
password += F("\"");
+#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
+#elif HASP_TARGET_PC
+ size_t pos = 0;
+ if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
+#endif
}
if(!settings[FPSTR(FP_WIFI)][pass].isNull()) {
password = F("\"pass\":\"");
password += settings[FPSTR(FP_WIFI)][pass].as();
password += F("\"");
+#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
+#elif HASP_TARGET_PC
+ size_t pos = 0;
+ if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
+#endif
}
if(!settings[FPSTR(FP_MQTT)][pass].isNull()) {
password = F("\"pass\":\"");
password += settings[FPSTR(FP_MQTT)][pass].as();
password += F("\"");
+#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
+#elif HASP_TARGET_PC
+ size_t pos = 0;
+ if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
+#endif
}
if(!settings[FPSTR(FP_HTTP)][pass].isNull()) {
password = F("\"pass\":\"");
password += settings[FPSTR(FP_HTTP)][pass].as();
password += F("\"");
+#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
+#elif HASP_TARGET_PC
+ size_t pos = 0;
+ if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
+#endif
}
if(!settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull()) {
@@ -660,7 +711,12 @@ void configOutput(const JsonObject& settings, uint8_t tag)
password += settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].as();
password += F("\"");
passmask = F("\"privkey\":\"" D_PASSWORD_MASK "\"");
+#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
+#elif HASP_TARGET_PC
+ size_t pos = 0;
+ if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
+#endif
}
LOG_VERBOSE(tag, output.c_str());
@@ -688,4 +744,4 @@ bool configClearEeprom()
#endif
}
-#endif // HAS_USE_CONFIG
\ No newline at end of file
+#endif // HAS_USE_CONFIG
diff --git a/src/hasp_config.h b/src/hasp_config.h
index 8a667ed6..04160d30 100644
--- a/src/hasp_config.h
+++ b/src/hasp_config.h
@@ -25,13 +25,15 @@ void configOutput(const JsonObject& settings, uint8_t tag);
bool configClearEeprom(void);
/* ===== Getter and Setter Functions ===== */
+#if HASP_TARGET_ARDUINO
bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(int8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(uint8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(uint16_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(int32_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(lv_color_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
-bool configSet(char *value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
+bool configSet(char* value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
+#endif
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name);
bool configSet(int8_t& value, const JsonVariant& setting, const char* fstr_name);
bool configSet(uint8_t& value, const JsonVariant& setting, const char* fstr_name);
@@ -41,8 +43,10 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n
void configMaskPasswords(JsonDocument& settings);
/* ===== Read/Write Configuration ===== */
+#if HASP_TARGET_ARDUINO
void configSetConfig(JsonObject& settings);
void configGetConfig(JsonDocument& settings);
+#endif
/* json keys used in the configfile */
const char FP_CONFIG_STARTPAGE[] PROGMEM = "startpage";
@@ -107,4 +111,4 @@ const char FP_OTA[] PROGMEM = "ota";
#endif
-#endif // HASP_USE_CONFIG
\ No newline at end of file
+#endif // HASP_USE_CONFIG
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index fa2f5406..421606cc 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -8,12 +8,12 @@
#include "hasp_debug.h"
#include "hasp_macro.h"
-#if(!defined(WINDOWS)) && (!defined(POSIX))
+#if HASP_TARGET_ARDUINO
#define debug_print(io, ...) io->printf(__VA_ARGS__)
#define debug_newline(io) io->println()
-#else
+#elif HASP_TARGET_PC
#include
#include
#include
@@ -21,6 +21,17 @@
#define debug_print(io, ...) fprintf(stdout, __VA_ARGS__)
#define debug_newline(io) fprintf(stdout, "\n")
+#if defined(WINDOWS)
+#include
+#include
+#define cwd _getcwd
+#endif
+
+#if defined(POSIX)
+#include
+#define cwd getcwd
+#endif
+
#endif
bool debugAnsiCodes = false;
@@ -121,6 +132,8 @@ void debugStart(void)
debugPrintHaspHeader(NULL);
debug_newline();
+ char curdir[PATH_MAX];
+ LOG_INFO(TAG_DEBG, F("Configuration directory: %s"), cwd(curdir, sizeof(curdir)));
LOG_INFO(TAG_DEBG, F("Environment: " PIOENV));
LOG_INFO(TAG_DEBG, F("Console started"));
@@ -445,4 +458,4 @@ void debugPrintPrefix(uint8_t tag, int level, Print* _logOutput)
#else
debug_print(_logOutput, PSTR(" %s: "), buffer);
#endif
-}
\ No newline at end of file
+}
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 68a51d1c..d39195e8 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -207,21 +207,7 @@ static inline void gui_init_images()
static inline void gui_init_filesystems()
{
#if LV_USE_FS_IF != 0
- //_lv_fs_init(); // lvgl File System -- not needed, it done in lv_init() when LV_USE_FILESYSTEM is set
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_ENABLED));
- lv_fs_if_init(); // auxiliary file system drivers
- // filesystem_list_path("L:/");
-
- lv_fs_file_t f;
- lv_fs_res_t res;
- res = lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
- if(res == LV_FS_RES_OK) {
- LOG_VERBOSE(TAG_HASP, F("TEST Opening config.json OK"));
- lv_fs_close(&f);
- } else {
- LOG_ERROR(TAG_HASP, F("TEST Opening config.json from FS failed %d"), res);
- }
-
#else
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_DISABLED));
#endif
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index c4988771..6b2d0c83 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -112,15 +112,15 @@ void InitializeConsoleOutput()
void setup()
{
- // Load Settings
-
- // Init debug log
- // debug_init();
-
// Initialize lvgl environment
lv_init();
lv_log_register_print_cb(debugLvglLogEvent);
+ // Read & Apply User Configuration
+#if HASP_USE_CONFIG > 0
+ configSetup();
+#endif
+
haspDevice.init(); // hardware setup
haspDevice.show_info(); // debug info
// hal_setup();
diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp
index 17804f89..323b82fd 100644
--- a/src/mqtt/hasp_mqtt_paho_single.cpp
+++ b/src/mqtt/hasp_mqtt_paho_single.cpp
@@ -8,12 +8,14 @@
#if HASP_USE_MQTT > 0
#ifdef HASP_USE_PAHO
+#if !HASP_USE_CONFIG
const char FP_CONFIG_HOST[] PROGMEM = "host";
const char FP_CONFIG_PORT[] PROGMEM = "port";
const char FP_CONFIG_NAME[] PROGMEM = "name";
const char FP_CONFIG_USER[] PROGMEM = "user";
const char FP_CONFIG_PASS[] PROGMEM = "pass";
const char FP_CONFIG_GROUP[] PROGMEM = "group";
+#endif
/*******************************************************************************
* Copyright (c) 2012, 2020 IBM Corp.
@@ -411,6 +413,32 @@ void mqtt_get_info(JsonDocument& doc)
info[F(D_INFO_FAILED)] = mqttFailedCount;
}
+bool mqttGetConfig(const JsonObject& settings)
+{
+ bool changed = false;
+
+ if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as().c_str()) != 0) changed = true;
+ settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname();
+
+ if(mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName;
+
+ if(mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_HOST)] = mqttServer;
+
+ if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_PORT)] = mqttPort;
+
+ if(mqttUsername != settings[FPSTR(FP_CONFIG_USER)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_USER)] = mqttUsername;
+
+ if(mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword;
+
+ if(changed) configOutput(settings, TAG_MQTT);
+ return changed;
+}
+
/** Set MQTT Configuration.
*
* Read the settings from json and sets the application variables.
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index 87a24f4e..4330c02a 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -22,7 +22,7 @@ build_flags =
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
-D HASP_USE_GPIO=1
- -D HASP_USE_CONFIG=0 ; Standalone application, as library
+ -D HASP_USE_CONFIG=1 ; Standalone application, as library
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index e7b7b082..30de808f 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -26,7 +26,7 @@ build_flags =
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
-D HASP_USE_GPIO=1
- -D HASP_USE_CONFIG=0 ; Standalone application, as library
+ -D HASP_USE_CONFIG=1 ; Standalone application, as library
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1
From cb1d860635ce329246b5a0faff8a6261739da68f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Wed, 7 Feb 2024 16:33:52 +0100
Subject: [PATCH 071/135] Cleanup PC entrypoint, remove MQTT CLI options
---
src/dev/win32/hasp_win32.cpp | 1 +
src/dev/win32/hasp_win32.h | 2 +-
src/drv/tft/tft_driver_win32drv.cpp | 8 +-
src/main_pc.cpp | 209 +++++++----------------
user_setups/win32/windows_gdi_64bits.ini | 4 +-
user_setups/win32/windows_sdl_64bits.ini | 3 +-
6 files changed, 63 insertions(+), 164 deletions(-)
diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp
index 46051804..213b8801 100644
--- a/src/dev/win32/hasp_win32.cpp
+++ b/src/dev/win32/hasp_win32.cpp
@@ -43,6 +43,7 @@ void Win32Device::show_info()
LOG_VERBOSE(0, F("Processor : %s"), vendor);
LOG_VERBOSE(0, F("CPU freq. : %i MHz"), get_cpu_frequency());
+ LOG_VERBOSE(0, F("OS Version : %s"), get_core_version());
}
const char* Win32Device::get_hostname()
diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h
index 5e59ea73..e4b11746 100644
--- a/src/dev/win32/hasp_win32.h
+++ b/src/dev/win32/hasp_win32.h
@@ -43,7 +43,7 @@ class Win32Device : public BaseDevice {
if(dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion));
char version[128];
- snprintf(version, sizeof(version), "Windows %d.%d-%d", dwMajorVersion, dwMinorVersion, dwBuild);
+ snprintf(version, sizeof(version), "Windows %d.%d.%d", dwMajorVersion, dwMinorVersion, dwBuild);
_core_version = version;
// _backlight_pin = -1;
diff --git a/src/drv/tft/tft_driver_win32drv.cpp b/src/drv/tft/tft_driver_win32drv.cpp
index 911cae2e..38babbb9 100644
--- a/src/drv/tft/tft_driver_win32drv.cpp
+++ b/src/drv/tft/tft_driver_win32drv.cpp
@@ -68,13 +68,7 @@ void TftWin32Drv::show_info()
{
splashscreen();
- unsigned long version = GetVersion();
- unsigned long major = LOBYTE(LOWORD(version));
- unsigned long minor = HIBYTE(LOWORD(version));
- unsigned long build = 0;
- if(version < 0x80000000) build = HIWORD(version);
- LOG_VERBOSE(TAG_TFT, F("Driver : Win32Drv"));
- LOG_VERBOSE(TAG_TFT, F("Windows Version: %d.%d.%d"), major, minor, build);
+ LOG_VERBOSE(TAG_TFT, F("Driver : Win32Drv"));
}
void TftWin32Drv::splashscreen()
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 6b2d0c83..5430b130 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -121,23 +121,19 @@ void setup()
configSetup();
#endif
- haspDevice.init(); // hardware setup
- haspDevice.show_info(); // debug info
+ haspDevice.init(); // hardware setup
// hal_setup();
guiSetup();
- LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
dispatchSetup(); // for hasp and oobe
haspSetup();
#if HASP_USE_MQTT > 0
- LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
mqttSetup(); // Hasp must be running
mqttStart();
#endif
#if HASP_USE_GPIO > 0
- LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
gpioSetup();
#endif
@@ -146,7 +142,6 @@ void setup()
#endif
mainLastLoopTime = millis(); // - 1000; // reset loop counter
- LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
// delay(250);
}
@@ -191,7 +186,9 @@ void loop()
if(mainLoopCounter == 0 || mainLoopCounter == 5) {
haspDevice.loop_5s();
+#if HASP_USE_GPIO > 0
gpioEvery5Seconds();
+#endif
#if HASP_USE_MQTT
mqttEvery5Seconds(true);
@@ -215,175 +212,86 @@ void loop()
void usage(const char* progName, const char* version)
{
- std::cout << "\n\n"
- << progName << " " << version << " [options]" << std::endl
- << std::endl
- << "Options:" << std::endl
- << " -? | --help Print this help" << std::endl
- << " -w | --width Width of the window" << std::endl
- << " -h | --height Height of the window" << std::endl
- << " --mqttname MQTT device name topic (default: computer hostname)" << std::endl
- << " --mqtthost MQTT broker hostname or IP address" << std::endl
- << " --mqttport MQTT broker port (default: 1883)" << std::endl
- << " --mqttuser MQTT username" << std::endl
- << " --mqttpass MQTT password" << std::endl
- << " --mqttgroup MQTT groupname (default: plates)" << std::endl
- << std::endl
- // << " -t | --topic Base topic of the mqtt messages (default: hasp)" << std::endl
- // << std::endl
- // << " -f | --fullscreen Open the application fullscreen" << std::endl
- // << " -v | --verbose Verbosity level" << std::endl
- << std::endl;
+ std::cout
+ << "\n"
+ << progName << " " << version << " [options]" << std::endl
+ << std::endl
+ << "Options:" << std::endl
+ << " -h | --help Print this help" << std::endl
+ << " -W | --width Width of the window" << std::endl
+ << " -H | --height Height of the window" << std::endl
+ << " -C | --config Configuration directory (default: '~/.local/share/hasp' or 'AppData\\hasp\\hasp')"
+ << std::endl
+ << std::endl;
fflush(stdout);
-#if defined(WINDOWS)
- static const char s[] = "\n";
- DWORD slen = lstrlen(s);
- WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), s, slen, &slen, NULL);
-#endif
}
int main(int argc, char* argv[])
{
- bool showhelp = false;
- int count;
+ bool showhelp = false;
+ bool console = true;
+ char config[PATH_MAX] = {'\0'};
#if defined(WINDOWS)
InitializeConsoleOutput();
SetConsoleCP(65001); // 65001 = UTF-8
- static const char s[] = "tränenüberströmt™\n";
- DWORD slen = lstrlen(s);
- WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), s, slen, &slen, NULL);
-
- HANDLE std_out = GetStdHandle(STD_OUTPUT_HANDLE);
- if(std_out == INVALID_HANDLE_VALUE) {
- return 66;
- }
- if(!WriteConsole(std_out, "Hello World!\n", 13, NULL, NULL)) {
- return 67;
- }
#endif
- char buf[4096]; // never know how much is needed
- std::cout << "CWD: " << cwd(buf, sizeof buf) << std::endl;
-#if USE_MONITOR
- SDL_Init(0); // Needs to be initialized for GetPerfPath
- cd(SDL_GetPrefPath("hasp", "hasp"));
- SDL_Quit(); // We'll properly init later
-#elif USE_WIN32DRV
- if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, buf))) {
- PathAppendA(buf, "hasp");
- PathAppendA(buf, "hasp");
- cd(buf);
- }
-#endif
- std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl;
-
- // Change to preferences dir
- std::cout << "\nCommand-line arguments:\n";
- for(count = 0; count < argc; count++)
- std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
-
- StaticJsonDocument<1024> settings;
-
- for(count = 0; count < argc; count++) {
- if(argv[count][0] == '-') {
-
- if(strncmp(argv[count], "--help", 6) == 0 || strncmp(argv[count], "-?", 2) == 0) {
+ for(int arg = 1; arg < argc; arg++) {
+ if(strncmp(argv[arg], "--help", 6) == 0 || strncmp(argv[arg], "-h", 2) == 0) {
+ showhelp = true;
+ } else if(strncmp(argv[arg], "--width", 7) == 0 || strncmp(argv[arg], "-W", 2) == 0) {
+ if(arg + 1 < argc) {
+ int w = atoi(argv[arg + 1]);
+ if(w > 0) tft_width = w;
+ arg++;
+ } else {
+ std::cout << "Missing width value" << std::endl;
showhelp = true;
}
-
- if(strncmp(argv[count], "--width", 7) == 0 || strncmp(argv[count], "-w", 2) == 0) {
- int w = atoi(argv[count + 1]);
- if(w > 0) tft_width = w;
- }
-
- if(strncmp(argv[count], "--height", 8) == 0 || strncmp(argv[count], "-h", 2) == 0) {
- int h = atoi(argv[count + 1]);
+ } else if(strncmp(argv[arg], "--height", 8) == 0 || strncmp(argv[arg], "-H", 2) == 0) {
+ if(arg + 1 < argc) {
+ int h = atoi(argv[arg + 1]);
if(h > 0) tft_height = h;
+ arg++;
+ } else {
+ std::cout << "Missing height value" << std::endl;
+ showhelp = true;
}
-
- if(strncmp(argv[count], "--mqttname", 10) == 0 || strncmp(argv[count], "-n", 2) == 0) {
- std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
- fflush(stdout);
- if(count + 1 < argc) {
- haspDevice.set_hostname(argv[count + 1]);
- settings["mqtt"]["name"] = argv[count + 1];
- } else {
- showhelp = true;
- }
- }
-
- if(strncmp(argv[count], "--mqtthost", 10) == 0) {
- std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
- fflush(stdout);
- if(count + 1 < argc) {
- settings["mqtt"]["host"] = argv[count + 1];
- } else {
- showhelp = true;
- }
- }
-
- if(strncmp(argv[count], "--mqttport", 10) == 0) {
- std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
- fflush(stdout);
- if(count + 1 < argc) {
- settings["mqtt"]["port"] = atoi(argv[count + 1]);
- } else {
- showhelp = true;
- }
- }
-
- if(strncmp(argv[count], "--mqttuser", 10) == 0) {
- std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
- fflush(stdout);
- if(count + 1 < argc) {
- settings["mqtt"]["user"] = argv[count + 1];
- } else {
- showhelp = true;
- }
- }
-
- if(strncmp(argv[count], "--mqttpass", 10) == 0) {
- std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
- fflush(stdout);
- if(count + 1 < argc) {
- settings["mqtt"]["pass"] = argv[count + 1];
- } else {
- showhelp = true;
- }
+ } else if(strncmp(argv[arg], "--config", 8) == 0 || strncmp(argv[arg], "-C", 2) == 0) {
+ if(arg + 1 < argc) {
+ strcpy(config, argv[arg + 1]);
+ arg++;
+ } else {
+ std::cout << "Missing config directory" << std::endl;
+ showhelp = true;
}
+ } else {
+ std::cout << "Unrecognized command line parameter: " << argv[arg] << std::endl;
+ showhelp = true;
}
}
if(showhelp) {
usage("openHASP", haspDevice.get_version());
-
-#if defined(WINDOWS)
- WriteConsole(std_out, "bye\n\n", 3, NULL, NULL);
- std::cout << std::endl << std::flush;
- fflush(stdout);
- FreeConsole();
- exit(0);
-#endif
- return 0;
+ goto end;
}
- char buffer[2048];
- serializeJson(settings, buffer, sizeof(buffer));
- std::cout << buffer << std::endl << std::flush;
- fflush(stdout);
-#if HASP_USE_MQTT
- mqttSetConfig(settings["mqtt"]);
+ if(config[0] == '\0') {
+#if USE_MONITOR
+ SDL_Init(0); // Needs to be initialized for GetPerfPath
+ strcpy(config, SDL_GetPrefPath("hasp", "hasp"));
+ SDL_Quit(); // We'll properly init later
+#elif USE_WIN32DRV
+ if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, config))) {
+ PathAppendA(config, "hasp");
+ PathAppendA(config, "hasp");
+ }
#endif
- // printf("%s %d\n", __FILE__, __LINE__);
- // fflush(stdout);
-
- debugPrintHaspHeader(stdout);
- LOG_INFO(TAG_MAIN, "resolution %d x %d", tft_width, tft_height);
- LOG_INFO(TAG_MAIN, "pre setup");
+ }
+ cd(config);
setup();
-
#if USE_MONITOR
while(1) {
loop();
@@ -395,14 +303,13 @@ int main(int argc, char* argv[])
}
#endif
+end:
#if defined(WINDOWS)
- WriteConsole(std_out, "bye\n\n", 3, NULL, NULL);
std::cout << std::endl << std::flush;
fflush(stdout);
FreeConsole();
exit(0);
#endif
-
return 0;
}
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index 4330c02a..0344d2fc 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -1,7 +1,6 @@
[env:windows_gdi_64bits]
platform = native@^1.1.4
extra_scripts =
- tools/sdl2_build_extra.py
tools/windows_build_extra.py
build_flags =
${env.build_flags}
@@ -65,13 +64,12 @@ build_flags =
-lrpcrt4
-lcrypt32
-lmingw32
- -mwindows
-lm
-ldinput8
;-ldxguid
;-ldxerr8
;-luser32
- ;-lgdi32
+ -lgdi32
-lwinmm
-limm32
-lole32
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index 30de808f..0caaccca 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -72,13 +72,12 @@ build_flags =
-lmingw32
-lSDL2main
-lSDL2
- -mwindows
-lm
-ldinput8
;-ldxguid
;-ldxerr8
;-luser32
- ;-lgdi32
+ -lgdi32
-lwinmm
-limm32
-lole32
From d0e383e398043d60e26b5469d35419c935441a80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Wed, 7 Feb 2024 17:19:35 +0100
Subject: [PATCH 072/135] Merge setup() and loop() of PC and Arduino
---
include/hasp_conf.h | 2 +-
src/{main_arduino.cpp => main.cpp} | 24 ++--
src/main_pc.cpp | 118 +------------------
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 4 +-
user_setups/linux_sdl/linux_sdl_64bits.ini | 4 +-
user_setups/win32/windows_gdi_64bits.ini | 4 +-
user_setups/win32/windows_sdl_64bits.ini | 4 +-
7 files changed, 27 insertions(+), 133 deletions(-)
rename src/{main_arduino.cpp => main.cpp} (94%)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index 723b070d..dece01d1 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -123,7 +123,7 @@
#endif
#ifndef HASP_USE_CONSOLE
-#define HASP_USE_CONSOLE 1
+#define HASP_USE_CONSOLE HASP_TARGET_ARDUINO
#endif
/* Filesystem */
diff --git a/src/main_arduino.cpp b/src/main.cpp
similarity index 94%
rename from src/main_arduino.cpp
rename to src/main.cpp
index b383531c..68a51af3 100644
--- a/src/main_arduino.cpp
+++ b/src/main.cpp
@@ -1,8 +1,6 @@
/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
-#if HASP_TARGET_ARDUINO
-
/*
#ifdef CORE_DEBUG_LEVEL
#undef CORE_DEBUG_LEVEL
@@ -28,9 +26,9 @@
#include "hasp_gui.h"
#endif
-bool isConnected;
-uint8_t mainLoopCounter = 0;
-unsigned long mainLastLoopTime = 0;
+static bool isConnected;
+static uint8_t mainLoopCounter = 0;
+static unsigned long mainLastLoopTime = 0;
#ifdef HASP_USE_STAT_COUNTER
uint16_t statLoopCounter = 0; // measures the average looptime
@@ -40,11 +38,18 @@ void setup()
{
// hal_setup();
+#if HASP_TARGET_ARDUINO
esp_log_level_set("*", ESP_LOG_NONE); // set all components to ERROR level
// esp_log_level_set("wifi", ESP_LOG_NONE); // enable WARN logs from WiFi stack
// esp_log_level_set("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client
// esp_log_level_set("esp_crt_bundle", ESP_LOG_VERBOSE); // enable WARN logs from WiFi stack
// esp_log_level_set("esp_tls", ESP_LOG_VERBOSE); // enable WARN logs from WiFi stack
+#elif HASP_TARGET_PC
+ // Initialize lvgl environment
+ lv_init();
+ lv_log_register_print_cb(debugLvglLogEvent);
+#endif
+
haspDevice.init();
/****************************
@@ -149,7 +154,7 @@ void setup()
gui_setup_lvgl_task();
#endif // HASP_USE_LVGL_TASK
- mainLastLoopTime = -1000; // reset loop counter
+ mainLastLoopTime = 0; // reset loop counter
}
IRAM_ATTR void loop()
@@ -195,7 +200,7 @@ IRAM_ATTR void loop()
/* Timer Loop */
if(millis() - mainLastLoopTime >= 1000) {
- mainLastLoopTime += 1000;
+ mainLastLoopTime = millis();
/* Runs Every Second */
haspEverySecond(); // sleep timer & statusupdate
@@ -237,10 +242,9 @@ IRAM_ATTR void loop()
case 4:
#if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0
isConnected = networkEvery5Seconds(); // Check connection
-
+#endif
#if HASP_USE_MQTT > 0
mqttEvery5Seconds(isConnected);
-#endif
#endif
break;
@@ -270,5 +274,3 @@ IRAM_ATTR void loop()
delay(2); // ms
#endif
}
-
-#endif
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 5430b130..2b4f7362 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -26,28 +26,20 @@
#include "hasplib.h"
-// #include "app_hal.h"
#if USE_MONITOR
#include "display/monitor.h"
#endif
#include "hasp_debug.h"
-#include "hasp_gui.h"
-
-#include "dev/device.h"
-
-bool isConnected;
-
-uint8_t mainLoopCounter = 0;
-unsigned long mainLastLoopTime = 0;
-
-#ifdef HASP_USE_STAT_COUNTER
-uint16_t statLoopCounter = 0; // measures the average looptime
-#endif
+// hasp_gui.cpp
extern uint16_t tft_width;
extern uint16_t tft_height;
+// main.cpp
+extern void setup();
+extern void loop();
+
#if defined(WINDOWS)
// https://gist.github.com/kingseva/a918ec66079a9475f19642ec31276a21
void BindStdHandlesToConsole()
@@ -110,106 +102,6 @@ void InitializeConsoleOutput()
}
#endif
-void setup()
-{
- // Initialize lvgl environment
- lv_init();
- lv_log_register_print_cb(debugLvglLogEvent);
-
- // Read & Apply User Configuration
-#if HASP_USE_CONFIG > 0
- configSetup();
-#endif
-
- haspDevice.init(); // hardware setup
- // hal_setup();
- guiSetup();
-
- dispatchSetup(); // for hasp and oobe
- haspSetup();
-
-#if HASP_USE_MQTT > 0
- mqttSetup(); // Hasp must be running
- mqttStart();
-#endif
-
-#if HASP_USE_GPIO > 0
- gpioSetup();
-#endif
-
-#if defined(HASP_USE_CUSTOM)
- custom_setup();
-#endif
-
- mainLastLoopTime = millis(); // - 1000; // reset loop counter
- // delay(250);
-}
-
-void loop()
-{
- haspLoop();
-#if HASP_USE_MQTT
- mqttLoop();
-#endif
-
- // debugLoop(); // Console
- haspDevice.loop();
- guiLoop();
-
-#if HASP_USE_GPIO > 0
- gpioLoop();
-#endif
-
-#if defined(HASP_USE_CUSTOM)
- custom_loop();
-#endif
-
-#ifdef HASP_USE_STAT_COUNTER
- statLoopCounter++; // measures the average looptime
-#endif
-
- /* Timer Loop */
- if(millis() - mainLastLoopTime >= 1000) {
- /* Runs Every Second */
- haspEverySecond(); // sleep timer
- dispatchEverySecond(); // sleep timer
-
-#if HASP_USE_ARDUINOOTA > 0
- otaEverySecond(); // progressbar
-#endif
-
-#if defined(HASP_USE_CUSTOM)
- custom_every_second();
-#endif
-
- /* Runs Every 5 Seconds */
- if(mainLoopCounter == 0 || mainLoopCounter == 5) {
-
- haspDevice.loop_5s();
-#if HASP_USE_GPIO > 0
- gpioEvery5Seconds();
-#endif
-
-#if HASP_USE_MQTT
- mqttEvery5Seconds(true);
-#endif
-
-#if defined(HASP_USE_CUSTOM)
- custom_every_5seconds();
-#endif
- }
-
- /* Reset loop counter every 10 seconds */
- if(mainLoopCounter >= 9) {
- mainLoopCounter = 0;
- } else {
- mainLoopCounter++;
- }
- mainLastLoopTime += 1000;
- }
- // delay(6);
-}
-
void usage(const char* progName, const char* version)
{
std::cout
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 1cae860e..1003bc6f 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -26,8 +26,8 @@ build_flags =
-D HASP_USE_SPIFFS=0
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
- -D HASP_USE_GPIO=1
- -D HASP_USE_CONFIG=0 ; Standalone application, as library
+ -D HASP_USE_GPIO=0
+ -D HASP_USE_CONFIG=1
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index dbe7f24c..c1e8d8dc 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -26,8 +26,8 @@ build_flags =
-D HASP_USE_LITTLEFS=0
-D LV_USE_FS_IF=1
-D HASP_USE_EEPROM=0
- -D HASP_USE_GPIO=1
- -D HASP_USE_CONFIG=0 ; Standalone application, as library
+ -D HASP_USE_GPIO=0
+ -D HASP_USE_CONFIG=1
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index 0344d2fc..e3a86401 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -20,8 +20,8 @@ build_flags =
-D HASP_USE_SPIFFS=0
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
- -D HASP_USE_GPIO=1
- -D HASP_USE_CONFIG=1 ; Standalone application, as library
+ -D HASP_USE_GPIO=0
+ -D HASP_USE_CONFIG=1
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index 0caaccca..a4a131e2 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -25,8 +25,8 @@ build_flags =
-D HASP_USE_SPIFFS=0
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
- -D HASP_USE_GPIO=1
- -D HASP_USE_CONFIG=1 ; Standalone application, as library
+ -D HASP_USE_GPIO=0
+ -D HASP_USE_CONFIG=1
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1
From a884fbf705e035eb00c3a76f5b4820176642dc62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Wed, 7 Feb 2024 19:30:17 +0100
Subject: [PATCH 073/135] Implement LVGL task for Windows GDI
---
src/dev/device.h | 3 ++
src/drv/tft/tft_driver_sdl2.cpp | 4 ++
src/drv/tft/tft_driver_win32drv.cpp | 66 ++++++++++++++++++++----
src/hasp_gui.cpp | 21 ++++++--
src/hasp_gui.h | 7 ++-
src/main_pc.cpp | 3 +-
user_setups/win32/windows_gdi_64bits.ini | 1 +
7 files changed, 87 insertions(+), 18 deletions(-)
diff --git a/src/dev/device.h b/src/dev/device.h
index 75039f34..a17ef6dd 100644
--- a/src/dev/device.h
+++ b/src/dev/device.h
@@ -30,6 +30,9 @@ class BaseDevice {
public:
bool has_battery = false;
bool has_backligth_control = true;
+#if HASP_TARGET_PC
+ bool pc_is_running = true;
+#endif
virtual void reboot()
{}
diff --git a/src/drv/tft/tft_driver_sdl2.cpp b/src/drv/tft/tft_driver_sdl2.cpp
index 82ca964d..c6c94651 100644
--- a/src/drv/tft/tft_driver_sdl2.cpp
+++ b/src/drv/tft/tft_driver_sdl2.cpp
@@ -75,6 +75,10 @@ void TftSdl::init(int32_t w, int h)
* You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed
* Create an SDL thread to do this*/
SDL_CreateThread(tick_thread, "tick", NULL);
+
+#if HASP_USE_LVGL_TASK
+#error "SDL2 LVGL task is not implemented"
+#endif
}
void TftSdl::show_info()
{
diff --git a/src/drv/tft/tft_driver_win32drv.cpp b/src/drv/tft/tft_driver_win32drv.cpp
index 38babbb9..25a85747 100644
--- a/src/drv/tft/tft_driver_win32drv.cpp
+++ b/src/drv/tft/tft_driver_win32drv.cpp
@@ -13,6 +13,7 @@
#include "dev/device.h"
#include "hasp_debug.h"
+#include "hasp_gui.h"
#ifdef HASP_CUSTOMIZE_BOOTLOGO
#include "custom/bootlogo.h" // Sketch tab header for xbm images
@@ -48,21 +49,66 @@ int32_t TftWin32Drv::height()
return _height;
}
+static void win32_message_loop(lv_task_t* param)
+{
+ MSG Message;
+#if HASP_USE_LVGL_TASK
+ while(haspDevice.pc_is_running && GetMessageW(&Message, NULL, 0, 0)) {
+ TranslateMessage(&Message);
+ DispatchMessageW(&Message);
+ }
+ // apparently GetMessageW doesn't deliver WM_QUIT
+ haspDevice.pc_is_running = false;
+#else
+ BOOL Result = PeekMessageW(&Message, NULL, 0, 0, TRUE);
+ if(Result != 0 && Result != -1) {
+ TranslateMessage(&Message);
+ DispatchMessageW(&Message);
+ if(Message.message == WM_QUIT) haspDevice.pc_is_running = false;
+ }
+#endif
+}
+
+static DWORD gui_entrypoint(HANDLE semaphore)
+{
+ /* Add a display
+ * Use the 'win32drv' driver which creates window on PC's monitor to simulate a display
+ * The following input devices are handled: mouse, keyboard, mousewheel */
+ lv_win32_init(0, SW_SHOWNORMAL, haspTft.width(), haspTft.height(), 0);
+ lv_win32_set_title(haspDevice.get_hostname());
+
+#if HASP_USE_LVGL_TASK
+ // let the init() function continue
+ ReleaseSemaphore(semaphore, 1, NULL);
+ // run the LVGL task as a thread
+ HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)gui_task, NULL, 0, NULL);
+ // run a blocking message loop on this thread
+ win32_message_loop(NULL);
+ // wait for the LVGL task now
+ WaitForSingleObject(thread, 4000);
+#else
+ // create a LVGL tick thread
+ CreateThread(NULL, 0, tick_thread, NULL, 0, NULL);
+ // create a LVGL task for the message loop
+ lv_task_create(win32_message_loop, 5, LV_TASK_PRIO_HIGHEST, NULL);
+#endif
+ return 0;
+}
+
void TftWin32Drv::init(int32_t w, int h)
{
_width = w;
_height = h;
- /* Add a display
- * Use the 'win32drv' driver which creates window on PC's monitor to simulate a display
- * The following input devices are handled: mouse, keyboard, mousewheel */
- lv_win32_init(0, SW_SHOWNORMAL, w, h, 0);
- lv_win32_set_title(haspDevice.get_hostname());
-
- /* Tick init.
- * You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed
- * Create a Windows thread to do this*/
- CreateThread(NULL, 0, tick_thread, NULL, 0, NULL);
+#if HASP_USE_LVGL_TASK
+ // run a thread for creating the window and running the message loop
+ HANDLE semaphore = CreateSemaphore(NULL, 0, 1, NULL);
+ HANDLE thread = CreateThread(NULL, 0, gui_entrypoint, semaphore, 0, NULL);
+ WaitForSingleObject(semaphore, INFINITE);
+#else
+ // do not use the gui_task(), just init the GUI and return
+ gui_entrypoint(NULL);
+#endif
}
void TftWin32Drv::show_info()
{
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index d39195e8..af4c8388 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -382,23 +382,34 @@ void guiEverySecond(void)
// nothing
}
-#if defined(ESP32) && defined(HASP_USE_ESP_MQTT)
-
#if HASP_USE_LVGL_TASK == 1
-static void gui_task(void* args)
+void gui_task(void* args)
{
LOG_TRACE(TAG_GUI, "Start to run LVGL");
- while(1) {
+ while(haspDevice.pc_is_running) {
+ // no idea what MQTT has to do with LVGL - the #if is copied from the code below
+#if defined(ESP32) && defined(HASP_USE_ESP_MQTT)
/* Try to take the semaphore, call lvgl related function on success */
- // if(pdTRUE == xSemaphoreTake(xGuiSemaphore, pdMS_TO_TICKS(10))) {
if(pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
lv_task_handler();
xSemaphoreGive(xGuiSemaphore);
vTaskDelay(pdMS_TO_TICKS(5));
}
+#else
+ // optimize lv_task_handler() by actually using the returned delay value
+ auto time_start = millis();
+ uint32_t sleep_time = lv_task_handler();
+ delay(sleep_time);
+ auto time_end = millis();
+ lv_tick_inc(time_end - time_start);
+#endif
}
}
+#endif // HASP_USE_LVGL_TASK
+#if defined(ESP32) && defined(HASP_USE_ESP_MQTT)
+
+#if HASP_USE_LVGL_TASK == 1
esp_err_t gui_setup_lvgl_task()
{
#if CONFIG_FREERTOS_UNICORE == 0
diff --git a/src/hasp_gui.h b/src/hasp_gui.h
index a95e877a..8b5b12af 100644
--- a/src/hasp_gui.h
+++ b/src/hasp_gui.h
@@ -60,6 +60,11 @@ uint32_t guiScreenshotEtag();
void gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
void gui_antiburn_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
+/* ===== Main LVGL Task ===== */
+#if HASP_USE_LVGL_TASK == 1
+void gui_task(void* args);
+#endif
+
/* ===== Locks ===== */
#ifdef ESP32
IRAM_ATTR bool gui_acquire(TickType_t timeout);
@@ -73,4 +78,4 @@ bool guiGetConfig(const JsonObject& settings);
bool guiSetConfig(const JsonObject& settings);
#endif // HASP_USE_CONFIG
-#endif // HASP_GUI_H
\ No newline at end of file
+#endif // HASP_GUI_H
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 2b4f7362..cb6f7c03 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -189,8 +189,7 @@ int main(int argc, char* argv[])
loop();
}
#elif USE_WIN32DRV
- extern bool lv_win32_quit_signal;
- while(!lv_win32_quit_signal) {
+ while(haspDevice.pc_is_running) {
loop();
}
#endif
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index e3a86401..039c4004 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -29,6 +29,7 @@ build_flags =
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
-D HASP_USE_SYSLOG=0
+ -D HASP_USE_LVGL_TASK=1
-D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
From e922042a3deaf3559a3a604af7907e5d0acbbb23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Wed, 7 Feb 2024 23:12:23 +0100
Subject: [PATCH 074/135] Fix disk access path separator on Linux
---
src/dev/posix/hasp_posix.cpp | 10 +++++-----
src/hasp/hasp_dispatch.cpp | 8 ++++++--
src/hasp/hasp_page.cpp | 4 ++++
src/hasp_debug.cpp | 1 +
src/main_pc.cpp | 26 +++++++++++++++-----------
5 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index a70ff4e2..af392e62 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -62,11 +62,11 @@ void PosixDevice::show_info()
if(uname(&uts) < 0) {
LOG_ERROR(0, "uname() error");
} else {
- LOG_VERBOSE(0, "Sysname: %s", uts.sysname);
- LOG_VERBOSE(0, "Nodename: %s", uts.nodename);
- LOG_VERBOSE(0, "Release: %s", uts.release);
- LOG_VERBOSE(0, "Version: %s", uts.version);
- LOG_VERBOSE(0, "Machine: %s", uts.machine);
+ LOG_VERBOSE(0, "Sysname : %s", uts.sysname);
+ LOG_VERBOSE(0, "Nodename : %s", uts.nodename);
+ LOG_VERBOSE(0, "Release : %s", uts.release);
+ LOG_VERBOSE(0, "Version : %s", uts.version);
+ LOG_VERBOSE(0, "Machine : %s", uts.machine);
}
LOG_VERBOSE(0, "Processor : %s", "unknown");
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index db7ffdf4..1124a76d 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -800,7 +800,11 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
path[0] = '.';
path[1] = '\0';
strcat(path, filename);
+#if defined(WINDOWS)
path[1] = '\\';
+#elif defined(POSIX)
+ path[1] = '/';
+#endif
LOG_TRACE(TAG_HASP, F("Loading %s from disk..."), path);
std::ifstream f(path); // taking file as inputstream
@@ -1323,8 +1327,8 @@ void dispatch_current_state(uint8_t source)
bool dispatch_factory_reset()
{
bool formatted = true;
- bool erased = true;
- bool cleared = true;
+ bool erased = true;
+ bool cleared = true;
#if ESP32
erased = nvs_clear_user_config();
diff --git a/src/hasp/hasp_page.cpp b/src/hasp/hasp_page.cpp
index bb970e57..50b80343 100644
--- a/src/hasp/hasp_page.cpp
+++ b/src/hasp/hasp_page.cpp
@@ -244,7 +244,11 @@ void Page::load_jsonl(const char* pagesfile)
path[0] = '.';
path[1] = '\0';
strcat(path, pagesfile);
+#if defined(WINDOWS)
path[1] = '\\';
+#elif defined(POSIX)
+ path[1] = '/';
+#endif
LOG_TRACE(TAG_HASP, F("Loading %s from disk..."), path);
std::ifstream f(path); // taking file as inputstream
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index 421606cc..2adfd826 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -29,6 +29,7 @@
#if defined(POSIX)
#include
+#include
#define cwd getcwd
#endif
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index cb6f7c03..50690677 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -17,6 +17,7 @@
#if defined(POSIX)
#include
#include
+#include
#define cwd getcwd
#define cd chdir
#endif
@@ -104,17 +105,20 @@ void InitializeConsoleOutput()
void usage(const char* progName, const char* version)
{
- std::cout
- << "\n"
- << progName << " " << version << " [options]" << std::endl
- << std::endl
- << "Options:" << std::endl
- << " -h | --help Print this help" << std::endl
- << " -W | --width Width of the window" << std::endl
- << " -H | --height Height of the window" << std::endl
- << " -C | --config Configuration directory (default: '~/.local/share/hasp' or 'AppData\\hasp\\hasp')"
- << std::endl
- << std::endl;
+ std::cout << "\n"
+ << progName << " " << version << " [options]" << std::endl
+ << std::endl
+ << "Options:" << std::endl
+ << " -h | --help Print this help" << std::endl
+ << " -W | --width Width of the window" << std::endl
+ << " -H | --height Height of the window" << std::endl
+ << " -C | --config Configuration directory" << std::endl
+#if defined(WINDOWS)
+ << " (default: 'AppData\\hasp\\hasp')" << std::endl
+#elif defined(POSIX)
+ << " (default: '~/.local/share/hasp/hasp')" << std::endl
+#endif
+ << std::endl;
fflush(stdout);
}
From 51f35e7d3602d2a619e6f11350eb735767ad02a7 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Thu, 8 Feb 2024 14:21:41 +0100
Subject: [PATCH 075/135] wireguard - allow to set hostname for the remote peer
WireGuard-ESP32 library uses lwip_getaddrinfo() call to resolve
IP/hostname string, so it should work.
---
src/sys/net/hasp_wireguard.cpp | 2 +-
src/sys/svc/hasp_http.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sys/net/hasp_wireguard.cpp b/src/sys/net/hasp_wireguard.cpp
index 36b05515..c2ca170a 100644
--- a/src/sys/net/hasp_wireguard.cpp
+++ b/src/sys/net/hasp_wireguard.cpp
@@ -12,7 +12,7 @@
char wg_ip[16] = WIREGUARD_IP;
char wg_private_key[45] = WIREGUARD_PRIVATE_KEY;
-char wg_ep_ip[16] = WIREGUARD_EP_IP;
+char wg_ep_ip[40] = WIREGUARD_EP_IP;
uint16_t wg_ep_port = WIREGUARD_EP_PORT;
char wg_ep_public_key[45] = WIREGUARD_EP_PUBLIC_KEY;
static WireGuard wg;
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index e3737309..1f78c7f8 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -2357,7 +2357,7 @@ static void http_handle_wireguard()
From 28152302b15a1b7433ed21feb31d124cb72eef68 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 16:28:12 +0100
Subject: [PATCH 076/135] Update root CA certificates
---
data/cert/x509_crt_bundle.bin | Bin 63694 -> 66563 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/data/cert/x509_crt_bundle.bin b/data/cert/x509_crt_bundle.bin
index 77d8ea3e85b3c2b257ffe256f6231d116a0cc7b8..c4c74b8996dd1ad9ae6c80fb858e8ed7a6d8a6b8 100644
GIT binary patch
delta 5528
zcmb_gWmr`0x~5BEaF7y&p=*GlL2~G!J4J+{TNp}^VWb5lhVCxukd_W5z~V
zbo=T4&iVFr&fe!-`H*So_w+zmTj{vEB0#?$a!`wy
z)PWcpSgij79mQYZ>F7fL0*@Y@p9?|;lJxqv<3>HJ&d*e5R3AQsCaW7SPkuLuNI_
zUr7|Fl%`DQ6Pd_+a&nD!bN{Le_<-*Mf!}n_`njoRd7yr3yhZvbC*`yGn6C{;haE~4
zD|Q=l4kxT5$LW@Qfdv!WV%*gZ>(><3r2C^<0&m^4_NZT04;&**9p(FBCZomi$CyeFEs$xOTTn9$sB9E?{m5&@I@0D-^w4Zd)tGQfR7OxL
zw%bV+V!xk6c(Z-4%cD5KWH{dHc@ajJTdoV3W5vjD&%{5~k)Q_hqdr
zM`F;nP;@a&xfq~E9XD~>fla#nq>e`Gh*$;)A^n5iM7Ig$T%DbD;jV7hd|VKY-;`(k
zk9Qy~PfI6z_;33EBK#lZ=Z5g18Pcebs>0iqhL1|zW+!40mfk&&o|dh@&O7qC!3r>3
zjPuQKYSszYYvaXv(=>WUI?1uuFp<-97~w|Us%_mTm(i0B&jbZY;oT~dl@Ga7tnz?+
zd&Z7eSwoi#Us}Drx!haK5JT&y6gBv6K?wiAg-3>^ugmur;6ncna{gb)eITeUINkd0
z6K%jbKK_tcs=vlGU<3lW6=Q>z8gK6lZNIE(te2|CA3RCoJJ~PLyvWyx<{&p}ns!AV
zI59R^&9wcX%*1{7gqX7#xoc=o6p2Mjxw1KWk!mKmya=YW5JH!iPz>R03*|=;a$x_?e{Z6>-
zU08r^D(AiS47{mg*jGJVM<>Y9F81_}q=Q%Y@I7{zI?`(SitD3C5b8%9c6&nW=cbn#
z{P5B2Ry$NpuxXWWhxfsK$vWu3KrkAoONw{PXV9--`;-W!Wkc_d71oa>5YQ4<7_5JM4NFtmfm7+?WPo{k
z&_9eQtNbnaI9bt^5xwVEhHAfv}H@%7MK$-
z7s>5Ad?k71Q@sh!MxIG!KVJT#ydA4RhpX*#4-5o9WG^SqW6BbY!QIFc7`x+5HbqiE
zCrckX>h^t(hg|Z0Ytyl=;rvKHf+K^fPS{hF2cVaG5l1Rp1cvxaw|V8oT?fq((i*RQP}stlRULP^gyKhSk2aE^)>zUWS^a
zzmUxB>ldIlyV>SQ`=vxk*LXtgTduKqStDcHn*=set0+yJ8gke*3EV$D74);j{ervl(^(4$-8E&xffiCiOj!qKh;d#&
zBgrudVp8^4-sJNr%UAvb?tSj*y$DV4XA9sh?O}*t(
zk{`4`1DUgo=l<;wKbcSrg{V3gG`?d<)NR_u{FToG^1MH@1?ybOU*0^3_~d92WKTh;
zwK}E$dO6VD%SBD8(No{JUKcT!&=0LJdckJ{pv$A-kkR1%xUCnG-z8INHOEoCNg)avItwHI)6dyRWw&BJD+#Z0hVT$k`8@-xrXNm}s`>xa9*C
z7W-Q?zI9KWm*}uLyZAOlUHe6KQK%gRBHtW(y@Bci1u9KMWnaw#q@dAW`25qaBF;2y
z=W1j7por-jxZ0essug8;s9oK|3#EE5?N7)hD&L+vramaBn&h
z^eoge+AcfKwPik~HxqE;VNEm9lFe+-&-Yh99rj~O|F%4>$h=Rg3Rf+}jcIAR&sB64
zw;He0zPD?e?3~7(jpE0(<^QHkAU(&@M1aG>`%4FPy^o;ybtv0w?7AywZ#+hWpGmIw
zmkuJQ!N&?={>`%cvI;O282U~u6&>Gw2+eP0+?7@N$txu%S4#`0KUMK7yN_%L+UNSn
zErx?}poR7#-uJtz{jPevm1D`=ttOlNV}&xQe8bn0F(s5x$0T_v#97iJ%ha{8$BMM^
zH4iMtt{N4yutR4BT=vfuqP#?wT$19>X9KvxD5oQZ4ua#{4Hq8w^fYe{*fKL|!inH#
zHqTV`i=}<6VD`Y|Wi{gWNWvU`$b+lw&f|LRQ+*TicWLu2rqeeiGMfXHe`
z+6dyyreTCBe)r&4p-C(F(`}bD_8Ca~2F)UQRq#&6z|bkl&aoK>GAzd4L+lL?v#SC_
zdEb;h3tmvgQ{@mcFfm?}ldr*bzAZoM)Ua^KP}Y9?A+yDoRS1=ae2Tv7({A(!>eoyD
zN-yqcz?A0M6R>V2sDLkl6PjCm0Zvalilo!UB(W&+sp@RYO{Kv>T()AUhs^;A(^iXF
zF)o!`{-*V_4ob?i$bh;j?w1B$8sqjyF7i%O%sbJ{xl|qPhTlt5g&O8by_+PJTV}d8
zkC>!pKZRtnNleMK6Wwk<-Hc|LK_S8vr#L+GWS!1EA~v6OJXN88&-j*HfBciHzy3r)
zB>o){^PnPD!y-)6fbT|j_@&!V=bE>EXwkpwuJ0V%+PML=M}yUy+MfKjT7#dx_J8IS
z{lDhaFPD9sIUE=lt!vxRtW|@3u@0k$G7?s6>ln>&3C8pR74P;%@`8hZfL%(aj|kVW
z8SeJVN&0tzdsQ7&Mz_P3pPezjxl++?g1op{S)u|GohdbLQg*Ptn1ZS$Njy&Kx*?~n
zb3@SLYy2er-<_Z6Htnxn80ukf0n)RE+qt+px!T%Wdw@YO7dQ_eGlcQC3~2uIvwzeA
zND18)$cXIZdu|c`Ie~_V(|Y0!UTK)PHgLxcTDkfSu|pKyT&K1W(@3VHsYkT}_DGED
zvk`X~FNZsa=^maRi8bcP!K-_*%?wL7<;Qw+gRIZAq-p{vnjXBsnnR@ss7&G*M=^eJeGm`W$Wp0H|Cq$lK}JtwJTfgM&jwBu1rq^X50t^{~y2
z-=D|%3`BZ6P^`m3Vinxoc;n12q^xCbQ6p2|vVu(Px`aA3i?xqF+~G1^PRn8!Cwf3c
z--TM|IV@_nFAPuEa3n)cT1iW0xGApZh4>i-vn})nO4+8R4W#jrK=w8$WfJEU_A!&n
zI&Pn+PQuU0j5?c6u51_6pE;}i;8$y45&uDJ3kYE}#*K@EdZQ*n)WS%g{K%4{skBe@
zr2#xttj6-a&vMx=2G{o#kwLITh+jz
zs?_0f%6YD&A%7kH)q5+F28X;91Xtv3>8(l|(g!6gYEh@}g)c?TUb&?y5wD`4c)PI6
zYK}#LJ*`5dFGmw7rOwaq`7QX*LCpU$h>|SdpM``Bplc0B*xR~-)a;$@fBs406NU)>
z5(*jjpC^CcwRNrCy{z3qP)~%NwF|-?Zh^3Ob@?463WCDF)>p5q)KVAF{^hLq8oqeR
zyrjA4)+_xY1I-!bojoLXSx;@B?_R0}lGJwq%j6PAU|E+qQRw6Kon
z2TZ0MS|wT70sM6%!%c7Ev@#c~|6N_ukG?ltjobxO;Hw?}MOb%pJ3v{|&m={!D$9%y
zp^1O3#jsc~Zl_5DggdjOs&S^CC_^l+Q2unq1S$(sT(tC5YER09qAD(2w!~HD))TO1
zB7(`voCh@pMzoSd;sqAWk>Q)!dUMK$DRMJ5H`$b;a($TEw`SLv0C&wy?{2ETS^PTq
z5nE((Ml6>>8xmCQJPXlCGL1WQV}8}4fU=S!ZfAJFE3utLJPc}(WgGeEntosfi4_|~
zTca5G8kn>ML>SjZ_b>P$BMRRwFDK3TePzQwIgA)k%czf)wO%%OAz=weY!`8bLF;&R
zaFW1R-XvEmjPA>Gq`$v)gMuj~`G6tt@ig}l6owaDUkI>i?r%~NyPdm+4kypc*S
z@7CkrmLb+zzv6fv#KL4a2Mk9eM)3MDNn3>#^4}NL>39{rKYN==me^ehxM6tE&qx
zl`n{e%e!o9|e|}z{zrOG9=NZplNlT1O^j_o
z)4Wou9Bl1fG?lbHXdu!*no4tRd?kEF1N}v
zpJ(BS@}_PR62N3wCYO*T<9djw^QcJ8x+CUpepwEae)Cx|xz1?uZ3j?usvkVQtYbm3
zN_ZZr{1g)9sFxE!s~rNkY2OHLIio@S>}ff&@SJZ9BIR%q9@H@aVgxp?SJu(%i$tR&
zT_xsxxaDbkE>d(0Tr4A@~q#sUQR`S|(F0C3iVwkg|M!&QpCX#Giy<$Xb#
z6;8|(vIfAB=UF|e>g*iPUBX9yptSl2N^>ie6!O3hR}e(p#u$Cx5^75g@TVcX2{cx4
ziV8o9rT9XT$!2de`zTcl2SOZ*z!ZA?32d|bpBD4+i_1qsR=>}yew>|s?CcK9%JMm;
z4JTO(-GYz2mG$&%%L+}2`NGq3#fQ!?bu?gT!yG)&-8CX8nPm@uR
zkxF96h0Q5m1!nF`k9~vJXrw6H=Qzx_wAg=B>nUUoCp|kfm{__zbhsj8(pPh(R{LSL
zP6ixZkl$$LNVPbGjOD+ucJ7JnReNIPD0*rIV9(saJfl+?O}jX&Lr;V6%L3%tKjW6=YnEv;zSO4$FLUA@mP`Wyc3sGd=Auh(%QU5hB
z^5V*yKJ=&?r#MQ}d?_)aVP6ww#!zxuj}v4}Ek@kR~iwM1M216qn_A%
zlYVO2)vmp+f~it&(lxE4SOWr0nmdj}oWh<>+Y9n2%Kz@nC;Xx#`OuI(ESs4T*uV#<0zR<-Q4pkdgFI59RwFdIs;e$G
z@G&+}(jxo8kVvVR!}{6i#SXzIF0M`!l1a8#NK7-Dpu12)0b8?g2+pk8S!MNqHxT^G
zKtrVdPXocHcRYHY`?rE;NMurLE{OuQC3t!JkbOK!WCE20r4yj0q+kkx_A?nFT5}M;
zOcVwG$3znnhP=
ziC!Z{Jkyt#5G_wjN~Opc_TCa}2=MMG^U7+8LRG#*cYZp0awa*$i~skxyUlmqbxx&4
zqx-_|=l|w>pFQW+c_1tBEVCnj&Gu^dhvbZ-kDUzxV0X!u8rCcB5`@?dW-RoksFYvK
z+lxc`OD83B6NK+@8q62x6!w?SAMPqN;mN=j*t^k>k10KBJ?7Fc%X4*a;;`IQN(_{j
zlH~hTt%M5fhC8RVY+5pN5^OJDhd)>kO$?cA%ORezyM~#rzK}>0Qi%NFtyhp<*%%;?hsR+XI`o&$x
z8RzH7(J@V>#od#e94`C*2VLv=PDltpGitZ1_01dzxE4`lv7zOw;gkLn0X}Qj`f}41
zP%t*&p5Vmh2bD2vKp4sI3n_-GN%i6kSJ&owJ7!Q_ftF>*qC2S2(%UIbmGvy6qmq{G6Rd7kftX@a}VEgI7UU
wNt<8
From ce116273081004c63f51901163654090a5c53f88 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 16:35:44 +0100
Subject: [PATCH 077/135] Add root CA cert bundle to src
---
src/hasp/hasp_attribute.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp
index f99a6e14..c40063d0 100644
--- a/src/hasp/hasp_attribute.cpp
+++ b/src/hasp/hasp_attribute.cpp
@@ -19,6 +19,9 @@ LV_FONT_DECLARE(unscii_8_icon);
extern const char** btnmatrix_default_map; // memory pointer to lvgl default btnmatrix map
extern const char* msgbox_default_map[]; // memory pointer to lvgl default btnmatrix map
+extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_bundle_bin_start");
+extern const uint8_t rootca_crt_bundle_end[] asm("_binary_data_cert_x509_crt_bundle_bin_end");
+
void my_image_release_resources(lv_obj_t* obj)
{
if(!obj) return;
@@ -1345,7 +1348,7 @@ static hasp_attribute_type_t special_attribute_src(lv_obj_t* obj, const char* pa
#if defined(ARDUINO) && defined(ARDUINO_ARCH_ESP32)
#if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0
HTTPClient http;
- http.begin(payload);
+ http.begin(payload, (const char*)rootca_crt_bundle_start);
http.setTimeout(5000);
http.setConnectTimeout(5000);
From ac5fe4a4249452d210621ab246ba676875659baa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Thu, 8 Feb 2024 16:37:14 +0100
Subject: [PATCH 078/135] Add POSIX fbdev port
---
include/hasp_conf.h | 8 +-
src/dev/posix/hasp_posix.cpp | 44 ++++---
src/dev/posix/hasp_posix.h | 3 +
src/dev/win32/hasp_win32.cpp | 48 ++++++--
src/dev/win32/hasp_win32.h | 35 +-----
src/drv/tft/tft_driver.h | 3 +
src/drv/tft/tft_driver_posix_fbdev.cpp | 117 +++++++++++++++++++
src/drv/tft/tft_driver_posix_fbdev.h | 44 +++++++
src/drv/tft/tft_driver_win32drv.cpp | 2 +-
src/main_pc.cpp | 14 +--
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 1 -
user_setups/linux_sdl/linux_fbdev_64bits.ini | 98 ++++++++++++++++
user_setups/linux_sdl/linux_sdl_64bits.ini | 1 -
user_setups/win32/windows_gdi_64bits.ini | 1 -
user_setups/win32/windows_sdl_64bits.ini | 1 -
15 files changed, 352 insertions(+), 68 deletions(-)
create mode 100644 src/drv/tft/tft_driver_posix_fbdev.cpp
create mode 100644 src/drv/tft/tft_driver_posix_fbdev.h
create mode 100644 user_setups/linux_sdl/linux_fbdev_64bits.ini
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index dece01d1..dc6eca52 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -377,7 +377,11 @@ static WiFiSpiClass WiFi;
#endif
#if defined(POSIX)
+#ifdef USE_MONITOR
#define delay SDL_Delay
+#else
+#define delay msleep
+#endif
#endif
#if HASP_TARGET_PC
@@ -398,8 +402,10 @@ static WiFiSpiClass WiFi;
#define halRestartMcu()
#if USE_MONITOR
#define millis SDL_GetTicks
-#elif USE_WIN32DRV
+#elif defined(WINDOWS)
#define millis Win32Millis
+#elif defined(POSIX)
+#define millis PosixMillis
#endif
#define DEC 10
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index af392e62..ef4fc10b 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -19,7 +19,13 @@
#include "hasp_conf.h"
#include "hasp_debug.h"
+#ifdef USE_MONITOR
#include "display/monitor.h"
+#elif USE_FBDEV
+#include "display/fbdev.h"
+#endif
+
+#include
// extern monitor_t monitor;
@@ -35,12 +41,6 @@ PosixDevice::PosixDevice()
_core_version = "unknown";
_chip_model = "unknown";
} else {
- // LOG_VERBOSE(0,"Sysname: %s", uts.sysname);
- // LOG_VERBOSE(0,"Nodename: %s", uts.nodename);
- // LOG_VERBOSE(0,"Release: %s", uts.release);
- // LOG_VERBOSE(0,"Version: %s", uts.version);
- // LOG_VERBOSE(0,"Machine: %s", uts.machine);
-
char version[256];
snprintf(version, sizeof(version), "%s %s", uts.sysname, uts.release);
_core_version = version;
@@ -69,8 +69,9 @@ void PosixDevice::show_info()
LOG_VERBOSE(0, "Machine : %s", uts.machine);
}
- LOG_VERBOSE(0, "Processor : %s", "unknown");
- LOG_VERBOSE(0, "CPU freq. : %i MHz", 0);
+ LOG_VERBOSE(0, "Processor : %s", get_chip_model());
+ LOG_VERBOSE(0, "CPU freq. : %i MHz", get_cpu_frequency());
+ LOG_VERBOSE(0, "OS Version : %s", get_core_version());
}
const char* PosixDevice::get_hostname()
@@ -81,8 +82,11 @@ const char* PosixDevice::get_hostname()
void PosixDevice::set_hostname(const char* hostname)
{
_hostname = hostname;
+#if USE_MONITOR
monitor_title(hostname);
- // SDL_SetWindowTitle(monitor.window, hostname);
+#elif USE_FBDEV
+ // fbdev doesn't really have a title bar
+#endif
}
const char* PosixDevice::get_core_version()
@@ -146,13 +150,11 @@ void PosixDevice::update_backlight()
{
uint8_t level = _backlight_power ? _backlight_level : 0;
if(_backlight_invert) level = 255 - level;
+#if USE_MONITOR
monitor_backlight(level);
- // SDL_SetTextureColorMod(monitor.texture, level, level, level);
- // window_update(&monitor);
- // monitor.sdl_refr_qry = true;
- // monitor_sdl_refr(NULL);
- // const lv_area_t area = {1,1,0,0};
- // monitor_flush(NULL,&area,NULL);
+#elif USE_FBDEV
+ // set display backlight, if possible
+#endif
}
size_t PosixDevice::get_free_max_block()
@@ -221,6 +223,18 @@ long PosixDevice::get_uptime()
} // namespace dev
+long PosixMillis()
+{
+ struct timespec spec;
+ clock_gettime(CLOCK_REALTIME, &spec);
+ return (spec.tv_sec) * 1000 + (spec.tv_nsec) / 1e6;
+}
+
+void msleep(unsigned long millis)
+{
+ usleep(millis * 1000);
+}
+
dev::PosixDevice haspDevice;
#endif // POSIX
diff --git a/src/dev/posix/hasp_posix.h b/src/dev/posix/hasp_posix.h
index 9dc8ad9f..73a8a49c 100644
--- a/src/dev/posix/hasp_posix.h
+++ b/src/dev/posix/hasp_posix.h
@@ -71,6 +71,9 @@ class PosixDevice : public BaseDevice {
} // namespace dev
+extern long PosixMillis();
+extern void msleep(unsigned long millis);
+
using dev::PosixDevice;
extern dev::PosixDevice haspDevice;
diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp
index 213b8801..6f7576de 100644
--- a/src/dev/win32/hasp_win32.cpp
+++ b/src/dev/win32/hasp_win32.cpp
@@ -25,11 +25,33 @@ static inline void native_cpuid(unsigned int* eax, unsigned int* ebx, unsigned i
asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "0"(*eax), "2"(*ecx) : "memory");
}
-void Win32Device::reboot()
-{}
-
-void Win32Device::show_info()
+Win32Device::Win32Device()
{
+ char buffer[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD length = sizeof(buffer);
+
+ if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameNetBIOS, buffer, &length)) {
+ _hostname = buffer;
+ } else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameDnsHostname, buffer, &length)) {
+ _hostname = buffer;
+ } else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsHostname, buffer, &length)) {
+ _hostname = buffer;
+ } else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsDomain, buffer, &length)) {
+ _hostname = buffer;
+ } else {
+ _hostname = "localhost";
+ }
+
+ // Get the Windows version.
+ DWORD dwBuild = 0;
+ DWORD dwVersion = GetVersion();
+ DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+ DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
+ if(dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion));
+
+ char version[128];
+ snprintf(version, sizeof(version), "Windows %d.%d.%d", dwMajorVersion, dwMinorVersion, dwBuild);
+ _core_version = version;
unsigned int eax, ebx, ecx, edx;
eax = 0;
@@ -39,9 +61,21 @@ void Win32Device::show_info()
memcpy(vendor, &ebx, 4);
memcpy(vendor + 4, &edx, 4);
memcpy(vendor + 8, &ecx, 4);
- vendor[12] = '\0';
+ vendor[12] = '\0';
+ _chip_model = vendor;
- LOG_VERBOSE(0, F("Processor : %s"), vendor);
+ // _backlight_pin = -1;
+ _backlight_power = 1;
+ _backlight_invert = 0;
+ _backlight_level = 255;
+}
+
+void Win32Device::reboot()
+{}
+
+void Win32Device::show_info()
+{
+ LOG_VERBOSE(0, F("Processor : %s"), get_chip_model());
LOG_VERBOSE(0, F("CPU freq. : %i MHz"), get_cpu_frequency());
LOG_VERBOSE(0, F("OS Version : %s"), get_core_version());
}
@@ -66,7 +100,7 @@ const char* Win32Device::get_core_version()
const char* Win32Device::get_chip_model()
{
- return "SDL2";
+ return _chip_model.c_str();
}
const char* Win32Device::get_hardware_id()
diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h
index e4b11746..1a25106d 100644
--- a/src/dev/win32/hasp_win32.h
+++ b/src/dev/win32/hasp_win32.h
@@ -18,39 +18,7 @@ namespace dev {
class Win32Device : public BaseDevice {
public:
- Win32Device()
- {
- char buffer[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD length = sizeof(buffer);
-
- if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameNetBIOS, buffer, &length)) {
- _hostname = buffer;
- } else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameDnsHostname, buffer, &length)) {
- _hostname = buffer;
- } else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsHostname, buffer, &length)) {
- _hostname = buffer;
- } else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsDomain, buffer, &length)) {
- _hostname = buffer;
- } else {
- _hostname = "localhost";
- }
-
- // Get the Windows version.
- DWORD dwBuild = 0;
- DWORD dwVersion = GetVersion();
- DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
- DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
- if(dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion));
-
- char version[128];
- snprintf(version, sizeof(version), "Windows %d.%d.%d", dwMajorVersion, dwMinorVersion, dwBuild);
- _core_version = version;
-
- // _backlight_pin = -1;
- _backlight_power = 1;
- _backlight_invert = 0;
- _backlight_level = 255;
- }
+ Win32Device();
void reboot() override;
void show_info() override;
@@ -80,6 +48,7 @@ class Win32Device : public BaseDevice {
private:
std::string _hostname;
std::string _core_version;
+ std::string _chip_model;
uint8_t _backlight_pin;
uint8_t _backlight_level;
diff --git a/src/drv/tft/tft_driver.h b/src/drv/tft/tft_driver.h
index 914597a8..4a9dff48 100644
--- a/src/drv/tft/tft_driver.h
+++ b/src/drv/tft/tft_driver.h
@@ -83,6 +83,9 @@ class BaseTft {
#elif USE_WIN32DRV && HASP_TARGET_PC
// #warning Building for Win32Drv
#include "tft_driver_win32drv.h"
+#elif USE_FBDEV && HASP_TARGET_PC
+// #warning Building for POSIX fbdev
+#include "tft_driver_posix_fbdev.h"
#else
// #warning Building for Generic Tfts
using dev::BaseTft;
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
new file mode 100644
index 00000000..ba584b01
--- /dev/null
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -0,0 +1,117 @@
+/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+ For full license information read the LICENSE file in the project folder */
+
+#if USE_FBDEV && HASP_TARGET_PC
+
+#include "hasplib.h"
+#include "lvgl.h"
+
+#include "display/fbdev.h"
+
+#include "drv/tft/tft_driver.h"
+#include "tft_driver_posix_fbdev.h"
+
+#include "dev/device.h"
+#include "hasp_debug.h"
+#include "hasp_gui.h"
+
+#ifdef HASP_CUSTOMIZE_BOOTLOGO
+#include "custom/bootlogo.h" // Sketch tab header for xbm images
+#else
+#include "custom/bootlogo_template.h" // Sketch tab header for xbm images
+#endif
+
+#include
+
+namespace dev {
+
+/**
+ * A task to measure the elapsed time for LittlevGL
+ * @param data unused
+ * @return never return
+ */
+static void* tick_thread(void* data)
+{
+ (void)data;
+
+ while(1) {
+ usleep(5000); /*Sleep for 5 millisecond*/
+ lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
+ }
+
+ return 0;
+}
+
+int32_t TftFbdevDrv::width()
+{
+ return _width;
+}
+int32_t TftFbdevDrv::height()
+{
+ return _height;
+}
+
+static void* gui_entrypoint(void* arg)
+{
+#if HASP_USE_LVGL_TASK
+#error "fbdev LVGL task is not implemented"
+#else
+ // create a LVGL tick thread
+ pthread_t thread;
+ pthread_create(&thread, 0, tick_thread, NULL);
+#endif
+ return 0;
+}
+
+void TftFbdevDrv::init(int32_t w, int h)
+{
+ /* Add a display
+ * Use the 'fbdev' driver which uses POSIX framebuffer device as a display
+ * The following input devices are handled: mouse, keyboard, mousewheel */
+ fbdev_init();
+ fbdev_get_sizes((uint32_t*)&_width, (uint32_t*)&_height);
+
+#if HASP_USE_LVGL_TASK
+#error "fbdev LVGL task is not implemented"
+#else
+ // do not use the gui_task(), just init the GUI and return
+ gui_entrypoint(NULL);
+#endif
+}
+void TftFbdevDrv::show_info()
+{
+ splashscreen();
+
+ LOG_VERBOSE(TAG_TFT, F("Driver : %s"), get_tft_model());
+}
+
+void TftFbdevDrv::splashscreen()
+{
+ uint8_t fg[] = logoFgColor;
+ uint8_t bg[] = logoBgColor;
+ lv_color_t fgColor = lv_color_make(fg[0], fg[1], fg[2]);
+ lv_color_t bgColor = lv_color_make(bg[0], bg[1], bg[2]);
+ // TODO show splashscreen
+}
+void TftFbdevDrv::set_rotation(uint8_t rotation)
+{}
+void TftFbdevDrv::set_invert(bool invert)
+{}
+void TftFbdevDrv::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
+{
+ fbdev_flush(disp, area, color_p);
+}
+bool TftFbdevDrv::is_driver_pin(uint8_t pin)
+{
+ return false;
+}
+const char* TftFbdevDrv::get_tft_model()
+{
+ return "POSIX fbdev";
+}
+
+} // namespace dev
+
+dev::TftFbdevDrv haspTft;
+
+#endif // WINDOWS || POSIX
diff --git a/src/drv/tft/tft_driver_posix_fbdev.h b/src/drv/tft/tft_driver_posix_fbdev.h
new file mode 100644
index 00000000..5856f892
--- /dev/null
+++ b/src/drv/tft/tft_driver_posix_fbdev.h
@@ -0,0 +1,44 @@
+/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+ For full license information read the LICENSE file in the project folder */
+
+#ifndef HASP_FBDEV_DRIVER_H
+#define HASP_FBDEV_DRIVER_H
+
+#include "tft_driver.h"
+
+#if USE_FBDEV && HASP_TARGET_PC
+// #warning Building H driver FBDEV
+
+#include "lvgl.h"
+
+namespace dev {
+
+class TftFbdevDrv : BaseTft {
+ public:
+ void init(int w, int h);
+ void show_info();
+ void splashscreen();
+
+ void set_rotation(uint8_t rotation);
+ void set_invert(bool invert);
+
+ void flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
+ bool is_driver_pin(uint8_t pin);
+
+ const char* get_tft_model();
+
+ int32_t width();
+ int32_t height();
+
+ private:
+ int32_t _width, _height;
+};
+
+} // namespace dev
+
+using dev::TftFbdevDrv;
+extern dev::TftFbdevDrv haspTft;
+
+#endif // HASP_TARGET_PC
+
+#endif // HASP_FBDEV_DRIVER_H
diff --git a/src/drv/tft/tft_driver_win32drv.cpp b/src/drv/tft/tft_driver_win32drv.cpp
index 25a85747..9e32cb59 100644
--- a/src/drv/tft/tft_driver_win32drv.cpp
+++ b/src/drv/tft/tft_driver_win32drv.cpp
@@ -114,7 +114,7 @@ void TftWin32Drv::show_info()
{
splashscreen();
- LOG_VERBOSE(TAG_TFT, F("Driver : Win32Drv"));
+ LOG_VERBOSE(TAG_TFT, F("Driver : %s"), get_tft_model());
}
void TftWin32Drv::splashscreen()
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 50690677..c6190c7a 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -18,6 +18,8 @@
#include
#include
#include
+#include
+#include
#define cwd getcwd
#define cd chdir
#endif
@@ -178,25 +180,23 @@ int main(int argc, char* argv[])
SDL_Init(0); // Needs to be initialized for GetPerfPath
strcpy(config, SDL_GetPrefPath("hasp", "hasp"));
SDL_Quit(); // We'll properly init later
-#elif USE_WIN32DRV
+#elif defined(WINDOWS)
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, config))) {
PathAppendA(config, "hasp");
PathAppendA(config, "hasp");
}
+#elif defined(POSIX)
+ struct passwd* pw = getpwuid(getuid());
+ strcpy(config, pw->pw_dir);
+ strcat(config, "/.local/share/hasp/hasp");
#endif
}
cd(config);
setup();
-#if USE_MONITOR
- while(1) {
- loop();
- }
-#elif USE_WIN32DRV
while(haspDevice.pc_is_running) {
loop();
}
-#endif
end:
#if defined(WINDOWS)
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 1003bc6f..4a1962c0 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -85,7 +85,6 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../hal/sdl2>
+<../.pio/libdeps/darwin_sdl_64bits/paho/src/*.c>
+<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.c>
+<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.h>
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux_sdl/linux_fbdev_64bits.ini
new file mode 100644
index 00000000..624d3de6
--- /dev/null
+++ b/user_setups/linux_sdl/linux_fbdev_64bits.ini
@@ -0,0 +1,98 @@
+[env:linux_fbdev_64bits]
+platform = native@^1.1.4
+extra_scripts =
+ tools/linux_build_extra.py
+build_flags =
+ ${env.build_flags}
+ -D HASP_MODEL="Linux App"
+ -D HASP_TARGET_PC=1
+
+ ; ----- Monitor
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=320
+ ; SDL drivers options
+ ;-D LV_LVGL_H_INCLUDE_SIMPLE
+ ;-D LV_DRV_NO_CONF
+ -D USE_FBDEV
+ ; ----- ArduinoJson
+ -D ARDUINOJSON_DECODE_UNICODE=1
+ -D HASP_NUM_PAGES=12
+ -D HASP_USE_SPIFFS=0
+ -D HASP_USE_LITTLEFS=0
+ -D LV_USE_FS_IF=1
+ -D HASP_USE_EEPROM=0
+ -D HASP_USE_GPIO=0
+ -D HASP_USE_CONFIG=1
+ -D HASP_USE_DEBUG=1
+ -D HASP_USE_PNGDECODE=1
+ -D HASP_USE_BMPDECODE=1
+ -D HASP_USE_GIFDECODE=0
+ -D HASP_USE_JPGDECODE=0
+ -D HASP_USE_MQTT=1
+ -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_ATTRIBUTE_FAST_MEM=
+ -D IRAM_ATTR= ; No IRAM_ATTR available
+ -D PROGMEM= ; No PROGMEM available
+ ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
+ ;-D LV_LOG_PRINTF=1
+ ; Add recursive dirs for hal headers search
+ -D POSIX
+ -D PAHO_MQTT_STATIC
+ -DPAHO_WITH_SSL=TRUE
+ -DPAHO_BUILD_DOCUMENTATION=FALSE
+ -DPAHO_BUILD_SAMPLES=FALSE
+ -DCMAKE_BUILD_TYPE=Release
+ -DCMAKE_VERBOSE_MAKEFILE=TRUE
+ ;-D NO_PERSISTENCE
+ -I.pio/libdeps/linux_fbdev_64bits/paho/src
+ -I.pio/libdeps/linux_fbdev_64bits/ArduinoJson/src
+
+ ; ----- Statically linked libraries --------------------
+ -lm
+ -lpthread
+
+lib_deps =
+ ${env.lib_deps}
+ ;lv_drivers@~7.9.0
+ ;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
+ https://github.com/eclipse/paho.mqtt.c.git
+ bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
+ https://github.com/fvanroie/lv_drivers
+
+lib_ignore =
+ paho
+ AXP192
+ ArduinoLog
+ lv_lib_qrcode
+ ETHSPI
+
+build_src_filter =
+ +<*>
+ -<*.h>
+ +<../.pio/libdeps/linux_fbdev_64bits/paho/src/*.c>
+ +<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTClient.c>
+ -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsync.c>
+ -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/linux_fbdev_64bits/paho/src/SSLSocket.c>
+ +
+ -
+ -
+ -
+ -
+ -
+ +
+ -
+ +
+ -
+ +
+ +
+ -
+ -
+ -
+ +
+ +
+ +
+ -
+ +
+ +<../.pio/libdeps/linux_fbdev_64bits/ArduinoJson/src/ArduinoJson.h>
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index c1e8d8dc..432c9814 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -76,7 +76,6 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../hal/sdl2>
+<../.pio/libdeps/linux_sdl_64bits/paho/src/*.c>
+<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTClient.c>
-<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsync.c>
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index 039c4004..d2657df5 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -100,7 +100,6 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../hal/sdl2>
+<../.pio/libdeps/windows_gdi_64bits/paho/src/*.c>
+<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTClient.c>
-<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsync.c>
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index a4a131e2..3c6957bb 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -106,7 +106,6 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../hal/sdl2>
+<../.pio/libdeps/windows_sdl_64bits/paho/src/*.c>
+<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTClient.c>
-<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsync.c>
From b85542c9ada9e75d2651b6a6a43e3a5fd8d23cb7 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 16:44:17 +0100
Subject: [PATCH 079/135] Update build actions to Node.js 20
---
.github/workflows/build.yaml | 16 ++++++++--------
.github/workflows/build_linux.yaml | 6 +++---
.github/workflows/release.yml | 6 +++---
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index ee4f01af..7fcc6234 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -64,23 +64,23 @@ jobs:
env: esp32-s3-4848S040
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: "true"
- name: Cache pip
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install PlatformIO
@@ -132,23 +132,23 @@ jobs:
linux_build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: "true"
- name: Cache pip
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install PlatformIO
diff --git a/.github/workflows/build_linux.yaml b/.github/workflows/build_linux.yaml
index a4baea49..bfe4ede4 100644
--- a/.github/workflows/build_linux.yaml
+++ b/.github/workflows/build_linux.yaml
@@ -14,18 +14,18 @@ jobs:
- linux_sdl_64bits
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: 'true'
- name: Cache pip
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 62ef57b4..31a693c6 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,16 +12,16 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Cache pip
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
From 91b347c8d1ab5f351a6d742fb86c0eeec97d0590 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 16:46:10 +0100
Subject: [PATCH 080/135] Bump RC version
---
platformio.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index 7d61dc60..2edc4d34 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -75,7 +75,7 @@ build_flags =
-D HASP_VER_MAJ=0
-D HASP_VER_MIN=7
;-D HASP_VER_REV=4
- -D HASP_VER_REV=0-rc10
+ -D HASP_VER_REV=0-rc11
;-D HASP_VER_REV=4-rc1
${override.build_flags}
From 2038cce0507b336ba7d2600a324c3f388eb8d832 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 16:57:23 +0100
Subject: [PATCH 081/135] Update build actions to Node.js 20
---
.github/workflows/build.yaml | 2 +-
.github/workflows/release.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 7fcc6234..e64de643 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -102,7 +102,7 @@ jobs:
- name: Run PlatformIO
run: pio run -e ${{ matrix.environment.env }}
- name: Upload output file
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: ${{ matrix.environment.out }}
path: build_output/firmware/*.bin
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 31a693c6..f4d093be 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -71,7 +71,7 @@ jobs:
- name: Run PlatformIO
run: pio run -e m5stack-core2
- name: Upload output file
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: openHASP firmware.zip
path: build_output/firmware/*.bin
From 7d804f8eab415ffed10108707c0aa88913e61ae4 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 17:23:04 +0100
Subject: [PATCH 082/135] Update hostnames to openhasp.com
---
CHANGELOG.md | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa53d7b7..e9b66efb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -168,23 +168,23 @@ Updated libraries to AceButton 1.9.1 and ArduinoJson 6.18.5
- Run `/online.cmd` or `/offline.cmd` script when the wifi status changed
### Objects
-- Add new *[line](https://openhasp.haswitchplate.com/0.6.1/design/objects/#line)* object
-- Add `val` to *[btnmatrix](https://openhasp.haswitchplate.com/0.6.1/design/objects/#button-matrix)* when `one_select` is set
-- Cache up to 20 *[images](https://openhasp.haswitchplate.com/0.6.1/design/objects/#image)* in PSram when available
-- Improve precision on the *[linemeter](https://openhasp.haswitchplate.com/0.6.1/design/objects/#line-meter)* scales
-- Fix *[dropdown](https://openhasp.haswitchplate.com/0.6.1/design/objects/#dropdown-list)* redraw bug
+- Add new *[line](https://www.openhasp.com/0.6.1/design/objects/#line)* object
+- Add `val` to *[btnmatrix](https://www.openhasp.com/0.6.1/design/objects/#button-matrix)* when `one_select` is set
+- Cache up to 20 *[images](https://www.openhasp.com/0.6.1/design/objects/#image)* in PSram when available
+- Improve precision on the *[linemeter](https://www.openhasp.com/0.6.1/design/objects/#line-meter)* scales
+- Fix *[dropdown](https://www.openhasp.com/0.6.1/design/objects/#dropdown-list)* redraw bug
### Devices
-- Fix [L8-HD dimmer](https://openhasp.haswitchplate.com/0.6.1/devices/lanbon-l8/) not responding correctly to mqtt after a reboot
-- Add [M5Stack Core2](https://openhasp.haswitchplate.com/0.6.1/devices/m5stack-core2/) backlight dimming
-- Add [Yeacreate Nscreen32](https://openhasp.haswitchplate.com/0.6.1/devices/yeacreate-nscreen32/)
-- Add [Makerfabs ESP32 TFT Touch](https://openhasp.haswitchplate.com/0.6.1/devices/makerfabs-tft-touch/) Capacitive
+- Fix [L8-HD dimmer](https://www.openhasp.com/0.6.1/devices/lanbon-l8/) not responding correctly to mqtt after a reboot
+- Add [M5Stack Core2](https://www.openhasp.com/0.6.1/devices/m5stack-core2/) backlight dimming
+- Add [Yeacreate Nscreen32](https://www.openhasp.com/0.6.1/devices/yeacreate-nscreen32/)
+- Add [Makerfabs ESP32 TFT Touch](https://www.openhasp.com/0.6.1/devices/makerfabs-tft-touch/) Capacitive
### Fonts
-- [Additional characters](https://openhasp.haswitchplate.com/0.6.1/design/fonts/#ascii): `²` (squared) and `³` (cubed)
-- [Additional icons](https://openhasp.haswitchplate.com/0.6.1/design/fonts/#built-in-icons): recycle-variant and additional weather icons
-- Use latin1 as default charset on [WT32-SC01](https://openhasp.haswitchplate.com/0.6.1/devices/wt32-sc01/)
-- Add [Greek font](https://openhasp.haswitchplate.com/0.6.1/design/fonts/#greek)
+- [Additional characters](https://www.openhasp.com/0.6.1/design/fonts/#ascii): `²` (squared) and `³` (cubed)
+- [Additional icons](https://www.openhasp.com/0.6.1/design/fonts/#built-in-icons): recycle-variant and additional weather icons
+- Use latin1 as default charset on [WT32-SC01](https://www.openhasp.com/0.6.1/devices/wt32-sc01/)
+- Add [Greek font](https://www.openhasp.com/0.6.1/design/fonts/#greek)
### Compiling
- Allow custom bootlogo
@@ -252,7 +252,7 @@ Updated libraries to lvgl 7.11.0, ArduinoJson 6.18.0 and TFT_eSPI 2.3.70
## v0.5.0
-Name changed to openHASP - https://openhasp.haswitchplate.com/
+Name changed to openHASP - https://www.openhasp.com/
> When using HomeAssistant also update the [openHASP Custom Component](https://github.com/HASwitchPlate/openHASP-custom-component/releases/tag/0.5.0)
- Switch built-in icons from FontAwesome to MaterialDesign icons #139
@@ -263,7 +263,7 @@ Name changed to openHASP - https://openhasp.haswitchplate.com/
- Add `back`, `prev`, `next` attributes to pages #114
- JSON Serialize text in payloads containing text attributes #140
- Add az-touch-mod-esp32_ili9341 config and allow for TFT_BACKLIGHT_ON set to LOW #131
-- Add [FreeTouchDeck](https://openhasp.haswitchplate.com/0.5/#devices/freetouchdeck/) and [ESP32-Touchdown](https://openhasp.haswitchplate.com/0.5/#devices/esp32-touchdown/) configs
+- Add [FreeTouchDeck](https://www.openhasp.com/0.5/#devices/freetouchdeck/) and [ESP32-Touchdown](https://www.openhasp.com/0.5/#devices/esp32-touchdown/) configs
- Add roller `mode` `infinite` attribute
- Add btnmatrix `toggle` and `one_check` attributes
- Rework all event handlers to reduce update events and prevent race condition #119 *(events have changed!)*
@@ -291,7 +291,7 @@ Changes:
- Remove HA auto-discovery in favor of the HA Custom Component
- Add `clearpage all` command option
- Add local page navigation and transitions
-- Add [scale properties](https://openhasp.haswitchplate.com/0.5/#styling/#scale)
+- Add [scale properties](https://www.openhasp.com/0.5/#styling/#scale)
- Add `config/gpio` command
- Allow for timezone setting in user_config_override.h (thanks @arovak)
- Start localizations for NL, HU and RO (thanks @nagyrobi)
From 1043f5ddd7169786228706de4efba0d64ca237ad Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 17:55:28 +0100
Subject: [PATCH 083/135] Update Changelog
---
CHANGELOG.md | 3 ++-
platformio.ini | 2 +-
user_setups/esp32/_esp32.ini | 3 +--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9b66efb..c4e51e24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@
- Firmware files include the bitmapped font sizes 12, 16, 24 and 32pt
- Use embedded TrueType font for other font sizes (PSram highly recommended)
- Add glyphs from Cyrillic, Latin-2, Greek and Viernamese character sets to default fonts
+- Add 12 new MDI icons
### Web UI
- Update Web UI to petite-vue app
@@ -58,7 +59,7 @@
- Add support for ESP32-S3 and ESP32-C3 devices
- Deprecation of support for ESP32-S2 devices due to lack of sRAM
-Updated libraries to ArduinoJson 6.21.4, ArduinoStreamUtils 1.7.3, AceButton 1.10.1, TFT_eSPI 2.5.0, LovyanGFX 1.1.8 and SimpleFTPServer 2.1.5
+Updated libraries to ArduinoJson 6.21.5, ArduinoStreamUtils 1.8.0, AceButton 1.10.1, TFT_eSPI 2.5.34, LovyanGFX 1.1.8 and SimpleFTPServer 2.1.5
## v0.6.3
diff --git a/platformio.ini b/platformio.ini
index 2edc4d34..bcffa81c 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -82,7 +82,7 @@ build_flags =
; -- Shared library dependencies in all environments
; Warning : don't put comments after github links => causes infinite download loop
lib_deps =
- bblanchon/ArduinoJson@^6.21.4
+ bblanchon/ArduinoJson@^6.21.5
;git+https://github.com/fvanroie/ConsoleInput.git
;git+https://github.com/andrethomas/TasmotaSlave.git
;git+https://github.com/lvgl/lvgl.git
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index a7440eae..93c493ed 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -95,7 +95,7 @@ lib_deps =
git+https://github.com/fvanroie/ConsoleInput.git#dev
; lorol/LittleFS_esp32@^1.0.6 ; for Arduino v1 only
bxparks/AceButton@^1.10.1 ; GPIO button library
- bblanchon/StreamUtils@^1.7.3 ; for EEPromStream and BufferedTelnetClient
+ bblanchon/StreamUtils@^1.8.0 ; for EEPromStream and BufferedTelnetClient
; knolleary/PubSubClient@^2.8.0 ; MQTT client
extra_scripts =
@@ -144,7 +144,6 @@ framework = arduino
;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
;;;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
platform = https://github.com/Jason2866/platform-espressif32/releases/download/2023.10.02/platform-espressif32-2023.10.02.zip
-
lib_ignore =
${esp32.lib_ignore}
LittleFS_esp32 ; Not needed for Arduino v2
From 109f00368e3dbd79a78b2b910acef7cc18808697 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 17:55:45 +0100
Subject: [PATCH 084/135] Remove root CA cert bundle
---
src/hasp/hasp_attribute.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp
index c40063d0..b903cc93 100644
--- a/src/hasp/hasp_attribute.cpp
+++ b/src/hasp/hasp_attribute.cpp
@@ -1348,7 +1348,8 @@ static hasp_attribute_type_t special_attribute_src(lv_obj_t* obj, const char* pa
#if defined(ARDUINO) && defined(ARDUINO_ARCH_ESP32)
#if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0
HTTPClient http;
- http.begin(payload, (const char*)rootca_crt_bundle_start);
+ // http.begin(payload, (const char*)rootca_crt_bundle_start);
+ http.begin(payload);
http.setTimeout(5000);
http.setConnectTimeout(5000);
From 1a5921080f8cf297b2999900dc52403dec5e1dd4 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 18:21:22 +0100
Subject: [PATCH 085/135] Update Timezones
---
src/sys/net/hasp_time.cpp | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/sys/net/hasp_time.cpp b/src/sys/net/hasp_time.cpp
index 3ad66a0f..3a193049 100644
--- a/src/sys/net/hasp_time.cpp
+++ b/src/sys/net/hasp_time.cpp
@@ -110,9 +110,7 @@ String time_zone_to_possix(const char* timezone)
case TZ_ASIA_RIYADH:
case TZ_ETC_GMT__3:
case TZ_EUROPE_ISTANBUL:
- case TZ_EUROPE_KIROV:
case TZ_EUROPE_MINSK:
- case TZ_EUROPE_VOLGOGRAD:
return "<+03>-3";
case TZ_ASIA_TEHRAN:
return "<+0330>-3:30";
@@ -283,9 +281,9 @@ String time_zone_to_possix(const char* timezone)
return "<-03>3";
case TZ_AMERICA_MIQUELON:
return "<-03>3<-02>,M3.2.0,M11.1.0";
- case TZ_AMERICA_GODTHAB:
case TZ_AMERICA_NUUK:
- return "<-03>3<-02>,M3.4.6/22,J365/25";
+ case TZ_AMERICA_GODTHAB:
+ return "<-02>2<-01>,M3.5.0/-1,M10.5.0/0";
case TZ_AMERICA_BOA_VISTA:
case TZ_AMERICA_CAMPO_GRANDE:
case TZ_AMERICA_CARACAS:
@@ -482,10 +480,11 @@ String time_zone_to_possix(const char* timezone)
case TZ_INDIAN_COMORO:
case TZ_INDIAN_MAYOTTE:
return "EAT-3";
- case TZ_AFRICA_CAIRO:
case TZ_AFRICA_TRIPOLI:
case TZ_EUROPE_KALININGRAD:
return "EET-2";
+ case TZ_AFRICA_CAIRO:
+ return "EET-2EEST,M4.5.5/0,M10.5.4/24";
case TZ_EUROPE_CHISINAU:
return "EET-2EEST,M3.5.0,M10.5.0/3";
case TZ_ASIA_BEIRUT:
@@ -506,7 +505,7 @@ String time_zone_to_possix(const char* timezone)
return "EET-2EEST,M3.5.0/3,M10.5.0/4";
case TZ_ASIA_GAZA:
case TZ_ASIA_HEBRON:
- return "EET-2EEST,M3.5.6,M10.5.6";
+ return "EET-2EEST,M3.4.4/50,M10.4.4/50";
case TZ_AMERICA_ATIKOKAN:
case TZ_AMERICA_CANCUN:
case TZ_AMERICA_CAYMAN:
@@ -577,8 +576,10 @@ String time_zone_to_possix(const char* timezone)
case TZ_ASIA_PYONGYANG:
case TZ_ASIA_SEOUL:
return "KST-9";
+ case TZ_EUROPE_KIROV:
case TZ_EUROPE_MOSCOW:
case TZ_EUROPE_SIMFEROPOL:
+ case TZ_EUROPE_VOLGOGRAD:
return "MSK-3";
case TZ_AMERICA_CRESTON:
case TZ_AMERICA_DAWSON:
From fdc5f9170a2065ca59137e6081508e4c5a56442e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Thu, 8 Feb 2024 18:57:08 +0100
Subject: [PATCH 086/135] Support evdev on Linux
---
src/drv/tft/tft_driver_posix_fbdev.cpp | 16 +++++++++++++++-
src/hasp_gui.cpp | 6 ++++++
user_setups/linux_sdl/linux_fbdev_64bits.ini | 1 +
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index ba584b01..e76b7190 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -11,6 +11,10 @@
#include "drv/tft/tft_driver.h"
#include "tft_driver_posix_fbdev.h"
+#if USE_EVDEV || USE_BSD_EVDEV
+#include "indev/evdev.h"
+#endif
+
#include "dev/device.h"
#include "hasp_debug.h"
#include "hasp_gui.h"
@@ -23,6 +27,9 @@
#include
+extern uint16_t tft_width;
+extern uint16_t tft_height;
+
namespace dev {
/**
@@ -71,6 +78,13 @@ void TftFbdevDrv::init(int32_t w, int h)
fbdev_init();
fbdev_get_sizes((uint32_t*)&_width, (uint32_t*)&_height);
+ tft_width = _width;
+ tft_height = _height;
+
+#if USE_EVDEV || USE_BSD_EVDEV
+ evdev_register("/dev/input/event2", LV_INDEV_TYPE_POINTER, NULL);
+#endif
+
#if HASP_USE_LVGL_TASK
#error "fbdev LVGL task is not implemented"
#else
@@ -99,7 +113,7 @@ void TftFbdevDrv::set_invert(bool invert)
{}
void TftFbdevDrv::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
{
- fbdev_flush(disp, area, color_p);
+ lv_disp_flush_ready(disp);
}
bool TftFbdevDrv::is_driver_pin(uint8_t pin)
{
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index af4c8388..ac181b83 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -291,6 +291,10 @@ void guiSetup()
#endif
disp_drv.monitor_cb = gui_monitor_cb;
+ // register a touchscreen/mouse driver - only on real hardware and SDL2
+ // Win32 and POSIX handles input drivers in tft_driver
+#if TOUCH_DRIVER != -1 || USE_MONITOR
+
/* Initialize the touch pad */
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
@@ -331,6 +335,8 @@ void guiSetup()
gui_hide_pointer(false);
lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
+#endif // TOUCH_DRIVER != -1 || USE_MONITOR
+
#if HASP_TARGET_ARDUINO
// drv_touch_init(gui_settings.rotation); // Touch driver
haspTouch.init(tft_width, tft_height);
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux_sdl/linux_fbdev_64bits.ini
index 624d3de6..d1982e57 100644
--- a/user_setups/linux_sdl/linux_fbdev_64bits.ini
+++ b/user_setups/linux_sdl/linux_fbdev_64bits.ini
@@ -14,6 +14,7 @@ build_flags =
;-D LV_LVGL_H_INCLUDE_SIMPLE
;-D LV_DRV_NO_CONF
-D USE_FBDEV
+ -D USE_EVDEV
; ----- ArduinoJson
-D ARDUINOJSON_DECODE_UNICODE=1
-D HASP_NUM_PAGES=12
From 9693ef361aedb306a0a73a28788ea23220f1ccb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Thu, 8 Feb 2024 19:44:12 +0100
Subject: [PATCH 087/135] Scan for input devices on Linux, show splashscreen
---
src/drv/tft/tft_driver_posix_fbdev.cpp | 79 +++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 2 deletions(-)
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index e76b7190..bde0450e 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -26,6 +26,14 @@
#endif
#include
+#include
+#include
+
+#if USE_BSD_EVDEV
+#include
+#else
+#include
+#endif
extern uint16_t tft_width;
extern uint16_t tft_height;
@@ -82,7 +90,74 @@ void TftFbdevDrv::init(int32_t w, int h)
tft_height = _height;
#if USE_EVDEV || USE_BSD_EVDEV
- evdev_register("/dev/input/event2", LV_INDEV_TYPE_POINTER, NULL);
+ DIR* dir = opendir("/dev/input");
+ if(dir == NULL) {
+ perror("/dev/input opendir failed");
+ } else {
+ // iterate through /dev/input devices
+ struct dirent* dirent;
+ unsigned char ev_type[EV_MAX / 8 + 1];
+ while((dirent = readdir(dir)) != NULL) {
+ // make sure it's a block device matching /dev/input/event*
+ if(strncmp(dirent->d_name, "event", 5) != 0 || strlen(dirent->d_name) <= 5) continue;
+ if(dirent->d_type != DT_CHR) continue;
+ // get full path
+ char dev_path[64];
+ strcpy(dev_path, "/dev/input/");
+ strcat(dev_path, dirent->d_name);
+#if USE_BSD_EVDEV
+ // open the device
+ int fd = open(dev_path, O_RDONLY | O_NOCTTY);
+#else
+ int fd = open(dev_path, O_RDONLY | O_NOCTTY | O_NDELAY);
+#endif
+ if(fd == -1) {
+ perror("input open failed");
+ continue;
+ }
+ // read supported event types
+ memset(ev_type, 0, sizeof(ev_type));
+ if(ioctl(fd, EVIOCGBIT(0, sizeof(ev_type)), ev_type) < 0) {
+ perror("ioctl failed");
+ close(fd);
+ continue;
+ }
+ // read device name
+ char dev_name[256];
+ if(ioctl(fd, EVIOCGNAME(sizeof(dev_name)), dev_name) < 0) {
+ perror("ioctl failed");
+ close(fd);
+ continue;
+ }
+ // check which types are supported; judge LVGL device type
+ lv_indev_type_t dev_type;
+ if(ev_type[EV_ABS / 8] & (1 << (EV_ABS % 8))) {
+ dev_type = LV_INDEV_TYPE_POINTER;
+ } else if(ev_type[EV_REL / 8] & (1 << (EV_REL % 8))) {
+ dev_type = LV_INDEV_TYPE_POINTER;
+ } else if(ev_type[EV_KEY / 8] & (1 << (EV_KEY % 8))) {
+ dev_type = LV_INDEV_TYPE_KEYPAD;
+ } else {
+ close(fd);
+ continue;
+ }
+ // register the device
+ switch(dev_type) {
+ case LV_INDEV_TYPE_POINTER:
+ LOG_VERBOSE(TAG_TFT, F("Pointer : %s (%s)"), dev_path, dev_name);
+ break;
+ case LV_INDEV_TYPE_KEYPAD:
+ LOG_VERBOSE(TAG_TFT, F("Keypad : %s (%s)"), dev_path, dev_name);
+ break;
+ default:
+ LOG_VERBOSE(TAG_TFT, F("Input : %s (%s)"), dev_path, dev_name);
+ break;
+ }
+ evdev_register(dev_path, dev_type, NULL);
+ close(fd);
+ }
+ closedir(dir);
+ }
#endif
#if HASP_USE_LVGL_TASK
@@ -105,7 +180,7 @@ void TftFbdevDrv::splashscreen()
uint8_t bg[] = logoBgColor;
lv_color_t fgColor = lv_color_make(fg[0], fg[1], fg[2]);
lv_color_t bgColor = lv_color_make(bg[0], bg[1], bg[2]);
- // TODO show splashscreen
+ fbdev_splashscreen(logoImage, logoWidth, logoHeight, fgColor, bgColor);
}
void TftFbdevDrv::set_rotation(uint8_t rotation)
{}
From 18a3f0bb7fc78adb0cb2370e5ba4a2946e819c81 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 19:47:53 +0100
Subject: [PATCH 088/135] Fix macro
---
src/drv/touch/touch_driver_tftespi.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/drv/touch/touch_driver_tftespi.h b/src/drv/touch/touch_driver_tftespi.h
index fc5895c8..8fc82a91 100644
--- a/src/drv/touch/touch_driver_tftespi.h
+++ b/src/drv/touch/touch_driver_tftespi.h
@@ -4,7 +4,7 @@
#ifndef HASP_TFTESPI_TOUCH_DRIVER_H
#define HASP_TFTESPI_TOUCH_DRIVER_H
-#ifdef ARDUINO && defined(USER_SETUP_LOADED)
+#if defined(ARDUINO) && defined(USER_SETUP_LOADED)
#include
#include "touch_driver.h" // base class
From f4f5ae0f0dae12e6a12fa3c592e7605530e2c5e3 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 8 Feb 2024 20:13:09 +0100
Subject: [PATCH 089/135] Update Graphics Libraries
---
CHANGELOG.md | 2 +-
platformio.ini | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c4e51e24..e9b368b6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -59,7 +59,7 @@
- Add support for ESP32-S3 and ESP32-C3 devices
- Deprecation of support for ESP32-S2 devices due to lack of sRAM
-Updated libraries to ArduinoJson 6.21.5, ArduinoStreamUtils 1.8.0, AceButton 1.10.1, TFT_eSPI 2.5.34, LovyanGFX 1.1.8 and SimpleFTPServer 2.1.5
+Updated libraries to Arduino_GFX v1.4.4, ArduinoJson 6.21.5, ArduinoStreamUtils 1.8.0, AceButton 1.10.1, TFT_eSPI 2.5.34, LovyanGFX 1.1.12 and SimpleFTPServer 2.1.5
## v0.6.3
diff --git a/platformio.ini b/platformio.ini
index bcffa81c..66bd9b3c 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -104,11 +104,11 @@ build_src_filter = +<*> -<.git/> - - - - -
Date: Thu, 8 Feb 2024 22:01:53 +0100
Subject: [PATCH 090/135] Print evdev input device resolution, enable cursor on
fbdev
---
src/drv/tft/tft_driver_posix_fbdev.cpp | 34 +++++++++++++++++++-------
src/hasp_gui.cpp | 16 ++++++++----
2 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index bde0450e..79706c49 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -86,6 +86,9 @@ void TftFbdevDrv::init(int32_t w, int h)
fbdev_init();
fbdev_get_sizes((uint32_t*)&_width, (uint32_t*)&_height);
+ // show the splashscreen early
+ splashscreen();
+
tft_width = _width;
tft_height = _height;
@@ -131,12 +134,16 @@ void TftFbdevDrv::init(int32_t w, int h)
}
// check which types are supported; judge LVGL device type
lv_indev_type_t dev_type;
- if(ev_type[EV_ABS / 8] & (1 << (EV_ABS % 8))) {
- dev_type = LV_INDEV_TYPE_POINTER;
- } else if(ev_type[EV_REL / 8] & (1 << (EV_REL % 8))) {
- dev_type = LV_INDEV_TYPE_POINTER;
+ const char* dev_type_name;
+ if(ev_type[EV_REL / 8] & (1 << (EV_REL % 8))) {
+ dev_type = LV_INDEV_TYPE_POINTER;
+ dev_type_name = "EV_REL";
+ } else if(ev_type[EV_ABS / 8] & (1 << (EV_ABS % 8))) {
+ dev_type = LV_INDEV_TYPE_POINTER;
+ dev_type_name = "EV_ABS";
} else if(ev_type[EV_KEY / 8] & (1 << (EV_KEY % 8))) {
- dev_type = LV_INDEV_TYPE_KEYPAD;
+ dev_type = LV_INDEV_TYPE_KEYPAD;
+ dev_type_name = "EV_KEY";
} else {
close(fd);
continue;
@@ -144,17 +151,26 @@ void TftFbdevDrv::init(int32_t w, int h)
// register the device
switch(dev_type) {
case LV_INDEV_TYPE_POINTER:
- LOG_VERBOSE(TAG_TFT, F("Pointer : %s (%s)"), dev_path, dev_name);
+ LOG_VERBOSE(TAG_TFT, F("Pointer : %s %s (%s)"), dev_path, dev_type_name, dev_name);
break;
case LV_INDEV_TYPE_KEYPAD:
- LOG_VERBOSE(TAG_TFT, F("Keypad : %s (%s)"), dev_path, dev_name);
+ LOG_VERBOSE(TAG_TFT, F("Keypad : %s %s (%s)"), dev_path, dev_type_name, dev_name);
break;
default:
- LOG_VERBOSE(TAG_TFT, F("Input : %s (%s)"), dev_path, dev_name);
+ LOG_VERBOSE(TAG_TFT, F("Input : %s %s (%s)"), dev_path, dev_type_name, dev_name);
break;
}
- evdev_register(dev_path, dev_type, NULL);
close(fd);
+ // print verbose resolution info
+ lv_indev_t* indev;
+ if(!evdev_register(dev_path, dev_type, &indev) || indev == NULL) {
+ printf("Failed to register evdev\n");
+ continue;
+ }
+ evdev_data_t* user_data = (evdev_data_t*)indev->driver.user_data;
+ LOG_VERBOSE(TAG_TFT, F("Resolution : X=%d (%d..%d), Y=%d (%d..%d)"), user_data->x_max,
+ user_data->x_absinfo.minimum, user_data->x_absinfo.maximum, user_data->y_max,
+ user_data->y_absinfo.minimum, user_data->y_absinfo.maximum);
}
closedir(dir);
}
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index ac181b83..9fd55c9b 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -294,7 +294,6 @@ void guiSetup()
// register a touchscreen/mouse driver - only on real hardware and SDL2
// Win32 and POSIX handles input drivers in tft_driver
#if TOUCH_DRIVER != -1 || USE_MONITOR
-
/* Initialize the touch pad */
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
@@ -306,6 +305,13 @@ void guiSetup()
#endif
lv_indev_t* mouse_indev = lv_indev_drv_register(&indev_drv);
mouse_indev->driver.type = LV_INDEV_TYPE_POINTER;
+#else
+ // find the first registered input device to add a cursor to
+ lv_indev_t* mouse_indev = NULL;
+ while((mouse_indev = lv_indev_get_next(mouse_indev))) {
+ if(mouse_indev->driver.type == LV_INDEV_TYPE_POINTER) break;
+ }
+#endif
/*Set a cursor for the mouse*/
LOG_TRACE(TAG_GUI, F("Initialize Cursor"));
@@ -326,16 +332,16 @@ void guiSetup()
cursor = lv_img_create(mouse_layer, NULL); /*Create an image object for the cursor */
lv_img_set_src(cursor, &mouse_cursor_icon); /*Set the image source*/
#else
- cursor = lv_obj_create(mouse_layer, NULL); // show cursor object on every page
+ cursor = lv_obj_create(mouse_layer, NULL); // show cursor object on every page
lv_obj_set_size(cursor, 9, 9);
lv_obj_set_style_local_radius(cursor, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
lv_obj_set_style_local_bg_color(cursor, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_obj_set_style_local_bg_opa(cursor, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER);
#endif
gui_hide_pointer(false);
- lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
-
-#endif // TOUCH_DRIVER != -1 || USE_MONITOR
+ if(mouse_indev != NULL) {
+ lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
+ }
#if HASP_TARGET_ARDUINO
// drv_touch_init(gui_settings.rotation); // Touch driver
From f36dd66a0577e9f70d5ac3ad8a325f5771a9ae5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Thu, 8 Feb 2024 22:05:57 +0100
Subject: [PATCH 091/135] Fix memory corruption with memcpy(), support musl
libc
---
src/hasp/hasp_dispatch.cpp | 2 +-
src/hasp/hasp_event.cpp | 22 +++++++++++++---------
src/hasp/hasp_parser.cpp | 22 +++++++++++-----------
3 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 1124a76d..0b58089f 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -1360,7 +1360,7 @@ void dispatch_idle_state(uint8_t state)
{
char topic[8];
char buffer[8];
- memcpy_P(topic, PSTR("idle"), 8);
+ memcpy_P(topic, PSTR("idle"), 5);
hasp_get_sleep_payload(state, buffer);
dispatch_state_subtopic(topic, buffer);
}
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index 433bc7ea..fd5eeaee 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -176,9 +176,9 @@ void event_timer_clock(lv_task_t* task)
timeval curTime;
int rslt = gettimeofday(&curTime, NULL);
(void)rslt; // unused
- time_t seconds = curTime.tv_sec;
- useconds_t tv_msec = curTime.tv_usec / 1000;
- tm* timeinfo = localtime(&seconds);
+ time_t seconds = curTime.tv_sec;
+ auto tv_msec = curTime.tv_usec / 1000;
+ tm* timeinfo = localtime(&seconds);
lv_task_set_period(task, data->interval - tv_msec);
char buffer[128] = {0};
@@ -835,7 +835,7 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
if(!translate_event(obj, event, hasp_event_id) || event == LV_EVENT_VALUE_CHANGED) return;
/* Get the new value */
- lv_color_t color = lv_cpicker_get_color(obj);
+ lv_color_t color = lv_cpicker_get_color(obj);
lv_cpicker_color_mode_t mode = lv_cpicker_get_color_mode(obj);
if(hasp_event_id == HASP_EVENT_CHANGED && last_color_sent.full == color.full) return; // same value as before
@@ -853,12 +853,16 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
if(const char* tag = my_obj_get_tag(obj))
snprintf_P(data, sizeof(data),
- PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%d,\"v\":%d,\"tag\":%s}"),
- eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h, hsv.s, hsv.v, tag);
+ PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
+ "d,\"v\":%d,\"tag\":%s}"),
+ eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
+ hsv.s, hsv.v, tag);
else
snprintf_P(data, sizeof(data),
- PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%d,\"v\":%d}"), eventname,
- c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h, hsv.s, hsv.v);
+ PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
+ "d,\"v\":%d}"),
+ eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
+ hsv.s, hsv.v);
}
event_send_object_data(obj, data);
@@ -907,4 +911,4 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
// event_update_group(obj->user_data.groupid, obj, val, min, max);
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index 0b85e415..8660060c 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -136,34 +136,34 @@ void Parser::get_event_name(uint8_t eventid, char* buffer, size_t size)
{
switch(eventid) {
case HASP_EVENT_ON:
- memcpy_P(buffer, PSTR("on"), size);
+ memcpy_P(buffer, PSTR("on"), 3);
break;
case HASP_EVENT_OFF:
- memcpy_P(buffer, PSTR("off"), size);
+ memcpy_P(buffer, PSTR("off"), 4);
break;
case HASP_EVENT_UP:
- memcpy_P(buffer, PSTR("up"), size);
+ memcpy_P(buffer, PSTR("up"), 3);
break;
case HASP_EVENT_DOWN:
- memcpy_P(buffer, PSTR("down"), size);
+ memcpy_P(buffer, PSTR("down"), 5);
break;
case HASP_EVENT_RELEASE:
- memcpy_P(buffer, PSTR("release"), size);
+ memcpy_P(buffer, PSTR("release"), 8);
break;
case HASP_EVENT_LONG:
- memcpy_P(buffer, PSTR("long"), size);
+ memcpy_P(buffer, PSTR("long"), 5);
break;
case HASP_EVENT_HOLD:
- memcpy_P(buffer, PSTR("hold"), size);
+ memcpy_P(buffer, PSTR("hold"), 5);
break;
case HASP_EVENT_LOST:
- memcpy_P(buffer, PSTR("lost"), size);
+ memcpy_P(buffer, PSTR("lost"), 5);
break;
case HASP_EVENT_CHANGED:
- memcpy_P(buffer, PSTR("changed"), size);
+ memcpy_P(buffer, PSTR("changed"), 8);
break;
default:
- memcpy_P(buffer, PSTR("unknown"), size);
+ memcpy_P(buffer, PSTR("unknown"), 8);
}
}
@@ -238,4 +238,4 @@ long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
-#endif
\ No newline at end of file
+#endif
From a7d900ed7b04debe907c868a07d2d4f4bb229ae1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Thu, 8 Feb 2024 22:44:39 +0100
Subject: [PATCH 092/135] Support brightness control on Linux fbdev
---
src/dev/posix/hasp_posix.cpp | 27 ++++++++++++++++++++++++++-
src/dev/posix/hasp_posix.h | 4 ++++
src/main_pc.cpp | 23 +++++++++++++++++++++++
3 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index ef4fc10b..3b0c7566 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -25,6 +25,7 @@
#include "display/fbdev.h"
#endif
+#include
#include
// extern monitor_t monitor;
@@ -153,7 +154,31 @@ void PosixDevice::update_backlight()
#if USE_MONITOR
monitor_backlight(level);
#elif USE_FBDEV
- // set display backlight, if possible
+ // set display backlight, if possible
+ if(backlight_device != "") {
+ if(backlight_max == 0) {
+ std::ifstream f;
+ f.open("/sys/class/backlight/" + backlight_device + "/max_brightness");
+ if(!f.fail()) {
+ f >> backlight_max;
+ f.close();
+ } else {
+ perror("Max brightness read failed");
+ }
+ }
+
+ int brightness = map(level, 0, 255, 0, backlight_max);
+ LOG_VERBOSE(0, "Setting brightness to %d/255 (%d)", level, brightness);
+
+ std::ofstream f;
+ f.open("/sys/class/backlight/" + backlight_device + "/brightness");
+ if(!f.fail()) {
+ f << brightness;
+ f.close();
+ } else {
+ perror("Brightness write failed");
+ }
+ }
#endif
}
diff --git a/src/dev/posix/hasp_posix.h b/src/dev/posix/hasp_posix.h
index 73a8a49c..4ec64458 100644
--- a/src/dev/posix/hasp_posix.h
+++ b/src/dev/posix/hasp_posix.h
@@ -56,6 +56,10 @@ class PosixDevice : public BaseDevice {
bool is_system_pin(uint8_t pin) override;
+ public:
+ std::string backlight_device;
+ int backlight_max = 0;
+
private:
std::string _hostname;
std::string _core_version;
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index c6190c7a..ad851d1b 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -119,6 +119,10 @@ void usage(const char* progName, const char* version)
<< " (default: 'AppData\\hasp\\hasp')" << std::endl
#elif defined(POSIX)
<< " (default: '~/.local/share/hasp/hasp')" << std::endl
+#endif
+#if USE_FBDEV && defined(POSIX)
+ << " -b | --backlight Backlight device name (in /sys/class/backlight/)" << std::endl
+ << " -B | --bl-max Backlight brightness limit (default: max_brightness)" << std::endl
#endif
<< std::endl;
fflush(stdout);
@@ -138,6 +142,25 @@ int main(int argc, char* argv[])
for(int arg = 1; arg < argc; arg++) {
if(strncmp(argv[arg], "--help", 6) == 0 || strncmp(argv[arg], "-h", 2) == 0) {
showhelp = true;
+#if USE_FBDEV && defined(POSIX)
+ } else if(strncmp(argv[arg], "--backlight", 11) == 0 || strncmp(argv[arg], "-b", 2) == 0) {
+ if(arg + 1 < argc) {
+ haspDevice.backlight_device = argv[arg + 1];
+ arg++;
+ } else {
+ std::cout << "Missing device name" << std::endl;
+ showhelp = true;
+ }
+ } else if(strncmp(argv[arg], "--bl-max", 9) == 0 || strncmp(argv[arg], "-B", 2) == 0) {
+ if(arg + 1 < argc) {
+ int bl_max = atoi(argv[arg + 1]);
+ if(bl_max > 0) haspDevice.backlight_max = bl_max;
+ arg++;
+ } else {
+ std::cout << "Missing backlight level" << std::endl;
+ showhelp = true;
+ }
+#endif
} else if(strncmp(argv[arg], "--width", 7) == 0 || strncmp(argv[arg], "-W", 2) == 0) {
if(arg + 1 < argc) {
int w = atoi(argv[arg + 1]);
From da9b0342894f4c04a4c381337a80800343e784b6 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 9 Feb 2024 02:15:30 +0100
Subject: [PATCH 093/135] Fix broken scripts
---
src/hasp/hasp_dispatch.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 2dacba77..d828b2b8 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -801,10 +801,10 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
return;
}
- if(!gui_acquire(pdMS_TO_TICKS(500))) {
- LOG_ERROR(TAG_MSGR, F(D_FILE_LOAD_FAILED), payload);
- return;
- }
+ // if(!gui_acquire(pdMS_TO_TICKS(500))) {
+ // LOG_ERROR(TAG_MSGR, F(D_FILE_LOAD_FAILED), payload);
+ // return;
+ // }
// char buffer[512]; // use stack
String buffer((char*)0); // use heap
@@ -829,7 +829,7 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
}
}
- gui_release();
+ // gui_release();
cmdfile.close();
LOG_INFO(TAG_MSGR, F(D_FILE_LOADED), payload);
#else
From 226a88f3dff1c5e9b17e299a333d9c6978463386 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 9 Feb 2024 02:15:55 +0100
Subject: [PATCH 094/135] Updated libraries and CHANGELOG
---
CHANGELOG.md | 2 +-
platformio.ini | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9b368b6..23bfac23 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -59,7 +59,7 @@
- Add support for ESP32-S3 and ESP32-C3 devices
- Deprecation of support for ESP32-S2 devices due to lack of sRAM
-Updated libraries to Arduino_GFX v1.4.4, ArduinoJson 6.21.5, ArduinoStreamUtils 1.8.0, AceButton 1.10.1, TFT_eSPI 2.5.34, LovyanGFX 1.1.12 and SimpleFTPServer 2.1.5
+Updated libraries to Arduino_GFX v1.4.0, ArduinoJson 6.21.5, ArduinoStreamUtils 1.8.0, AceButton 1.10.1, TFT_eSPI 2.5.34, LovyanGFX 1.1.12 and SimpleFTPServer 2.1.5
## v0.6.3
diff --git a/platformio.ini b/platformio.ini
index 66bd9b3c..05f259ea 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -108,7 +108,7 @@ lib_deps =
[arduinogfx]
lib_deps =
- moononournation/GFX Library for Arduino@1.4.4
+ moononournation/GFX Library for Arduino@1.4.0 ; Update needs modification of custom PCA class
;git+https://github.com/moononournation/Arduino_GFX.git
[tft_espi]
From a0c8fd49d410c02dbd153bf52863c046cb58d54d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Fri, 9 Feb 2024 20:45:53 +0100
Subject: [PATCH 095/135] Fix millis() overflow on 32-bit Linux
---
src/dev/posix/hasp_posix.cpp | 11 +++++++++--
src/dev/posix/hasp_posix.h | 2 +-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index 3b0c7566..e19e3c2e 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -248,11 +248,18 @@ long PosixDevice::get_uptime()
} // namespace dev
-long PosixMillis()
+static time_t tv_sec_start = 0;
+
+unsigned long PosixMillis()
{
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
- return (spec.tv_sec) * 1000 + (spec.tv_nsec) / 1e6;
+ if (tv_sec_start == 0) {
+ tv_sec_start = spec.tv_sec;
+ }
+ unsigned long msec1 = (spec.tv_sec - tv_sec_start) * 1000;
+ unsigned long msec2 = spec.tv_nsec / 1e6;
+ return msec1 + msec2;
}
void msleep(unsigned long millis)
diff --git a/src/dev/posix/hasp_posix.h b/src/dev/posix/hasp_posix.h
index 4ec64458..7e7d6275 100644
--- a/src/dev/posix/hasp_posix.h
+++ b/src/dev/posix/hasp_posix.h
@@ -75,7 +75,7 @@ class PosixDevice : public BaseDevice {
} // namespace dev
-extern long PosixMillis();
+extern unsigned long PosixMillis();
extern void msleep(unsigned long millis);
using dev::PosixDevice;
From 4c20d6a4b973938855fc3f4240a8dffe0e31f735 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Fri, 9 Feb 2024 22:35:01 +0100
Subject: [PATCH 096/135] Allow choosing fbdev and evdev names, load POSIX
settings from config
---
src/dev/posix/hasp_posix.cpp | 31 ++++++++++++++++++++++++--
src/dev/posix/hasp_posix.h | 2 ++
src/drv/tft/tft_driver_posix_fbdev.cpp | 7 +++++-
src/drv/tft/tft_driver_posix_fbdev.h | 6 +++++
src/hasp_config.cpp | 6 +++++
src/main_pc.cpp | 31 +++++---------------------
6 files changed, 55 insertions(+), 28 deletions(-)
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index e19e3c2e..8d864cf7 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -23,6 +23,7 @@
#include "display/monitor.h"
#elif USE_FBDEV
#include "display/fbdev.h"
+#include "drv/tft/tft_driver.h"
#endif
#include
@@ -54,6 +55,32 @@ PosixDevice::PosixDevice()
_backlight_level = 255;
}
+void PosixDevice::set_config(const JsonObject& settings)
+{
+ configOutput(settings, 0);
+#if USE_FBDEV
+ if(settings["fbdev"].is()) {
+ haspTft.fbdev_path = "/dev/" + settings["fbdev"].as();
+ }
+#if USE_EVDEV
+ if(settings["evdev"].is()) {
+ haspTft.evdev_names.push_back(settings["evdev"].as());
+ }
+ if(settings["evdevs"].is()) {
+ for(auto v : settings["evdevs"].as()) {
+ haspTft.evdev_names.push_back(v.as());
+ }
+ }
+#endif
+ if(settings["bldev"].is()) {
+ haspDevice.backlight_device = settings["bldev"].as();
+ }
+ if(settings["blmax"].is()) {
+ haspDevice.backlight_max = settings["blmax"];
+ }
+#endif
+}
+
void PosixDevice::reboot()
{}
void PosixDevice::show_info()
@@ -254,8 +281,8 @@ unsigned long PosixMillis()
{
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
- if (tv_sec_start == 0) {
- tv_sec_start = spec.tv_sec;
+ if(tv_sec_start == 0) {
+ tv_sec_start = spec.tv_sec;
}
unsigned long msec1 = (spec.tv_sec - tv_sec_start) * 1000;
unsigned long msec2 = spec.tv_nsec / 1e6;
diff --git a/src/dev/posix/hasp_posix.h b/src/dev/posix/hasp_posix.h
index 7e7d6275..439d4c12 100644
--- a/src/dev/posix/hasp_posix.h
+++ b/src/dev/posix/hasp_posix.h
@@ -31,6 +31,8 @@ class PosixDevice : public BaseDevice {
public:
PosixDevice();
+ void set_config(const JsonObject& settings);
+
void reboot() override;
void show_info() override;
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index 79706c49..955903f8 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#if USE_BSD_EVDEV
#include
@@ -83,7 +84,7 @@ void TftFbdevDrv::init(int32_t w, int h)
/* Add a display
* Use the 'fbdev' driver which uses POSIX framebuffer device as a display
* The following input devices are handled: mouse, keyboard, mousewheel */
- fbdev_init();
+ fbdev_init(fbdev_path.empty() ? NULL : fbdev_path.c_str());
fbdev_get_sizes((uint32_t*)&_width, (uint32_t*)&_height);
// show the splashscreen early
@@ -104,6 +105,10 @@ void TftFbdevDrv::init(int32_t w, int h)
// make sure it's a block device matching /dev/input/event*
if(strncmp(dirent->d_name, "event", 5) != 0 || strlen(dirent->d_name) <= 5) continue;
if(dirent->d_type != DT_CHR) continue;
+ // skip device if not specified on command line
+ if(!evdev_names.empty() &&
+ std::find(evdev_names.begin(), evdev_names.end(), std::string(dirent->d_name)) == evdev_names.end())
+ continue;
// get full path
char dev_path[64];
strcpy(dev_path, "/dev/input/");
diff --git a/src/drv/tft/tft_driver_posix_fbdev.h b/src/drv/tft/tft_driver_posix_fbdev.h
index 5856f892..643126bf 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.h
+++ b/src/drv/tft/tft_driver_posix_fbdev.h
@@ -11,6 +11,8 @@
#include "lvgl.h"
+#include
+
namespace dev {
class TftFbdevDrv : BaseTft {
@@ -30,6 +32,10 @@ class TftFbdevDrv : BaseTft {
int32_t width();
int32_t height();
+ public:
+ std::string fbdev_path;
+ std::vector evdev_names;
+
private:
int32_t _width, _height;
};
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index 559c3f0a..4bdb7c80 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -636,6 +636,12 @@ void configSetup()
gpioSetConfig(settings[FPSTR(FP_GPIO)]);
#endif
+ // target-specific config
+#if defined(POSIX)
+ LOG_INFO(TAG_CONF, F("Loading POSIX-specific settings"));
+ haspDevice.set_config(settings[F("posix")]);
+#endif
+
LOG_INFO(TAG_CONF, F(D_CONFIG_LOADED));
}
// #endif
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index ad851d1b..63d3d2bb 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -112,17 +112,15 @@ void usage(const char* progName, const char* version)
<< std::endl
<< "Options:" << std::endl
<< " -h | --help Print this help" << std::endl
+#if !USE_FBDEV
<< " -W | --width Width of the window" << std::endl
<< " -H | --height Height of the window" << std::endl
- << " -C | --config Configuration directory" << std::endl
+#endif
+ << " -c | --config Configuration/storage directory" << std::endl
#if defined(WINDOWS)
<< " (default: 'AppData\\hasp\\hasp')" << std::endl
#elif defined(POSIX)
<< " (default: '~/.local/share/hasp/hasp')" << std::endl
-#endif
-#if USE_FBDEV && defined(POSIX)
- << " -b | --backlight Backlight device name (in /sys/class/backlight/)" << std::endl
- << " -B | --bl-max Backlight brightness limit (default: max_brightness)" << std::endl
#endif
<< std::endl;
fflush(stdout);
@@ -142,25 +140,7 @@ int main(int argc, char* argv[])
for(int arg = 1; arg < argc; arg++) {
if(strncmp(argv[arg], "--help", 6) == 0 || strncmp(argv[arg], "-h", 2) == 0) {
showhelp = true;
-#if USE_FBDEV && defined(POSIX)
- } else if(strncmp(argv[arg], "--backlight", 11) == 0 || strncmp(argv[arg], "-b", 2) == 0) {
- if(arg + 1 < argc) {
- haspDevice.backlight_device = argv[arg + 1];
- arg++;
- } else {
- std::cout << "Missing device name" << std::endl;
- showhelp = true;
- }
- } else if(strncmp(argv[arg], "--bl-max", 9) == 0 || strncmp(argv[arg], "-B", 2) == 0) {
- if(arg + 1 < argc) {
- int bl_max = atoi(argv[arg + 1]);
- if(bl_max > 0) haspDevice.backlight_max = bl_max;
- arg++;
- } else {
- std::cout << "Missing backlight level" << std::endl;
- showhelp = true;
- }
-#endif
+#if !USE_FBDEV
} else if(strncmp(argv[arg], "--width", 7) == 0 || strncmp(argv[arg], "-W", 2) == 0) {
if(arg + 1 < argc) {
int w = atoi(argv[arg + 1]);
@@ -179,7 +159,8 @@ int main(int argc, char* argv[])
std::cout << "Missing height value" << std::endl;
showhelp = true;
}
- } else if(strncmp(argv[arg], "--config", 8) == 0 || strncmp(argv[arg], "-C", 2) == 0) {
+#endif
+ } else if(strncmp(argv[arg], "--config", 8) == 0 || strncmp(argv[arg], "-c", 2) == 0) {
if(arg + 1 < argc) {
strcpy(config, argv[arg + 1]);
arg++;
From 6bfe89cac0bdca23b7594b7ac613d6730a97f7c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Fri, 9 Feb 2024 22:55:11 +0100
Subject: [PATCH 097/135] Implement LVGL task for POSIX fbdev
---
src/drv/tft/tft_driver_posix_fbdev.cpp | 16 ++++++----------
user_setups/linux_sdl/linux_fbdev_64bits.ini | 1 +
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index 955903f8..c596f852 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -70,12 +70,13 @@ int32_t TftFbdevDrv::height()
static void* gui_entrypoint(void* arg)
{
#if HASP_USE_LVGL_TASK
-#error "fbdev LVGL task is not implemented"
-#else
- // create a LVGL tick thread
- pthread_t thread;
- pthread_create(&thread, 0, tick_thread, NULL);
+ // create an LVGL GUI task thread
+ pthread_t gui_pthread;
+ pthread_create(&gui_pthread, 0, (void* (*)(void*))gui_task, NULL);
#endif
+ // create an LVGL tick thread
+ pthread_t tick_pthread;
+ pthread_create(&tick_pthread, 0, tick_thread, NULL);
return 0;
}
@@ -181,12 +182,7 @@ void TftFbdevDrv::init(int32_t w, int h)
}
#endif
-#if HASP_USE_LVGL_TASK
-#error "fbdev LVGL task is not implemented"
-#else
- // do not use the gui_task(), just init the GUI and return
gui_entrypoint(NULL);
-#endif
}
void TftFbdevDrv::show_info()
{
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux_sdl/linux_fbdev_64bits.ini
index d1982e57..4904cf69 100644
--- a/user_setups/linux_sdl/linux_fbdev_64bits.ini
+++ b/user_setups/linux_sdl/linux_fbdev_64bits.ini
@@ -30,6 +30,7 @@ build_flags =
-D HASP_USE_GIFDECODE=0
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
+ -D HASP_USE_LVGL_TASK=1
-D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
From de0aeab4357994f4f8444c3eb6b24b263e5bbc11 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Fri, 9 Feb 2024 23:47:18 +0100
Subject: [PATCH 098/135] Hide active tty cursor on POSIX fbdev
---
src/drv/tft/tft_driver_posix_fbdev.cpp | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index c596f852..2961b728 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#if USE_BSD_EVDEV
#include
@@ -82,6 +83,23 @@ static void* gui_entrypoint(void* arg)
void TftFbdevDrv::init(int32_t w, int h)
{
+ // check active tty
+ std::ifstream f;
+ f.open("/sys/class/tty/tty0/active");
+ std::string tty;
+ f >> tty;
+ tty = "/dev/" + tty;
+ f.close();
+
+ // try to hide the cursor
+ int tty_fd = open(tty.c_str(), O_WRONLY);
+ if(tty_fd == -1) {
+ perror("Couldn't open tty");
+ } else {
+ write(tty_fd, "\033[?25l", 6);
+ }
+ close(tty_fd);
+
/* Add a display
* Use the 'fbdev' driver which uses POSIX framebuffer device as a display
* The following input devices are handled: mouse, keyboard, mousewheel */
From c01e4a799ecd3a18fc348cde3b9d85504d55db40 Mon Sep 17 00:00:00 2001
From: Ryan Press
Date: Fri, 9 Feb 2024 19:28:57 -0800
Subject: [PATCH 099/135] Use callback for backlight fade
---
src/dev/esp32/esp32.cpp | 48 ++++++++++++++++++++++++++++++++---------
src/dev/esp32/esp32.h | 6 ++++++
2 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp
index 049f3c1b..76eece8a 100644
--- a/src/dev/esp32/esp32.cpp
+++ b/src/dev/esp32/esp32.cpp
@@ -110,6 +110,8 @@ Esp32Device::Esp32Device()
_backlight_power = 1;
_backlight_level = 255;
_backlight_pin = 255; // not TFT_BCKL because it is unknown at this stage
+ _backlight_pending = false;
+ _backlight_fading = false;
/* fill unique identifier with wifi mac */
byte mac[6];
@@ -241,6 +243,22 @@ const char* Esp32Device::get_hardware_id()
return _hardware_id.c_str();
}
+bool Esp32Device::cb_backlight(const ledc_cb_param_t *param, void *user_arg) {
+ reinterpret_cast(user_arg)->end_backlight_fade();
+ return false;
+}
+
+void Esp32Device::end_backlight_fade()
+{
+ if (_backlight_pending) {
+ _backlight_pending = false;
+ _backlight_fading = false;
+ update_backlight(_backlight_fade);
+ } else {
+ _backlight_fading = false;
+ }
+}
+
void Esp32Device::set_backlight_pin(uint8_t pin)
{
_backlight_pin = pin;
@@ -255,6 +273,8 @@ void Esp32Device::set_backlight_pin(uint8_t pin)
#endif
ledcAttachPin(pin, BACKLIGHT_CHANNEL);
ledc_fade_func_install(0);
+ ledc_cbs_t cbs = {cb_backlight};
+ ledc_cb_register(LEDC_LOW_SPEED_MODE, (ledc_channel_t) BACKLIGHT_CHANNEL, &cbs, this);
update_backlight(false);
} else {
LOG_VERBOSE(TAG_GUI, F("Backlight : Pin not set"));
@@ -296,28 +316,36 @@ bool Esp32Device::get_backlight_power()
void Esp32Device::update_backlight(bool fade)
{
- static uint32_t last_duty = 0;
if(_backlight_pin < GPIO_NUM_MAX) {
#if !defined(CONFIG_IDF_TARGET_ESP32S2)
uint32_t duty = _backlight_power ? map(_backlight_level, 0, 255, 0, 1023) : 0;
if(_backlight_invert) duty = 1023 - duty;
- if(fade) {
- ledcWrite(BACKLIGHT_CHANNEL, last_duty); // this will stop an in-progress fade
- ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE, (ledc_channel_t) BACKLIGHT_CHANNEL, duty, BACKLIGHT_FADEMS, LEDC_FADE_NO_WAIT);
+ if(_backlight_fading) {
+ _backlight_fade = fade;
+ _backlight_pending = true;
} else {
- ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ if(fade) {
+ _backlight_fading = true;
+ ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE, (ledc_channel_t) BACKLIGHT_CHANNEL, duty, BACKLIGHT_FADEMS, LEDC_FADE_NO_WAIT);
+ } else {
+ ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ }
}
#else
uint32_t duty = _backlight_power ? map(_backlight_level, 0, 255, 0, 1023) : 0;
if(_backlight_invert) duty = 1023 - duty;
- if(fade) {
- ledcWrite(BACKLIGHT_CHANNEL, last_duty); // this will stop an in-progress fade
- ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE, (ledc_channel_t) BACKLIGHT_CHANNEL, duty, BACKLIGHT_FADEMS, LEDC_FADE_NO_WAIT);
+ if(_backlight_fading) {
+ _backlight_fade = fade;
+ _backlight_pending = true;
} else {
- ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ if(fade) {
+ _backlight_fading = true;
+ ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE, (ledc_channel_t) BACKLIGHT_CHANNEL, duty, BACKLIGHT_FADEMS, LEDC_FADE_NO_WAIT);
+ } else {
+ ledcWrite(BACKLIGHT_CHANNEL, duty); // ledChannel and value
+ }
}
#endif
- last_duty = duty;
}
// haspTft.tft.writecommand(0x53); // Write CTRL Display
diff --git a/src/dev/esp32/esp32.h b/src/dev/esp32/esp32.h
index 660d0df8..25dc157b 100644
--- a/src/dev/esp32/esp32.h
+++ b/src/dev/esp32/esp32.h
@@ -6,6 +6,7 @@
#include "hasp_conf.h"
#include "../device.h"
+#include "driver/ledc.h"
#if defined(ESP32)
@@ -68,8 +69,13 @@ class Esp32Device : public BaseDevice {
uint8_t _backlight_level;
uint8_t _backlight_power;
uint8_t _backlight_invert;
+ bool _backlight_pending;
+ bool _backlight_fading;
+ bool _backlight_fade;
void update_backlight(bool fade);
+ static bool cb_backlight(const ledc_cb_param_t *param, void *user_arg);
+ void end_backlight_fade();
};
} // namespace dev
From 2738bff96a7a0c86a73f93d668c885ce0394ebe0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 12:11:37 +0100
Subject: [PATCH 100/135] Allow changing LVGL refresh and animation period
---
src/hasp_config.h | 1 +
src/hasp_gui.cpp | 35 +++++++++++++++++++++++++++++++++++
src/hasp_gui.h | 1 +
3 files changed, 37 insertions(+)
diff --git a/src/hasp_config.h b/src/hasp_config.h
index 04160d30..ca5429ae 100644
--- a/src/hasp_config.h
+++ b/src/hasp_config.h
@@ -90,6 +90,7 @@ const char FP_GUI_BACKLIGHTINVERT[] PROGMEM = "bcklinv";
const char FP_GUI_POINTER[] PROGMEM = "cursor";
const char FP_GUI_LONG_TIME[] PROGMEM = "long";
const char FP_GUI_REPEAT_TIME[] PROGMEM = "repeat";
+const char FP_GUI_FPS[] PROGMEM = "fps";
const char FP_DEBUG_TELEPERIOD[] PROGMEM = "tele";
const char FP_DEBUG_ANSI[] PROGMEM = "ansi";
const char FP_GPIO_CONFIG[] PROGMEM = "config";
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 9fd55c9b..5c39f590 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -57,6 +57,8 @@ uint32_t screenshotEtag = 0;
void (*drv_display_flush_cb)(struct _disp_drv_t* disp_drv, const lv_area_t* area, lv_color_t* color_p);
static lv_disp_buf_t disp_buf;
+static bool gui_initialized = false;
+static uint32_t anim_fps_deferred = 0;
static inline void gui_init_lvgl()
{
@@ -100,6 +102,27 @@ void gui_hide_pointer(bool hidden)
if(cursor) lv_obj_set_hidden(cursor, hidden || !gui_settings.show_pointer);
}
+bool gui_set_fps(uint32_t fps)
+{
+ if(!gui_initialized) {
+ LOG_ERROR(TAG_GUI, F("GUI not initialized, deferring FPS setting"));
+ anim_fps_deferred = fps;
+ return false;
+ }
+
+ bool changed = false;
+ uint32_t period = 1000 / fps;
+ // find animation task by its period
+ lv_task_t* task = NULL;
+ while(task = lv_task_get_next(task)) {
+ if(!(task->period == LV_DISP_DEF_REFR_PERIOD)) continue;
+ changed |= (task->period != period);
+ LOG_INFO(TAG_GUI, F("Changing animation period: %u -> %u (%u FPS)"), task->period, period, fps);
+ task->period = period;
+ }
+ return changed;
+}
+
IRAM_ATTR void gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
{
haspTft.flush_pixels(disp, area, color_p);
@@ -373,6 +396,13 @@ void guiSetup()
}
#endif // ESP32 && HASP_USE_ESP_MQTT
+ // apply deferred FPS setting
+ gui_initialized = true;
+ if(anim_fps_deferred != 0) {
+ gui_set_fps(anim_fps_deferred);
+ anim_fps_deferred = 0;
+ }
+
LOG_INFO(TAG_LVGL, F(D_SERVICE_STARTED));
}
@@ -612,6 +642,11 @@ bool guiSetConfig(const JsonObject& settings)
changed |= status;
}
+ if(!settings[FPSTR(FP_GUI_FPS)].isNull()) {
+ uint32_t fps = settings[FPSTR(FP_GUI_FPS)].as();
+ changed |= gui_set_fps(fps);
+ }
+
return changed;
}
#endif // HASP_USE_CONFIG
diff --git a/src/hasp_gui.h b/src/hasp_gui.h
index 8b5b12af..adb5ddb6 100644
--- a/src/hasp_gui.h
+++ b/src/hasp_gui.h
@@ -48,6 +48,7 @@ void guiEverySecond(void);
void guiStart(void);
void guiStop(void);
void gui_hide_pointer(bool hidden);
+bool gui_set_fps(uint32_t fps);
/* ===== Special Event Processors ===== */
void guiCalibrate(void);
From 4fff3d79c5696d7ce7ac7ea4b0aed1647cb9d988 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 15:05:01 +0100
Subject: [PATCH 101/135] Enable command console on PC build
---
include/hasp_conf.h | 2 +-
src/hasp_debug.cpp | 4 +-
src/sys/svc/hasp_console.cpp | 41 ++++++++++++++++++--
src/sys/svc/hasp_console.h | 4 +-
src/sys/svc/hasp_http.cpp | 4 +-
src/sys/svc/hasp_http_async.cpp | 4 +-
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 1 +
user_setups/linux_sdl/linux_fbdev_64bits.ini | 1 +
user_setups/linux_sdl/linux_sdl_64bits.ini | 1 +
user_setups/win32/windows_gdi_64bits.ini | 1 +
user_setups/win32/windows_sdl_64bits.ini | 1 +
11 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index dc6eca52..f458102b 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -123,7 +123,7 @@
#endif
#ifndef HASP_USE_CONSOLE
-#define HASP_USE_CONSOLE HASP_TARGET_ARDUINO
+#define HASP_USE_CONSOLE 1
#endif
/* Filesystem */
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index 2adfd826..ca648c60 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -139,13 +139,11 @@ void debugStart(void)
LOG_INFO(TAG_DEBG, F("Console started"));
debug_flush();
-#else
+#endif
#if HASP_USE_CONSOLE > 0
consoleSetup();
#endif
-
-#endif
}
void debugStop()
diff --git a/src/sys/svc/hasp_console.cpp b/src/sys/svc/hasp_console.cpp
index 66312569..17612d2d 100644
--- a/src/sys/svc/hasp_console.cpp
+++ b/src/sys/svc/hasp_console.cpp
@@ -5,8 +5,10 @@
#if HASP_USE_CONSOLE > 0
+#if HASP_TARGET_ARDUINO
#include "ConsoleInput.h"
#include
+#endif
#include "hasp_debug.h"
#include "hasp_console.h"
@@ -17,15 +19,18 @@
extern hasp_http_config_t http_config;
#endif
+#if HASP_TARGET_ARDUINO
// Create a new Stream that buffers all writes to serialClient
HardwareSerial* bufferedSerialClient = (HardwareSerial*)&HASP_SERIAL;
+ConsoleInput* console;
+#endif
uint8_t consoleLoginState = CONSOLE_UNAUTHENTICATED;
uint16_t serialPort = 0;
uint8_t consoleEnabled = true; // Enable serial debug output
uint8_t consoleLoginAttempt = 0; // Initial attempt
-ConsoleInput* console;
+#if HASP_TARGET_ARDUINO
void console_update_prompt()
{
if(console) console->update(__LINE__);
@@ -101,9 +106,21 @@ static void console_process_line(const char* input)
}
}
}
+#elif HASP_TARGET_PC
+static bool console_running = true;
+static int console_thread(void* arg)
+{
+ while(console_running) {
+ std::string input;
+ std::getline(std::cin, input);
+ dispatch_text_line(input.c_str(), TAG_CONS);
+ }
+}
+#endif
void consoleStart()
{
+#if HASP_TARGET_ARDUINO
LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING));
console = new ConsoleInput(bufferedSerialClient, HASP_CONSOLE_BUFFER);
if(console) {
@@ -126,16 +143,32 @@ void consoleStart()
console_logoff();
LOG_ERROR(TAG_CONS, F(D_SERVICE_START_FAILED));
}
+#elif HASP_TARGET_PC
+ LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING));
+#if defined(WINDOWS)
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)console_thread, NULL, 0, NULL);
+#elif defined(POSIX)
+ pthread_t thread;
+ pthread_create(&thread, NULL, (void* (*)(void*))console_thread, NULL);
+#endif
+#endif
}
void consoleStop()
{
+#if HASP_TARGET_ARDUINO
console_logoff();
Log.unregisterOutput(0); // serialClient
HASP_SERIAL.end();
-
delete console;
console = NULL;
+#elif HASP_TARGET_PC
+#if defined(WINDOWS)
+
+#elif defined(POSIX)
+
+#endif
+#endif
}
void consoleSetup()
@@ -147,6 +180,7 @@ void consoleSetup()
IRAM_ATTR void consoleLoop()
{
+#if HASP_TARGET_ARDUINO
if(!console) return;
bool update = false;
@@ -175,6 +209,7 @@ IRAM_ATTR void consoleLoop()
}
}
if(update) console_update_prompt();
+#endif
}
#if HASP_USE_CONFIG > 0
@@ -201,4 +236,4 @@ bool consoleSetConfig(const JsonObject& settings)
}
#endif // HASP_USE_CONFIG
-#endif
\ No newline at end of file
+#endif
diff --git a/src/sys/svc/hasp_console.h b/src/sys/svc/hasp_console.h
index 10c17b69..18834508 100644
--- a/src/sys/svc/hasp_console.h
+++ b/src/sys/svc/hasp_console.h
@@ -4,10 +4,10 @@
#ifndef HASP_CONSOLE_H
#define HASP_CONSOLE_H
-#if HASP_USE_CONSOLE > 0
-
#include "hasplib.h"
+#if HASP_USE_CONSOLE > 0
+
/* ===== Default Event Processors ===== */
void consoleSetup();
IRAM_ATTR void consoleLoop(void);
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index e3737309..6debc383 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -2,6 +2,9 @@
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
+
+#if HASP_USE_HTTP > 0
+
#include "ArduinoLog.h"
#define HTTP_LEGACY
@@ -21,7 +24,6 @@
#include "hasp_gui.h"
#include "hasp_debug.h"
-#if HASP_USE_HTTP > 0
#include "sys/net/hasp_network.h"
#include "sys/net/hasp_time.h"
diff --git a/src/sys/svc/hasp_http_async.cpp b/src/sys/svc/hasp_http_async.cpp
index 2c8ec707..683d2f50 100644
--- a/src/sys/svc/hasp_http_async.cpp
+++ b/src/sys/svc/hasp_http_async.cpp
@@ -3,6 +3,9 @@
//#include "webServer.h"
#include "hasplib.h"
+
+#if HASP_USE_HTTP_ASYNC > 0
+
#include "ArduinoLog.h"
#if defined(ARDUINO_ARCH_ESP32)
@@ -16,7 +19,6 @@
#include "hasp_gui.h"
#include "hasp_debug.h"
-#if HASP_USE_HTTP_ASYNC > 0
#include "sys/net/hasp_network.h"
/* clang-format off */
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 4a1962c0..7f6b2dca 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -99,6 +99,7 @@ build_src_filter =
-
-
+
+ +
-
+
-
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux_sdl/linux_fbdev_64bits.ini
index 4904cf69..6517de41 100644
--- a/user_setups/linux_sdl/linux_fbdev_64bits.ini
+++ b/user_setups/linux_sdl/linux_fbdev_64bits.ini
@@ -84,6 +84,7 @@ build_src_filter =
-
-
+
+ +
-
+
-
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index 432c9814..09976003 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -89,6 +89,7 @@ build_src_filter =
-
-
+
+ +
-
+
-
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index d2657df5..901d2f36 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -113,6 +113,7 @@ build_src_filter =
-
-
+
+ +
-
+
-
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index 3c6957bb..a9327f8a 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -119,6 +119,7 @@ build_src_filter =
-
-
+
+ +
-
+
-
From 603d38ae3c25844cb40aebe30e6bfec696462ecb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 16:22:29 +0100
Subject: [PATCH 102/135] Support executing shell commands on PC build
---
src/dev/posix/hasp_posix.cpp | 6 +++++
src/dev/posix/hasp_posix.h | 2 ++
src/dev/win32/hasp_win32.cpp | 5 ++++
src/dev/win32/hasp_win32.h | 2 ++
src/hasp/hasp_dispatch.cpp | 45 ++++++++++++++++++++++++++++++++++++
src/sys/svc/hasp_console.cpp | 11 +++------
6 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index 8d864cf7..db6aa584 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -246,6 +246,12 @@ bool PosixDevice::is_system_pin(uint8_t pin)
return false;
}
+void Win32Device::run_thread(void (*func)(void*), void* arg)
+{
+ pthread_t thread;
+ pthread_create(&thread, NULL, (void* (*)(void*))func, arg);
+}
+
#ifndef TARGET_OS_MAC
long PosixDevice::get_uptime()
{
diff --git a/src/dev/posix/hasp_posix.h b/src/dev/posix/hasp_posix.h
index 439d4c12..70f62695 100644
--- a/src/dev/posix/hasp_posix.h
+++ b/src/dev/posix/hasp_posix.h
@@ -58,6 +58,8 @@ class PosixDevice : public BaseDevice {
bool is_system_pin(uint8_t pin) override;
+ void run_thread(void (*func)(void*), void* arg);
+
public:
std::string backlight_device;
int backlight_max = 0;
diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp
index 6f7576de..591ccb75 100644
--- a/src/dev/win32/hasp_win32.cpp
+++ b/src/dev/win32/hasp_win32.cpp
@@ -187,6 +187,11 @@ bool Win32Device::is_system_pin(uint8_t pin)
return false;
}
+void Win32Device::run_thread(void (*func)(void*), void* arg)
+{
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL);
+}
+
long Win32Device::get_uptime()
{
return GetTickCount64() / 1000;
diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h
index 1a25106d..09f56773 100644
--- a/src/dev/win32/hasp_win32.h
+++ b/src/dev/win32/hasp_win32.h
@@ -45,6 +45,8 @@ class Win32Device : public BaseDevice {
bool is_system_pin(uint8_t pin) override;
+ void run_thread(void (*func)(void*), void* arg);
+
private:
std::string _hostname;
std::string _core_version;
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 0b58089f..42cc1750 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -822,6 +822,48 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
#endif
}
+#if HASP_TARGET_PC
+static void shell_command_thread(char* cmdline)
+{
+ // run the command
+ FILE* pipe = popen(cmdline, "r");
+ // free the string duplicated previously
+ free(cmdline);
+ if(!pipe) {
+ LOG_ERROR(TAG_MSGR, F("Couldn't execute system command"));
+ return;
+ }
+ // read each line, up to 1023 chars long
+ char command[1024];
+ while(fgets(command, sizeof(command), pipe) != NULL) {
+ // strip newline character
+ char* temp = command;
+ while(*temp) {
+ if(*temp == '\r' || *temp == '\n') {
+ *temp = '\0';
+ break;
+ }
+ temp++;
+ }
+ // run the command
+ LOG_INFO(TAG_MSGR, F("Running '%s'"), command);
+ dispatch_text_line(command, TAG_MSGR);
+ }
+ // close the pipe, check return code
+ int status_code = pclose(pipe);
+ if(status_code) {
+ LOG_ERROR(TAG_MSGR, F("Process exited with non-zero return code %d"), status_code);
+ }
+}
+
+void dispatch_shell_execute(const char*, const char* payload, uint8_t source)
+{
+ // must duplicate the string for thread's own usage
+ char* command = strdup(payload);
+ haspDevice.run_thread((void (*)(void*))shell_command_thread, (void*)command);
+}
+#endif
+
void dispatch_current_page()
{
char topic[8];
@@ -1495,6 +1537,9 @@ void dispatchSetup()
dispatch_add_command(PSTR("sensors"), dispatch_send_sensordata);
dispatch_add_command(PSTR("theme"), dispatch_theme);
dispatch_add_command(PSTR("run"), dispatch_run_script);
+#if HASP_TARGET_PC
+ dispatch_add_command(PSTR("shell"), dispatch_shell_execute);
+#endif
dispatch_add_command(PSTR("service"), dispatch_service);
dispatch_add_command(PSTR("antiburn"), dispatch_antiburn);
dispatch_add_command(PSTR("calibrate"), dispatch_calibrate);
diff --git a/src/sys/svc/hasp_console.cpp b/src/sys/svc/hasp_console.cpp
index 17612d2d..04ab243f 100644
--- a/src/sys/svc/hasp_console.cpp
+++ b/src/sys/svc/hasp_console.cpp
@@ -108,7 +108,7 @@ static void console_process_line(const char* input)
}
#elif HASP_TARGET_PC
static bool console_running = true;
-static int console_thread(void* arg)
+static void console_thread(void* arg)
{
while(console_running) {
std::string input;
@@ -145,12 +145,7 @@ void consoleStart()
}
#elif HASP_TARGET_PC
LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING));
-#if defined(WINDOWS)
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)console_thread, NULL, 0, NULL);
-#elif defined(POSIX)
- pthread_t thread;
- pthread_create(&thread, NULL, (void* (*)(void*))console_thread, NULL);
-#endif
+ haspDevice.run_thread(console_thread, NULL);
#endif
}
@@ -202,7 +197,7 @@ IRAM_ATTR void consoleLoop()
case 0:
case -1:
break;
-
+
default: {
update = true;
}
From 3cb5eb2d580cf8291eaccd84fdec8362f1785bf0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 18:04:18 +0100
Subject: [PATCH 103/135] Support event data substitution in action commands
---
include/hasp_conf.h | 4 +
src/hasp/hasp_dispatch.cpp | 28 ++++--
src/hasp/hasp_dispatch.h | 3 +-
src/hasp/hasp_event.cpp | 89 ++++++++++++--------
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 3 +-
user_setups/linux_sdl/linux_fbdev_64bits.ini | 3 +-
user_setups/linux_sdl/linux_sdl_64bits.ini | 3 +-
user_setups/win32/windows_gdi_64bits.ini | 3 +-
user_setups/win32/windows_sdl_64bits.ini | 3 +-
9 files changed, 94 insertions(+), 45 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index f458102b..9f4b60ff 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -177,6 +177,10 @@
#define HASP_NUM_GPIO_CONFIG 8
#endif
+#ifndef HASP_USE_EVENT_DATA_SUBST
+#define HASP_USE_EVENT_DATA_SUBST 0
+#endif
+
// #ifndef HASP_USE_CUSTOM
// #define HASP_USE_CUSTOM 0
// #endif
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 42cc1750..1fb19b01 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -610,11 +610,17 @@ void dispatch_screenshot(const char*, const char* filename, uint8_t source)
}
bool dispatch_json_variant(JsonVariant& json, uint8_t& savedPage, uint8_t source)
+{
+ JsonObject dummy;
+ return dispatch_json_variant_with_data(json, savedPage, source, dummy);
+}
+
+bool dispatch_json_variant_with_data(JsonVariant& json, uint8_t& savedPage, uint8_t source, JsonObject& data)
{
if(json.is()) { // handle json as an array of commands
LOG_DEBUG(TAG_MSGR, "Json ARRAY");
for(JsonVariant command : json.as()) {
- dispatch_json_variant(command, savedPage, source);
+ dispatch_json_variant_with_data(command, savedPage, source, data);
}
} else if(json.is()) { // handle json as a jsonl
@@ -622,13 +628,23 @@ bool dispatch_json_variant(JsonVariant& json, uint8_t& savedPage, uint8_t source
hasp_new_object(json.as(), savedPage);
} else if(json.is()) { // handle json as a single command
- LOG_DEBUG(TAG_MSGR, "Json text = %s", json.as().c_str());
- dispatch_simple_text_command(json.as().c_str(), source);
+ std::string command = json.as();
- } else if(json.is()) { // handle json as a single command
- LOG_DEBUG(TAG_MSGR, "Json text = %s", json.as());
- dispatch_simple_text_command(json.as(), source);
+#if HASP_USE_EVENT_DATA_SUBST
+ if(command.find('%') != std::string::npos) {
+ // '%' found in command, run variable substitution
+ for(JsonPair kv : data) {
+ std::string find = "%" + std::string(kv.key().c_str()) + "%";
+ std::string replace = kv.value().as();
+ size_t pos = command.find(find);
+ if(pos == std::string::npos) continue;
+ command.replace(pos, find.length(), replace);
+ }
+ }
+#endif
+ LOG_DEBUG(TAG_MSGR, "Json text = %s", command.c_str());
+ dispatch_simple_text_command(command.c_str(), source);
} else if(json.isNull()) { // event handler not found
// nothing to do
diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h
index 245da30c..53a5804a 100644
--- a/src/hasp/hasp_dispatch.h
+++ b/src/hasp/hasp_dispatch.h
@@ -55,6 +55,7 @@ void dispatch_parse_jsonl(Stream& stream, uint8_t& saved_page_id);
void dispatch_parse_jsonl(std::istream& stream, uint8_t& saved_page_id);
#endif
bool dispatch_json_variant(JsonVariant& json, uint8_t& savedPage, uint8_t source);
+bool dispatch_json_variant_with_data(JsonVariant& json, uint8_t& savedPage, uint8_t source, JsonObject& data);
void dispatch_clear_page(const char* page);
void dispatch_json_error(uint8_t tag, DeserializationError& jsonError);
@@ -101,4 +102,4 @@ struct haspCommand_t
void (*func)(const char*, const char*, uint8_t);
};
-#endif
\ No newline at end of file
+#endif
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index fd5eeaee..9a5cc2bf 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -42,23 +42,47 @@ void event_reset_last_value_sent()
last_value_sent = INT16_MIN;
}
-void script_event_handler(const char* eventname, const char* json)
+static bool script_event_handler(const char* eventname, const char* action, const char* data)
{
+ if(action == NULL) {
+ LOG_DEBUG(TAG_EVENT, F("Skipping event: name=%s, data=%s"), eventname, data);
+ return false;
+ }
StaticJsonDocument<256> doc;
StaticJsonDocument<64> filter;
filter[eventname] = true;
- DeserializationError jsonError = deserializeJson(doc, json, DeserializationOption::Filter(filter));
+ DeserializationError jsonError = deserializeJson(doc, action, DeserializationOption::Filter(filter));
if(!jsonError) {
- JsonVariant json = doc[eventname].as();
+ JsonVariant json = doc[eventname].as();
+ if(json.isNull()) {
+ LOG_DEBUG(TAG_EVENT, F("Skipping event: name=%s, data=%s"), eventname, data);
+ return true;
+ } else {
+ LOG_DEBUG(TAG_EVENT, F("Handling event: name=%s, data=%s"), eventname, data);
+ }
+
+ JsonObject dataJson;
+#if HASP_USE_EVENT_DATA_SUBST
+ if(data != NULL) {
+ StaticJsonDocument<256> jsonDoc;
+ if(deserializeJson(jsonDoc, data) != DeserializationError::Ok) {
+ LOG_ERROR(TAG_EVENT, F("Deserialization failed"));
+ } else {
+ dataJson = jsonDoc.as();
+ }
+ }
+#endif
+
uint8_t savedPage = haspPages.get();
- if(!dispatch_json_variant(json, savedPage, TAG_EVENT)) {
+ if(!dispatch_json_variant_with_data(json, savedPage, TAG_EVENT, dataJson)) {
LOG_WARNING(TAG_EVENT, F(D_DISPATCH_COMMAND_NOT_FOUND), eventname);
}
} else {
dispatch_json_error(TAG_EVENT, jsonError);
}
+ return true;
}
/**
@@ -254,11 +278,16 @@ static bool translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid)
// ##################### Value Senders ########################################################
-static void event_send_object_data(lv_obj_t* obj, const char* data)
+static void event_send_object_data(lv_obj_t* obj, const char* eventname, const char* data)
{
uint8_t pageid;
uint8_t objid;
+ // handle object "action", abort sending if handled
+ if(script_event_handler(eventname, my_obj_get_action(obj), data)) {
+ return;
+ }
+
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
if(!data) return;
object_dispatch_state(pageid, objid, data);
@@ -271,23 +300,23 @@ static void event_send_object_data(lv_obj_t* obj, const char* data)
static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val)
{
char data[512];
+ char eventname[8];
{
- char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"tag\":%s}"), eventname, val, tag);
else
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
}
- event_send_object_data(obj, data);
+ event_send_object_data(obj, eventname, data);
}
// Send out events with a val and text attribute
static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text)
{
char data[512];
+ char eventname[8];
{
- char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
@@ -296,7 +325,7 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16
else
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), eventname, val, text);
}
- event_send_object_data(obj, data);
+ event_send_object_data(obj, eventname, data);
}
// ##################### Event Handlers ########################################################
@@ -402,16 +431,16 @@ void swipe_event_handler(lv_obj_t* obj, lv_event_t event)
lv_gesture_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
switch(dir) {
case LV_GESTURE_DIR_LEFT:
- script_event_handler("left", swipe);
+ script_event_handler("left", swipe, NULL);
break;
case LV_GESTURE_DIR_RIGHT:
- script_event_handler("right", swipe);
+ script_event_handler("right", swipe, NULL);
break;
case LV_GESTURE_DIR_BOTTOM:
- script_event_handler("down", swipe);
+ script_event_handler("down", swipe, NULL);
break;
default:
- script_event_handler("up", swipe);
+ script_event_handler("up", swipe, NULL);
}
}
}
@@ -432,8 +461,8 @@ void textarea_event_handler(lv_obj_t* obj, lv_event_t event)
if(!translate_event(obj, event, hasp_event_id)) return;
char data[1024];
+ char eventname[8];
{
- char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
@@ -444,7 +473,7 @@ void textarea_event_handler(lv_obj_t* obj, lv_event_t event)
lv_textarea_get_text(obj));
}
- event_send_object_data(obj, data);
+ event_send_object_data(obj, eventname, data);
} else if(event == LV_EVENT_FOCUSED) {
lv_textarea_set_cursor_hidden(obj, false);
} else if(event == LV_EVENT_DEFOCUSED) {
@@ -518,23 +547,17 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event)
if(last_value_sent == HASP_EVENT_LOST) return;
- if(const char* action = my_obj_get_action(obj)) {
- char eventname[8];
+ char data[512];
+ char eventname[8];
+ {
Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
- script_event_handler(eventname, action);
- } else {
- char data[512];
- {
- char eventname[8];
- Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
- if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
- else
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
- }
- event_send_object_data(obj, data);
+ if(const char* tag = my_obj_get_tag(obj))
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
+ else
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
}
+ event_send_object_data(obj, eventname, data);
// Update group objects and gpios on release
if(last_value_sent != LV_EVENT_LONG_PRESSED && last_value_sent != LV_EVENT_LONG_PRESSED_REPEAT) {
@@ -841,8 +864,8 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
if(hasp_event_id == HASP_EVENT_CHANGED && last_color_sent.full == color.full) return; // same value as before
char data[512];
+ char eventname[8];
{
- char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
lv_color32_t c32;
@@ -864,7 +887,7 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
hsv.s, hsv.v);
}
- event_send_object_data(obj, data);
+ event_send_object_data(obj, eventname, data);
// event_update_group(obj->user_data.groupid, obj, val, min, max);
}
@@ -891,8 +914,8 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
return; // same object and value as before
char data[512];
+ char eventname[8];
{
- char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
last_value_sent = val;
@@ -907,7 +930,7 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
PSTR("{\"event\":\"%s\",\"val\":\"%d\",\"text\":\"%04d-%02d-%02dT00:00:00Z\"}"), eventname,
date->day, date->year, date->month, date->day);
}
- event_send_object_data(obj, data);
+ event_send_object_data(obj, eventname, data);
// event_update_group(obj->user_data.groupid, obj, val, min, max);
}
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 7f6b2dca..55e0288c 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -34,7 +34,8 @@ build_flags =
-D HASP_USE_GIFDECODE=0
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
- -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_USE_EVENT_DATA_SUBST=1
+ -D MQTT_MAX_PACKET_SIZE=32768
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux_sdl/linux_fbdev_64bits.ini
index 6517de41..a709efb7 100644
--- a/user_setups/linux_sdl/linux_fbdev_64bits.ini
+++ b/user_setups/linux_sdl/linux_fbdev_64bits.ini
@@ -31,7 +31,8 @@ build_flags =
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
-D HASP_USE_LVGL_TASK=1
- -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_USE_EVENT_DATA_SUBST=1
+ -D MQTT_MAX_PACKET_SIZE=32768
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index 09976003..fc3287cc 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -34,7 +34,8 @@ build_flags =
-D HASP_USE_GIFDECODE=0
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
- -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_USE_EVENT_DATA_SUBST=1
+ -D MQTT_MAX_PACKET_SIZE=32768
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index 901d2f36..23062b6f 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -30,7 +30,8 @@ build_flags =
-D HASP_USE_MQTT=1
-D HASP_USE_SYSLOG=0
-D HASP_USE_LVGL_TASK=1
- -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_USE_EVENT_DATA_SUBST=1
+ -D MQTT_MAX_PACKET_SIZE=32768
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index a9327f8a..bd4338b1 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -34,7 +34,8 @@ build_flags =
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
-D HASP_USE_SYSLOG=0
- -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_USE_EVENT_DATA_SUBST=1
+ -D MQTT_MAX_PACKET_SIZE=32768
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
From 3fcae65fadb3f2cf1671c0d3a091ffb4cec85109 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 18:20:54 +0100
Subject: [PATCH 104/135] Allow suppressing console output on PC build
---
src/dev/posix/hasp_posix.cpp | 2 +-
src/main_pc.cpp | 11 +++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index db6aa584..e5f1b173 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -246,7 +246,7 @@ bool PosixDevice::is_system_pin(uint8_t pin)
return false;
}
-void Win32Device::run_thread(void (*func)(void*), void* arg)
+void PosixDevice::run_thread(void (*func)(void*), void* arg)
{
pthread_t thread;
pthread_create(&thread, NULL, (void* (*)(void*))func, arg);
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 63d3d2bb..40431d75 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -17,6 +17,7 @@
#if defined(POSIX)
#include
#include
+#include
#include
#include
#include
@@ -112,6 +113,7 @@ void usage(const char* progName, const char* version)
<< std::endl
<< "Options:" << std::endl
<< " -h | --help Print this help" << std::endl
+ << " -q | --quiet Suppress console output (can improve performance)" << std::endl
#if !USE_FBDEV
<< " -W | --width Width of the window" << std::endl
<< " -H | --height Height of the window" << std::endl
@@ -140,6 +142,15 @@ int main(int argc, char* argv[])
for(int arg = 1; arg < argc; arg++) {
if(strncmp(argv[arg], "--help", 6) == 0 || strncmp(argv[arg], "-h", 2) == 0) {
showhelp = true;
+ } else if(strncmp(argv[arg], "--quiet", 7) == 0 || strncmp(argv[arg], "-q", 2) == 0) {
+#if defined(WINDOWS)
+ FreeConsole();
+#endif
+#if defined(POSIX)
+ int nullfd = open("/dev/null", O_WRONLY);
+ dup2(nullfd, 1);
+ close(nullfd);
+#endif
#if !USE_FBDEV
} else if(strncmp(argv[arg], "--width", 7) == 0 || strncmp(argv[arg], "-W", 2) == 0) {
if(arg + 1 < argc) {
From 32c21b9c5235acb61f9112f3b2dd0ff2a491e5b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 20:30:12 +0100
Subject: [PATCH 105/135] Implement command scheduling
---
src/hasp/hasp_dispatch.cpp | 87 ++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 1fb19b01..b5795d16 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -37,6 +37,8 @@
#endif
#endif
+#include
+
dispatch_conf_t dispatch_setings = {.teleperiod = 300};
uint16_t dispatchSecondsToNextTeleperiod = 0;
@@ -48,6 +50,8 @@ haspCommand_t commands[28];
moodlight_t moodlight = {.brightness = 255};
uint8_t saved_jsonl_page = 0;
+static std::map scheduled_tasks;
+
/* Sends the payload out on the state/subtopic
*/
void dispatch_state_subtopic(const char* subtopic, const char* payload)
@@ -1414,6 +1418,88 @@ void dispatch_sleep(const char*, const char*, uint8_t source)
hasp_set_wakeup_touch(false);
}
+static void dispatch_schedule_runner(lv_task_t* task)
+{
+ dispatch_text_line((const char*)task->user_data, TAG_MSGR);
+}
+
+void dispatch_schedule(const char*, const char* payload, uint8_t source)
+{
+ // duplicate the string for modification
+ char* argline = strdup(payload);
+ // split argline into argv by whitespace; limit to 4 parts
+ char* argv[4];
+ int argn = 0;
+ argv[argn++] = argline;
+ while(*argline) {
+ if(*argline == ' ') {
+ *argline = '\0';
+ argv[argn++] = argline + 1;
+ }
+ argline++;
+ if(argn == 4) break;
+ }
+
+ const char* action = argv[0];
+ uint32_t id = atoi(argv[1]);
+
+ if(strcasecmp(action, "set") == 0) {
+ if(argn != 4) {
+ LOG_ERROR(TAG_MSGR, F("Usage: schedule set "));
+ goto end;
+ }
+ uint32_t period = atoi(argv[2]);
+ const char* command = strdup(argv[3]);
+
+ if(scheduled_tasks.find(id) != scheduled_tasks.end()) {
+ // update an existing task
+ lv_task_t* task = scheduled_tasks[id];
+ free(task->user_data);
+ task->period = period;
+ task->user_data = (void*)command;
+ } else {
+ // create a new task
+ lv_task_t* task = lv_task_create(dispatch_schedule_runner, period, LV_TASK_PRIO_MID, (void*)command);
+ scheduled_tasks[id] = task;
+ }
+
+ LOG_INFO(TAG_MSGR, F("Scheduled command ID %u, every %u ms: %s"), id, period, command);
+
+ goto end;
+ }
+
+ if(argn != 2) {
+ LOG_ERROR(TAG_MSGR, F("Usage: schedule "));
+ goto end;
+ }
+ if(scheduled_tasks.find(id) == scheduled_tasks.end()) {
+ LOG_ERROR(TAG_MSGR, F("Task by ID %u does not exist"), id);
+ goto end;
+ }
+
+ {
+ lv_task_t* task = scheduled_tasks[id];
+ if(strcasecmp(action, "del") == 0) {
+ free(task->user_data);
+ lv_task_del(task);
+ scheduled_tasks.erase(id);
+ goto end;
+ }
+ if(strcasecmp(action, "start") == 0) {
+ lv_task_set_prio(task, LV_TASK_PRIO_MID);
+ goto end;
+ }
+ if(strcasecmp(action, "stop") == 0) {
+ lv_task_set_prio(task, LV_TASK_PRIO_OFF);
+ goto end;
+ }
+ }
+
+end:
+ // release the duplicated argline
+ free(argv[0]);
+}
+
void dispatch_idle_state(uint8_t state)
{
char topic[8];
@@ -1547,6 +1633,7 @@ void dispatchSetup()
dispatch_add_command(PSTR("moodlight"), dispatch_moodlight);
dispatch_add_command(PSTR("idle"), dispatch_idle);
dispatch_add_command(PSTR("sleep"), dispatch_sleep);
+ dispatch_add_command(PSTR("schedule"), dispatch_schedule);
dispatch_add_command(PSTR("statusupdate"), dispatch_statusupdate);
dispatch_add_command(PSTR("clearpage"), dispatch_clear_page);
dispatch_add_command(PSTR("clearfont"), dispatch_clear_font);
From e93597a881268fcfcd0b8c2a7037a66f1357edbd Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Sat, 10 Feb 2024 21:50:09 +0100
Subject: [PATCH 106/135] Little wireguard cleanups
- accept the password mask as valid input string in web ui
- do not set the new configuration immediatelly (use manual restart like for wifi)
---
src/lang/lang.h | 2 +-
src/sys/net/hasp_wireguard.cpp | 11 +++++------
src/sys/svc/hasp_http.cpp | 2 +-
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/lang/lang.h b/src/lang/lang.h
index 20411ecd..cfc2ed88 100644
--- a/src/lang/lang.h
+++ b/src/lang/lang.h
@@ -11,7 +11,7 @@
#endif
// language independent defines
-#define D_PASSWORD_MASK "********"
+#define D_PASSWORD_MASK "********" // beware: webui have this string hardcoded!
#define D_BULLET " * "
#define D_MANUFACTURER "openHASP"
#define D_BACK_ICON "↩ "
diff --git a/src/sys/net/hasp_wireguard.cpp b/src/sys/net/hasp_wireguard.cpp
index c2ca170a..fb485295 100644
--- a/src/sys/net/hasp_wireguard.cpp
+++ b/src/sys/net/hasp_wireguard.cpp
@@ -103,7 +103,6 @@ bool wgSetConfig(const JsonObject& settings)
configOutput(settings, TAG_WG);
bool changed = false;
- bool changed_privkey = false;
changed |= configSet((char *)wg_ip, sizeof(wg_ip), settings[FPSTR(FP_CONFIG_VPN_IP)], F("wgIp"));
if(!settings[FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull() &&
@@ -113,15 +112,15 @@ bool wgSetConfig(const JsonObject& settings)
wg_private_key[sizeof(wg_private_key)-1] = '\0';
nvsUpdateString(preferences, FP_CONFIG_PRIVATE_KEY, settings[FPSTR(FP_CONFIG_PRIVATE_KEY)]);
}
- changed |= changed_privkey;
changed |= configSet((char *)wg_ep_ip, sizeof(wg_ep_ip), settings[FPSTR(FP_CONFIG_HOST)], F("wgEpIp"));
changed |= configSet(wg_ep_port, settings[FPSTR(FP_CONFIG_PORT)], F("wgEpPort"));
changed |= configSet((char *)wg_ep_public_key, sizeof(wg_ep_public_key), settings[FPSTR(FP_CONFIG_PUBLIC_KEY)], F("wgEpPubKey"));
- if (changed && network_is_connected()) {
- wg.end();
- wg_network_connected();
- }
+// may reset device...
+// if (changed && network_is_connected()) {
+// wg.end();
+// wg_network_connected();
+// }
return changed;
}
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index 1f78c7f8..1b91f801 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -2353,7 +2353,7 @@ static void http_handle_wireguard()
From d0d2bc19409dee40d9598ecb0210aaa9ac8488b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 23:43:28 +0100
Subject: [PATCH 107/135] Enable Paho Async MQTT client on PC build
---
include/hasp_conf.h | 4 +
src/mqtt/hasp_mqtt_paho_async.cpp | 558 ++++++++++++-------
src/mqtt/hasp_mqtt_paho_single.cpp | 2 +-
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 13 +-
user_setups/linux_sdl/linux_fbdev_64bits.ini | 12 +-
user_setups/linux_sdl/linux_sdl_64bits.ini | 12 +-
user_setups/win32/windows_gdi_64bits.ini | 12 +-
user_setups/win32/windows_sdl_64bits.ini | 12 +-
8 files changed, 385 insertions(+), 240 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index 9f4b60ff..e36b8925 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -70,6 +70,10 @@
#define HASP_USE_MQTT (HASP_HAS_NETWORK)
#endif
+#ifndef HASP_USE_MQTT_ASYNC
+#define HASP_USE_MQTT_ASYNC (HASP_TARGET_PC)
+#endif
+
#ifndef HASP_USE_WIREGUARD
#define HASP_USE_WIREGUARD (HASP_HAS_NETWORK)
#endif
diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp
index b56783fa..5485fe9e 100644
--- a/src/mqtt/hasp_mqtt_paho_async.cpp
+++ b/src/mqtt/hasp_mqtt_paho_async.cpp
@@ -10,6 +10,15 @@
#if HASP_USE_MQTT_ASYNC > 0
#ifdef HASP_USE_PAHO
+#if !HASP_USE_CONFIG
+const char FP_CONFIG_HOST[] PROGMEM = "host";
+const char FP_CONFIG_PORT[] PROGMEM = "port";
+const char FP_CONFIG_NAME[] PROGMEM = "name";
+const char FP_CONFIG_USER[] PROGMEM = "user";
+const char FP_CONFIG_PASS[] PROGMEM = "pass";
+const char FP_CONFIG_GROUP[] PROGMEM = "group";
+#endif
+
/*******************************************************************************
* Copyright (c) 2012, 2020 IBM Corp.
*
@@ -38,7 +47,7 @@
#include "hasp_mqtt.h" // functions to implement here
#include "hasp/hasp_dispatch.h" // for dispatch_topic_payload
-#include "hasp_debug.h" // for logging
+#include "hasp_debug.h" // for logging
#if !defined(_WIN32)
#include
@@ -50,78 +59,122 @@
#include
#endif
-#define ADDRESS "10.4.0.5:1883"
-#define CLIENTID "ExampleClientSub"
-#define TOPIC "hasp/plate35/"
+// #define ADDRESS "10.4.0.5:1883"
+// #define CLIENTID "ExampleClientSub"
+// #define TOPIC "hasp/plate35/"
#define QOS 1
#define TIMEOUT 10000L
-const char* mqttNodeTopic = TOPIC;
-const char* mqttGroupTopic = TOPIC;
-// char mqttNodeTopic[24];
-// char mqttGroupTopic[24];
+std::string mqttNodeTopic;
+std::string mqttGroupTopic;
+std::string mqttLwtTopic;
bool mqttEnabled = false;
bool mqttHAautodiscover = true;
+uint32_t mqttPublishCount;
+uint32_t mqttReceiveCount;
+uint32_t mqttFailedCount;
std::recursive_mutex dispatch_mtx;
std::recursive_mutex publish_mtx;
-char mqttServer[MAX_HOSTNAME_LENGTH] = MQTT_HOSTNAME;
-char mqttUser[MAX_USERNAME_LENGTH] = MQTT_USERNAME;
-char mqttPassword[MAX_PASSWORD_LENGTH] = MQTT_PASSWORD;
-// char mqttNodeName[16] = MQTT_NODENAME;
-char mqttGroupName[16] = MQTT_GROUPNAME;
-uint16_t mqttPort = MQTT_PORT;
+std::string mqttServer = MQTT_HOSTNAME;
+std::string mqttUsername = MQTT_USERNAME;
+std::string mqttPassword = MQTT_PASSWORD;
+std::string mqttGroupName = MQTT_GROUPNAME;
+uint16_t mqttPort = MQTT_PORT;
MQTTAsync mqtt_client;
-int disc_finished = 0;
-int subscribed = 0;
-int connected = 0;
+static bool mqttConnecting = false;
+static bool mqttConnected = false;
-static bool mqttPublish(const char* topic, const char* payload, size_t len, bool retain = false);
+int mqttPublish(const char* topic, const char* payload, size_t len, bool retain = false);
/* ===== Paho event callbacks ===== */
-void connlost(void* context, char* cause)
+static void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
- printf("\nConnection lost\n");
- if(cause) printf(" cause: %s\n", cause);
+ mqttConnecting = false;
+ mqttConnected = false;
+ LOG_ERROR(TAG_MQTT, "Connection failed, return code %d (%s)", response->code, response->message);
+}
- printf("Reconnecting\n");
- mqttStart();
+static void onDisconnect(void* context, MQTTAsync_successData* response)
+{
+ mqttConnecting = false;
+ mqttConnected = false;
+}
+
+static void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
+{
+ mqttConnecting = false;
+ mqttConnected = false;
+ LOG_ERROR(TAG_MQTT, "Disconnection failed, return code %d (%s)", response->code, response->message);
+}
+
+static void onSendFailure(void* context, MQTTAsync_failureData* response)
+{
+ LOG_ERROR(TAG_MQTT, "Send failed, return code %d (%s)", response->code, response->message);
+}
+
+static void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
+{
+ LOG_ERROR(TAG_MQTT, "Subscribe failed, return code %d (%s)", response->code, response->message);
+}
+
+static void connlost(void* context, char* cause)
+{
+ LOG_WARNING(TAG_MQTT, F(D_MQTT_DISCONNECTED ": %s"), cause);
+ mqttConnecting = false;
+ mqttConnected = false;
}
// Receive incoming messages
static void mqtt_message_cb(char* topic, char* payload, size_t length)
{ // Handle incoming commands from MQTT
if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
+ mqttFailedCount++;
LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), (uint32_t)length);
return;
} else {
+ mqttReceiveCount++;
payload[length] = '\0';
}
LOG_TRACE(TAG_MQTT_RCV, F("%s = %s"), topic, (char*)payload);
- if(topic == strstr(topic, mqttNodeTopic)) { // startsWith mqttNodeTopic
+ if(topic == strstr(topic, mqttNodeTopic.c_str())) { // startsWith mqttNodeTopic
// Node topic
- topic += strlen(mqttNodeTopic); // shorten topic
+ topic += mqttNodeTopic.length(); // shorten topic
- } else if(topic == strstr(topic, mqttGroupTopic)) { // startsWith mqttGroupTopic
+ } else if(topic == strstr(topic, mqttGroupTopic.c_str())) { // startsWith mqttGroupTopic
// Group topic
- topic += strlen(mqttGroupTopic); // shorten topic
+ topic += mqttGroupTopic.length(); // shorten topic
dispatch_mtx.lock();
- dispatch_topic_payload(topic, (const char*)payload);
+ dispatch_topic_payload(topic, (const char*)payload, length > 0, TAG_MQTT);
dispatch_mtx.unlock();
return;
+#ifdef HASP_USE_BROADCAST
+ } else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST
+ "/"))) { // /" MQTT_TOPIC_BROADCAST "/ discovery topic
+
+ // /" MQTT_TOPIC_BROADCAST "/ topic
+ topic += strlen(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/"); // shorten topic
+ dispatch_mtx.lock();
+ dispatch_topic_payload(topic, (const char*)payload, length > 0, TAG_MQTT);
+ dispatch_mtx.unlock();
+ return;
+#endif
+
#ifdef HASP_USE_HA
} else if(topic == strstr_P(topic, PSTR("homeassistant/status"))) { // HA discovery topic
if(mqttHAautodiscover && !strcasecmp_P((char*)payload, PSTR("online"))) {
- dispatch_current_state();
+ dispatch_mtx.lock();
+ dispatch_current_state(TAG_MQTT);
+ dispatch_mtx.unlock();
mqtt_ha_register_auto_discovery();
}
return;
@@ -138,11 +191,8 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length)
if(!strcasecmp_P((char*)payload, PSTR("offline"))) {
{
char msg[8];
- char tmp_topic[strlen(mqttNodeTopic) + 8];
- snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_LWT), mqttNodeTopic);
snprintf_P(msg, sizeof(msg), PSTR("online"));
-
- mqttPublish(tmp_topic, msg, true);
+ mqttPublish(mqttLwtTopic.c_str(), msg, strlen(msg), true);
}
} else {
@@ -150,175 +200,147 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length)
}
} else {
dispatch_mtx.lock();
- dispatch_topic_payload(topic, (const char*)payload);
+ dispatch_topic_payload(topic, (const char*)payload, length > 0, TAG_MQTT);
dispatch_mtx.unlock();
}
}
-int msgarrvd(void* context, char* topicName, int topicLen, MQTTAsync_message* message)
+static int mqtt_message_arrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message)
{
- // printf("MQT RCV >> ");
- // printf("%s => %.*s (%d)\n", topicName, message->payloadlen, (char *)message->payload, message->payloadlen);
-
char msg[message->payloadlen + 1];
memcpy(msg, (char*)message->payload, message->payloadlen);
msg[message->payloadlen] = '\0';
- mqtt_message_cb(topicName, (char*)message->payload, message->payloadlen);
+ mqtt_message_cb(topicName, msg, message->payloadlen);
MQTTAsync_freeMessage(&message);
MQTTAsync_free(topicName);
- return 1;
+ return 1; // the message was received properly
}
-void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
-{
- printf("Disconnect failed, rc %d\n", response->code);
- disc_finished = 1;
-}
-
-void onDisconnect(void* context, MQTTAsync_successData* response)
-{
- printf("Successful disconnection\n");
- disc_finished = 1;
- connected = 0;
-}
-
-void onSubscribe(void* context, MQTTAsync_successData* response)
-{
- printf("Subscribe succeeded %d\n", response->token);
- subscribed = 1;
-}
-
-void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
-{
- printf("Subscribe failed, rc %d\n", response->code);
-}
-
-void onConnectFailure(void* context, MQTTAsync_failureData* response)
-{
- connected = 0;
- printf("Connect failed, rc %d\n", response->code);
-}
-
-void mqtt_subscribe(void* context, const char* topic)
+static void mqtt_subscribe(void* context, const char* topic)
{
MQTTAsync client = (MQTTAsync)context;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
int rc;
- printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n", topic, CLIENTID, QOS);
- opts.onSuccess = onSubscribe;
opts.onFailure = onSubscribeFailure;
opts.context = client;
if((rc = MQTTAsync_subscribe(client, topic, QOS, &opts)) != MQTTASYNC_SUCCESS) {
- printf("Failed to start subscribe, return code %d\n", rc);
+ LOG_WARNING(TAG_MQTT, D_BULLET D_MQTT_NOT_SUBSCRIBED, topic); // error code rc
+ } else {
+ LOG_VERBOSE(TAG_MQTT, D_BULLET D_MQTT_SUBSCRIBED, topic);
}
}
-void onConnect(void* context, MQTTAsync_successData* response)
-{
- MQTTAsync client = (MQTTAsync)context;
- connected = 1;
-
- printf("Successful connection\n");
-
- mqtt_subscribe(context, TOPIC MQTT_TOPIC_COMMAND "/#");
- mqtt_subscribe(context, TOPIC MQTT_TOPIC_COMMAND);
- mqtt_subscribe(context, TOPIC "light");
- mqtt_subscribe(context, TOPIC "dim");
-
- mqttPublish(TOPIC MQTT_TOPIC_LWT, "online", false);
-
- mqtt_send_object_state(0, 0, "connected");
- std::cout << std::endl;
-}
-
-void onSendFailure(void* context, MQTTAsync_failureData* response)
-{
- MQTTAsync client = (MQTTAsync)context;
- MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
- int rc;
-
- printf("Message send failed token %d error code %d\n", response->token, response->code);
- opts.onSuccess = onDisconnect;
- opts.onFailure = onDisconnectFailure;
- opts.context = client;
- if((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) {
- printf("Failed to start disconnect, return code %d\n", rc);
- // exit(EXIT_FAILURE);
- }
-}
-
-void onSend(void* context, MQTTAsync_successData* response)
-{
- MQTTAsync client = (MQTTAsync)context;
- MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
- int rc;
-
- // printf("Message with token value %d delivery confirmed\n", response->token);
-
- // opts.onSuccess = onDisconnect;
- // opts.onFailure = onDisconnectFailure;
- // opts.context = client;
- // if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
- // {
- // printf("Failed to start disconnect, return code %d\n", rc);
- // exit(EXIT_FAILURE);
- // }
-}
-
/* ===== Local HASP MQTT functions ===== */
-static bool mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
+int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
{
- if(mqttIsConnected()) {
- MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
- MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
- int rc;
+ if(!mqttEnabled) return MQTT_ERR_DISABLED;
- opts.onSuccess = onSend;
- opts.onFailure = onSendFailure;
- opts.context = mqtt_client;
- pubmsg.payload = (char*)payload;
- pubmsg.payloadlen = (int)strlen(payload);
- pubmsg.qos = QOS;
- pubmsg.retained = 0;
- dispatch_mtx.lock();
- if((rc = MQTTAsync_sendMessage(mqtt_client, topic, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) {
- dispatch_mtx.unlock();
- LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " %s => %s"), topic, payload);
- } else {
- dispatch_mtx.unlock();
- LOG_TRACE(TAG_MQTT_PUB, F("%s => %s"), topic, payload);
- return true;
- }
- } else {
- LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED));
+ if(!mqttIsConnected()) {
+ mqttFailedCount++;
+ return MQTT_ERR_NO_CONN;
+ }
+
+ MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
+ MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
+
+ opts.onFailure = onSendFailure;
+ opts.context = mqtt_client;
+ pubmsg.payload = (char*)payload;
+ pubmsg.payloadlen = (int)strlen(payload);
+ pubmsg.qos = QOS;
+ pubmsg.retained = 0;
+
+ dispatch_mtx.lock();
+ int rc = MQTTAsync_sendMessage(mqtt_client, topic, &pubmsg, &opts);
+
+ if(rc != MQTTASYNC_SUCCESS) {
+ dispatch_mtx.unlock();
+ mqttFailedCount++;
+ LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " '%s' => %s"), topic, payload);
+ return MQTT_ERR_PUB_FAIL;
+ } else {
+ dispatch_mtx.unlock();
+ mqttPublishCount++;
+ // LOG_TRACE(TAG_MQTT_PUB, F("'%s' => %s OK"), topic, payload);
+ return MQTT_ERR_OK;
}
- return false;
}
/* ===== Public HASP MQTT functions ===== */
bool mqttIsConnected()
{
- return connected == 1;
+ return mqttConnected; // MQTTAsync_isConnected(mqtt_client); // <- deadlocking on Linux
}
-void mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload)
+int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload)
{
- char tmp_topic[strlen(mqttNodeTopic) + 20];
- printf(("%s" MQTT_TOPIC_STATE "/%s\n"), mqttNodeTopic, subtopic);
- snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic, subtopic);
- mqttPublish(tmp_topic, payload, false);
+ char tmp_topic[mqttNodeTopic.length() + 20];
+ snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic.c_str(), subtopic);
+ return mqttPublish(tmp_topic, payload, strlen(payload), false);
}
-void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
+int mqtt_send_discovery(const char* payload, size_t len)
{
- char tmp_topic[strlen(mqttNodeTopic) + 20];
- snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/p%ub%u"), mqttNodeTopic, pageid, btnid);
- mqttPublish(tmp_topic, payload, false);
+ char tmp_topic[128];
+ snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/" MQTT_TOPIC_DISCOVERY "/%s"),
+ haspDevice.get_hardware_id());
+ return mqttPublish(tmp_topic, payload, len, false);
+}
+
+// int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
+// {
+// char tmp_topic[mqttNodeTopic.length() + 20];
+// snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/p%ub%u"), mqttNodeTopic.c_str(), pageid,
+// btnid);
+// return mqttPublish(tmp_topic, payload, strlen(payload), false);
+// }
+
+static void onConnect(void* context, MQTTAsync_successData* response)
+{
+ mqttConnecting = false;
+ mqttConnected = true;
+ MQTTAsync client = (MQTTAsync)context;
+ std::string topic;
+
+ LOG_VERBOSE(TAG_MQTT, D_MQTT_CONNECTED, mqttServer.c_str(), haspDevice.get_hostname());
+
+ topic = mqttGroupTopic + MQTT_TOPIC_COMMAND "/#";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+
+ topic = mqttNodeTopic + MQTT_TOPIC_COMMAND "/#";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+
+ topic = mqttGroupTopic + "config/#";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+
+ topic = mqttNodeTopic + "config/#";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+
+#if defined(HASP_USE_CUSTOM)
+ topic = mqttGroupTopic + MQTT_TOPIC_CUSTOM "/#";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+
+ topic = mqttNodeTopic + MQTT_TOPIC_CUSTOM "/#";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+#endif
+
+#ifdef HASP_USE_BROADCAST
+ topic = MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/" MQTT_TOPIC_COMMAND "/#";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+#endif
+
+ /* Home Assistant auto-configuration */
+#ifdef HASP_USE_HA
+ topic = "homeassistant/status";
+ mqtt_subscribe(mqtt_client, topic.c_str());
+#endif
+
+ mqttPublish(mqttLwtTopic.c_str(), "online", 6, true);
}
void mqttStart()
@@ -328,47 +350,51 @@ void mqttStart()
int rc;
int ch;
- if((rc = MQTTAsync_create(&mqtt_client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) !=
+ if((rc = MQTTAsync_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
+ NULL)) != MQTTASYNC_SUCCESS) {
+ LOG_ERROR(TAG_MQTT, "Failed to create client, return code %d", rc);
+ rc = EXIT_FAILURE;
+ return;
+ }
+
+ if((rc = MQTTAsync_setCallbacks(mqtt_client, mqtt_client, connlost, mqtt_message_arrived, NULL)) !=
MQTTASYNC_SUCCESS) {
- printf("Failed to create client, return code %d\n", rc);
+ LOG_ERROR(TAG_MQTT, "Failed to set callbacks, return code %d", rc);
rc = EXIT_FAILURE;
return;
}
- if((rc = MQTTAsync_setCallbacks(mqtt_client, mqtt_client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) {
- printf("Failed to set callbacks, return code %d\n", rc);
- rc = EXIT_FAILURE;
- return;
- }
+ mqttEnabled = mqttServer.length() > 0 && mqttPort > 0;
- conn_opts.will = &will_opts;
- conn_opts.will->message = "offline";
- conn_opts.will->qos = 1;
- conn_opts.will->retained = 0;
- conn_opts.will->topicName = "hasp/plate35/LWT";
+ if(mqttEnabled) {
+ conn_opts.will = &will_opts;
+ conn_opts.will->message = "offline";
+ conn_opts.will->qos = 1;
+ conn_opts.will->retained = 1;
+ conn_opts.will->topicName = mqttLwtTopic.c_str();
- conn_opts.keepAliveInterval = 20;
- conn_opts.cleansession = 1;
- conn_opts.onSuccess = onConnect;
- conn_opts.onFailure = onConnectFailure;
- conn_opts.context = mqtt_client;
+ conn_opts.keepAliveInterval = 20;
+ conn_opts.cleansession = 1;
+ conn_opts.connectTimeout = 2; // seconds
+ conn_opts.retryInterval = 15; // 0 = no retry
+ conn_opts.onSuccess = onConnect;
+ conn_opts.onFailure = onConnectFailure;
+ conn_opts.context = mqtt_client;
- if((rc = MQTTAsync_connect(mqtt_client, &conn_opts)) != MQTTASYNC_SUCCESS) {
- printf("Failed to start connect, return code %d\n", rc);
- rc = EXIT_FAILURE;
- // goto destroy_exit;
+ conn_opts.username = mqttUsername.c_str();
+ conn_opts.password = mqttPassword.c_str();
+
+ mqttConnecting = true;
+ if((rc = MQTTAsync_connect(mqtt_client, &conn_opts)) != MQTTASYNC_SUCCESS) {
+ mqttConnecting = false;
+ LOG_ERROR(TAG_MQTT, "Failed to connect, return code %d", rc);
+ rc = EXIT_FAILURE;
+ // goto destroy_exit;
+ }
} else {
+ rc = EXIT_FAILURE;
+ LOG_WARNING(TAG_MQTT, "Mqtt server not configured");
}
-
- // while (!subscribed && !finished)
- // #if defined(_WIN32)
- // Sleep(100);
- // #else
- // usleep(10000L);
- // #endif
-
- // if (finished)
- // goto exit;
}
void mqttStop()
@@ -378,30 +404,146 @@ void mqttStop()
disc_opts.onSuccess = onDisconnect;
disc_opts.onFailure = onDisconnectFailure;
if((rc = MQTTAsync_disconnect(mqtt_client, &disc_opts)) != MQTTASYNC_SUCCESS) {
- printf("Failed to start disconnect, return code %d\n", rc);
+ LOG_ERROR(TAG_MQTT, "Failed to disconnect, return code %d", rc);
rc = EXIT_FAILURE;
- // goto destroy_exit;
}
- // while (!disc_finished)
- // {
- // #if defined(_WIN32)
- // Sleep(100);
- // #else
- // usleep(10000L);
- // #endif
- // }
-
- // destroy_exit:
- // MQTTAsync_destroy(&client);
- // exit:
- // return rc;
}
-void mqttSetup(){};
+void mqttSetup()
+{
+ mqttNodeTopic = MQTT_PREFIX;
+ mqttNodeTopic += "/";
+ mqttNodeTopic += haspDevice.get_hostname();
+ mqttNodeTopic += "/";
+
+ mqttGroupTopic = MQTT_PREFIX;
+ mqttGroupTopic += "/";
+ mqttGroupTopic += mqttGroupName;
+ mqttGroupTopic += "/";
+
+ mqttLwtTopic = mqttNodeTopic;
+ mqttLwtTopic += MQTT_TOPIC_LWT;
+}
IRAM_ATTR void mqttLoop(){};
-void mqttEvery5Seconds(bool wifiIsConnected){};
+void mqttEvery5Seconds(bool wifiIsConnected)
+{
+ if(!mqttIsConnected() && !mqttConnecting && mqttServer.length() > 0 && mqttPort > 0) {
+ LOG_WARNING(TAG_MQTT, F(D_MQTT_RECONNECTING));
+ mqttStart();
+ }
+};
+
+void mqtt_get_info(JsonDocument& doc)
+{
+ char mqttClientId[64];
+
+ JsonObject info = doc.createNestedObject(F("MQTT"));
+ info[F(D_INFO_SERVER)] = mqttServer;
+ info[F(D_INFO_USERNAME)] = mqttUsername;
+ info[F(D_INFO_CLIENTID)] = haspDevice.get_hostname();
+ info[F(D_INFO_STATUS)] = mqttIsConnected() ? F(D_SERVICE_CONNECTED) : F(D_SERVICE_DISCONNECTED);
+ info[F(D_INFO_RECEIVED)] = mqttReceiveCount;
+ info[F(D_INFO_PUBLISHED)] = mqttPublishCount;
+ info[F(D_INFO_FAILED)] = mqttFailedCount;
+}
+
+bool mqttGetConfig(const JsonObject& settings)
+{
+ bool changed = false;
+
+ if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as().c_str()) != 0) changed = true;
+ settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname();
+
+ if(mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName;
+
+ if(mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_HOST)] = mqttServer;
+
+ if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_PORT)] = mqttPort;
+
+ if(mqttUsername != settings[FPSTR(FP_CONFIG_USER)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_USER)] = mqttUsername;
+
+ if(mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as()) changed = true;
+ settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword;
+
+ if(changed) configOutput(settings, TAG_MQTT);
+ return changed;
+}
+
+/** Set MQTT Configuration.
+ *
+ * Read the settings from json and sets the application variables.
+ *
+ * @note: data pixel should be formatted to uint32_t RGBA. Imagemagick requirements.
+ *
+ * @param[in] settings JsonObject with the config settings.
+ **/
+bool mqttSetConfig(const JsonObject& settings)
+{
+ // configOutput(settings, TAG_MQTT);
+ bool changed = false;
+
+ if(!settings[FPSTR(FP_CONFIG_PORT)].isNull()) {
+ // changed |= configSet(mqttPort, settings[FPSTR(FP_CONFIG_PORT)], F("mqttPort"));
+ changed |= mqttPort != settings[FPSTR(FP_CONFIG_PORT)];
+ mqttPort = settings[FPSTR(FP_CONFIG_PORT)];
+ }
+
+ if(!settings[FPSTR(FP_CONFIG_NAME)].isNull()) {
+ LOG_VERBOSE(TAG_MQTT, "%s => %s", FP_CONFIG_NAME, settings[FPSTR(FP_CONFIG_NAME)].as());
+ changed |= strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)]) != 0;
+ // strncpy(mqttNodeName, settings[FPSTR(FP_CONFIG_NAME)], sizeof(mqttNodeName));
+ haspDevice.set_hostname(settings[FPSTR(FP_CONFIG_NAME)].as());
+ }
+ // Prefill node name
+ // if(strlen(haspDevice.get_hostname()) == 0) {
+ // char mqttNodeName[64];
+ // std::string mac = halGetMacAddress(3, "");
+ // mac.toLowerCase();
+ // snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR(D_MQTT_DEFAULT_NAME), mac.c_str());
+ // haspDevice.set_hostname(mqttNodeName);
+ // changed = true;
+ // }
+
+ if(!settings[FPSTR(FP_CONFIG_GROUP)].isNull()) {
+ changed |= mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)];
+ mqttGroupName = settings[FPSTR(FP_CONFIG_GROUP)].as();
+ }
+
+ if(mqttGroupName.length() == 0) {
+ mqttGroupName = "plates";
+ changed = true;
+ }
+
+ if(!settings[FPSTR(FP_CONFIG_HOST)].isNull()) {
+ LOG_VERBOSE(TAG_MQTT, "%s => %s", FP_CONFIG_HOST, settings[FPSTR(FP_CONFIG_HOST)].as());
+ changed |= mqttServer != settings[FPSTR(FP_CONFIG_HOST)];
+ mqttServer = settings[FPSTR(FP_CONFIG_HOST)].as();
+ }
+
+ if(!settings[FPSTR(FP_CONFIG_USER)].isNull()) {
+ changed |= mqttUsername != settings[FPSTR(FP_CONFIG_USER)];
+ mqttUsername = settings[FPSTR(FP_CONFIG_USER)].as();
+ }
+
+ if(!settings[FPSTR(FP_CONFIG_PASS)].isNull() &&
+ settings[FPSTR(FP_CONFIG_PASS)].as() != D_PASSWORD_MASK) {
+ changed |= mqttPassword != settings[FPSTR(FP_CONFIG_PASS)];
+ mqttPassword = settings[FPSTR(FP_CONFIG_PASS)].as();
+ }
+
+ mqttNodeTopic = MQTT_PREFIX;
+ mqttNodeTopic += haspDevice.get_hostname();
+ mqttGroupTopic = MQTT_PREFIX;
+ mqttGroupTopic += mqttGroupName;
+
+ return changed;
+}
#endif // HASP_USE_PAHO
#endif // USE_MQTT
diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp
index 323b82fd..653a884f 100644
--- a/src/mqtt/hasp_mqtt_paho_single.cpp
+++ b/src/mqtt/hasp_mqtt_paho_single.cpp
@@ -5,7 +5,7 @@
#include "hasplib.h"
-#if HASP_USE_MQTT > 0
+#if HASP_USE_MQTT > 0 && !HASP_USE_MQTT_ASYNC
#ifdef HASP_USE_PAHO
#if !HASP_USE_CONFIG
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index 55e0288c..d9c2f28e 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -87,15 +87,14 @@ build_src_filter =
+<*>
-<*.h>
+<../.pio/libdeps/darwin_sdl_64bits/paho/src/*.c>
- +<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.c>
- +<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.h>
- -<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsync.c>
- -<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsyncUtils.c>
-<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTVersion.c>
-<../.pio/libdeps/darwin_sdl_64bits/paho/src/SSLSocket.c>
- +
- -
- -
+ -
+ +
+ +
-
-
-
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux_sdl/linux_fbdev_64bits.ini
index a709efb7..a5e10592 100644
--- a/user_setups/linux_sdl/linux_fbdev_64bits.ini
+++ b/user_setups/linux_sdl/linux_fbdev_64bits.ini
@@ -73,14 +73,14 @@ build_src_filter =
+<*>
-<*.h>
+<../.pio/libdeps/linux_fbdev_64bits/paho/src/*.c>
- +<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTClient.c>
- -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsync.c>
- -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsyncUtils.c>
-<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTVersion.c>
-<../.pio/libdeps/linux_fbdev_64bits/paho/src/SSLSocket.c>
- +
- -
- -
+ -
+ +
+ +
-
-
-
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index fc3287cc..9af47c82 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -78,14 +78,14 @@ build_src_filter =
+<*>
-<*.h>
+<../.pio/libdeps/linux_sdl_64bits/paho/src/*.c>
- +<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTClient.c>
- -<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsync.c>
- -<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsyncUtils.c>
-<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTVersion.c>
-<../.pio/libdeps/linux_sdl_64bits/paho/src/SSLSocket.c>
- +
- -
- -
+ -
+ +
+ +
-
-
-
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index 23062b6f..ac0ddeab 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -102,14 +102,14 @@ build_src_filter =
+<*>
-<*.h>
+<../.pio/libdeps/windows_gdi_64bits/paho/src/*.c>
- +<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTClient.c>
- -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsync.c>
- -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsyncUtils.c>
-<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTVersion.c>
-<../.pio/libdeps/windows_gdi_64bits/paho/src/SSLSocket.c>
- +
- -
- -
+ -
+ +
+ +
-
-
-
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index bd4338b1..9e20993d 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -108,14 +108,14 @@ build_src_filter =
+<*>
-<*.h>
+<../.pio/libdeps/windows_sdl_64bits/paho/src/*.c>
- +<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTClient.c>
- -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsync.c>
- -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsyncUtils.c>
-<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTVersion.c>
-<../.pio/libdeps/windows_sdl_64bits/paho/src/SSLSocket.c>
- +
- -
- -
+ -
+ +
+ +
-
-
-
From d77428db54b129b6cafef65e1e6691909d03c640 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Sat, 10 Feb 2024 23:58:37 +0100
Subject: [PATCH 108/135] Allow publishing MQTT message even with action tag
---
src/hasp/hasp_event.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index 9a5cc2bf..4f06e517 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -52,13 +52,14 @@ static bool script_event_handler(const char* eventname, const char* action, cons
StaticJsonDocument<64> filter;
filter[eventname] = true;
+ filter["pub"] = true;
DeserializationError jsonError = deserializeJson(doc, action, DeserializationOption::Filter(filter));
if(!jsonError) {
JsonVariant json = doc[eventname].as();
if(json.isNull()) {
LOG_DEBUG(TAG_EVENT, F("Skipping event: name=%s, data=%s"), eventname, data);
- return true;
+ goto end;
} else {
LOG_DEBUG(TAG_EVENT, F("Handling event: name=%s, data=%s"), eventname, data);
}
@@ -82,6 +83,9 @@ static bool script_event_handler(const char* eventname, const char* action, cons
} else {
dispatch_json_error(TAG_EVENT, jsonError);
}
+
+end:
+ if(doc["pub"].is()) return !doc["pub"].as();
return true;
}
From 9b3c88492ce37dd6d9fd472530177ae2dbd82657 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Mon, 12 Feb 2024 16:32:38 +0100
Subject: [PATCH 109/135] Switch to tty7 on POSIX fbdev
---
src/dev/posix/hasp_posix.cpp | 2 +-
src/drv/tft/tft_driver_posix_fbdev.cpp | 14 ++++++++++++--
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index e5f1b173..ad020e4b 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -203,7 +203,7 @@ void PosixDevice::update_backlight()
f << brightness;
f.close();
} else {
- perror("Brightness write failed");
+ perror("Brightness write failed (are you root?)");
}
}
#endif
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index 2961b728..7abafa58 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#if USE_BSD_EVDEV
#include
@@ -83,6 +84,15 @@ static void* gui_entrypoint(void* arg)
void TftFbdevDrv::init(int32_t w, int h)
{
+ // try to switch the active tty to tty7
+ int tty_fd = open("/dev/tty0", O_WRONLY);
+ if(tty_fd == -1) {
+ perror("Couldn't open /dev/tty0 (try running as root)");
+ } else {
+ if(ioctl(tty_fd, VT_ACTIVATE, 7) == -1) perror("Couldn't change active tty");
+ }
+ close(tty_fd);
+
// check active tty
std::ifstream f;
f.open("/sys/class/tty/tty0/active");
@@ -92,9 +102,9 @@ void TftFbdevDrv::init(int32_t w, int h)
f.close();
// try to hide the cursor
- int tty_fd = open(tty.c_str(), O_WRONLY);
+ tty_fd = open(tty.c_str(), O_WRONLY);
if(tty_fd == -1) {
- perror("Couldn't open tty");
+ perror("Couldn't open active tty (try running as root)");
} else {
write(tty_fd, "\033[?25l", 6);
}
From b0969892fdae9e01688f51c9bc079971a7ba8e9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Mon, 12 Feb 2024 18:20:00 +0100
Subject: [PATCH 110/135] Workaround "clearpage all" crashing on PC build
---
src/hasp/hasp_dispatch.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index b5795d16..dbf42062 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -967,7 +967,14 @@ void dispatch_page(const char*, const char* payload, uint8_t source)
void dispatch_clear_page(const char*, const char* page, uint8_t source)
{
if(!strcasecmp(page, "all")) {
+#if !HASP_TARGET_PC
hasp_init();
+#else
+ // workaround for "clearpage all" deadlocking or crashing on PC build (when called from non-LVGL thread)
+ for(uint8_t pageid = 0; pageid <= HASP_NUM_PAGES; pageid++) {
+ haspPages.clear(pageid);
+ }
+#endif
return;
}
From 55f39f02d08122121d85576c6557a22dc0094d83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Mon, 12 Feb 2024 18:24:43 +0100
Subject: [PATCH 111/135] Revert changes unrelated to PC build
---
include/hasp_conf.h | 4 -
src/hasp/hasp_dispatch.cpp | 115 +------------------
src/hasp/hasp_dispatch.h | 3 +-
src/hasp/hasp_event.cpp | 93 ++++++---------
src/hasp_config.h | 1 -
src/hasp_gui.cpp | 35 ------
src/hasp_gui.h | 1 -
user_setups/darwin_sdl/darwin_sdl_64bits.ini | 3 +-
user_setups/linux_sdl/linux_fbdev_64bits.ini | 3 +-
user_setups/linux_sdl/linux_sdl_64bits.ini | 3 +-
user_setups/win32/windows_gdi_64bits.ini | 3 +-
user_setups/win32/windows_sdl_64bits.ini | 3 +-
12 files changed, 45 insertions(+), 222 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index e36b8925..d7b666cb 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -181,10 +181,6 @@
#define HASP_NUM_GPIO_CONFIG 8
#endif
-#ifndef HASP_USE_EVENT_DATA_SUBST
-#define HASP_USE_EVENT_DATA_SUBST 0
-#endif
-
// #ifndef HASP_USE_CUSTOM
// #define HASP_USE_CUSTOM 0
// #endif
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index dbf42062..e9aae6cd 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -37,8 +37,6 @@
#endif
#endif
-#include
-
dispatch_conf_t dispatch_setings = {.teleperiod = 300};
uint16_t dispatchSecondsToNextTeleperiod = 0;
@@ -50,8 +48,6 @@ haspCommand_t commands[28];
moodlight_t moodlight = {.brightness = 255};
uint8_t saved_jsonl_page = 0;
-static std::map scheduled_tasks;
-
/* Sends the payload out on the state/subtopic
*/
void dispatch_state_subtopic(const char* subtopic, const char* payload)
@@ -614,17 +610,11 @@ void dispatch_screenshot(const char*, const char* filename, uint8_t source)
}
bool dispatch_json_variant(JsonVariant& json, uint8_t& savedPage, uint8_t source)
-{
- JsonObject dummy;
- return dispatch_json_variant_with_data(json, savedPage, source, dummy);
-}
-
-bool dispatch_json_variant_with_data(JsonVariant& json, uint8_t& savedPage, uint8_t source, JsonObject& data)
{
if(json.is()) { // handle json as an array of commands
LOG_DEBUG(TAG_MSGR, "Json ARRAY");
for(JsonVariant command : json.as()) {
- dispatch_json_variant_with_data(command, savedPage, source, data);
+ dispatch_json_variant(command, savedPage, source);
}
} else if(json.is()) { // handle json as a jsonl
@@ -632,23 +622,13 @@ bool dispatch_json_variant_with_data(JsonVariant& json, uint8_t& savedPage, uint
hasp_new_object(json.as(), savedPage);
} else if(json.is()) { // handle json as a single command
- std::string command = json.as();
+ LOG_DEBUG(TAG_MSGR, "Json text = %s", json.as().c_str());
+ dispatch_simple_text_command(json.as().c_str(), source);
-#if HASP_USE_EVENT_DATA_SUBST
- if(command.find('%') != std::string::npos) {
- // '%' found in command, run variable substitution
- for(JsonPair kv : data) {
- std::string find = "%" + std::string(kv.key().c_str()) + "%";
- std::string replace = kv.value().as();
- size_t pos = command.find(find);
- if(pos == std::string::npos) continue;
- command.replace(pos, find.length(), replace);
- }
- }
-#endif
+ } else if(json.is()) { // handle json as a single command
+ LOG_DEBUG(TAG_MSGR, "Json text = %s", json.as());
+ dispatch_simple_text_command(json.as(), source);
- LOG_DEBUG(TAG_MSGR, "Json text = %s", command.c_str());
- dispatch_simple_text_command(command.c_str(), source);
} else if(json.isNull()) { // event handler not found
// nothing to do
@@ -1425,88 +1405,6 @@ void dispatch_sleep(const char*, const char*, uint8_t source)
hasp_set_wakeup_touch(false);
}
-static void dispatch_schedule_runner(lv_task_t* task)
-{
- dispatch_text_line((const char*)task->user_data, TAG_MSGR);
-}
-
-void dispatch_schedule(const char*, const char* payload, uint8_t source)
-{
- // duplicate the string for modification
- char* argline = strdup(payload);
- // split argline into argv by whitespace; limit to 4 parts
- char* argv[4];
- int argn = 0;
- argv[argn++] = argline;
- while(*argline) {
- if(*argline == ' ') {
- *argline = '\0';
- argv[argn++] = argline + 1;
- }
- argline++;
- if(argn == 4) break;
- }
-
- const char* action = argv[0];
- uint32_t id = atoi(argv[1]);
-
- if(strcasecmp(action, "set") == 0) {
- if(argn != 4) {
- LOG_ERROR(TAG_MSGR, F("Usage: schedule set "));
- goto end;
- }
- uint32_t period = atoi(argv[2]);
- const char* command = strdup(argv[3]);
-
- if(scheduled_tasks.find(id) != scheduled_tasks.end()) {
- // update an existing task
- lv_task_t* task = scheduled_tasks[id];
- free(task->user_data);
- task->period = period;
- task->user_data = (void*)command;
- } else {
- // create a new task
- lv_task_t* task = lv_task_create(dispatch_schedule_runner, period, LV_TASK_PRIO_MID, (void*)command);
- scheduled_tasks[id] = task;
- }
-
- LOG_INFO(TAG_MSGR, F("Scheduled command ID %u, every %u ms: %s"), id, period, command);
-
- goto end;
- }
-
- if(argn != 2) {
- LOG_ERROR(TAG_MSGR, F("Usage: schedule "));
- goto end;
- }
- if(scheduled_tasks.find(id) == scheduled_tasks.end()) {
- LOG_ERROR(TAG_MSGR, F("Task by ID %u does not exist"), id);
- goto end;
- }
-
- {
- lv_task_t* task = scheduled_tasks[id];
- if(strcasecmp(action, "del") == 0) {
- free(task->user_data);
- lv_task_del(task);
- scheduled_tasks.erase(id);
- goto end;
- }
- if(strcasecmp(action, "start") == 0) {
- lv_task_set_prio(task, LV_TASK_PRIO_MID);
- goto end;
- }
- if(strcasecmp(action, "stop") == 0) {
- lv_task_set_prio(task, LV_TASK_PRIO_OFF);
- goto end;
- }
- }
-
-end:
- // release the duplicated argline
- free(argv[0]);
-}
-
void dispatch_idle_state(uint8_t state)
{
char topic[8];
@@ -1640,7 +1538,6 @@ void dispatchSetup()
dispatch_add_command(PSTR("moodlight"), dispatch_moodlight);
dispatch_add_command(PSTR("idle"), dispatch_idle);
dispatch_add_command(PSTR("sleep"), dispatch_sleep);
- dispatch_add_command(PSTR("schedule"), dispatch_schedule);
dispatch_add_command(PSTR("statusupdate"), dispatch_statusupdate);
dispatch_add_command(PSTR("clearpage"), dispatch_clear_page);
dispatch_add_command(PSTR("clearfont"), dispatch_clear_font);
diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h
index 53a5804a..245da30c 100644
--- a/src/hasp/hasp_dispatch.h
+++ b/src/hasp/hasp_dispatch.h
@@ -55,7 +55,6 @@ void dispatch_parse_jsonl(Stream& stream, uint8_t& saved_page_id);
void dispatch_parse_jsonl(std::istream& stream, uint8_t& saved_page_id);
#endif
bool dispatch_json_variant(JsonVariant& json, uint8_t& savedPage, uint8_t source);
-bool dispatch_json_variant_with_data(JsonVariant& json, uint8_t& savedPage, uint8_t source, JsonObject& data);
void dispatch_clear_page(const char* page);
void dispatch_json_error(uint8_t tag, DeserializationError& jsonError);
@@ -102,4 +101,4 @@ struct haspCommand_t
void (*func)(const char*, const char*, uint8_t);
};
-#endif
+#endif
\ No newline at end of file
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index 4f06e517..fd5eeaee 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -42,51 +42,23 @@ void event_reset_last_value_sent()
last_value_sent = INT16_MIN;
}
-static bool script_event_handler(const char* eventname, const char* action, const char* data)
+void script_event_handler(const char* eventname, const char* json)
{
- if(action == NULL) {
- LOG_DEBUG(TAG_EVENT, F("Skipping event: name=%s, data=%s"), eventname, data);
- return false;
- }
StaticJsonDocument<256> doc;
StaticJsonDocument<64> filter;
filter[eventname] = true;
- filter["pub"] = true;
- DeserializationError jsonError = deserializeJson(doc, action, DeserializationOption::Filter(filter));
+ DeserializationError jsonError = deserializeJson(doc, json, DeserializationOption::Filter(filter));
if(!jsonError) {
- JsonVariant json = doc[eventname].as();
- if(json.isNull()) {
- LOG_DEBUG(TAG_EVENT, F("Skipping event: name=%s, data=%s"), eventname, data);
- goto end;
- } else {
- LOG_DEBUG(TAG_EVENT, F("Handling event: name=%s, data=%s"), eventname, data);
- }
-
- JsonObject dataJson;
-#if HASP_USE_EVENT_DATA_SUBST
- if(data != NULL) {
- StaticJsonDocument<256> jsonDoc;
- if(deserializeJson(jsonDoc, data) != DeserializationError::Ok) {
- LOG_ERROR(TAG_EVENT, F("Deserialization failed"));
- } else {
- dataJson = jsonDoc.as();
- }
- }
-#endif
-
+ JsonVariant json = doc[eventname].as();
uint8_t savedPage = haspPages.get();
- if(!dispatch_json_variant_with_data(json, savedPage, TAG_EVENT, dataJson)) {
+ if(!dispatch_json_variant(json, savedPage, TAG_EVENT)) {
LOG_WARNING(TAG_EVENT, F(D_DISPATCH_COMMAND_NOT_FOUND), eventname);
}
} else {
dispatch_json_error(TAG_EVENT, jsonError);
}
-
-end:
- if(doc["pub"].is()) return !doc["pub"].as();
- return true;
}
/**
@@ -282,16 +254,11 @@ static bool translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid)
// ##################### Value Senders ########################################################
-static void event_send_object_data(lv_obj_t* obj, const char* eventname, const char* data)
+static void event_send_object_data(lv_obj_t* obj, const char* data)
{
uint8_t pageid;
uint8_t objid;
- // handle object "action", abort sending if handled
- if(script_event_handler(eventname, my_obj_get_action(obj), data)) {
- return;
- }
-
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
if(!data) return;
object_dispatch_state(pageid, objid, data);
@@ -304,23 +271,23 @@ static void event_send_object_data(lv_obj_t* obj, const char* eventname, const c
static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val)
{
char data[512];
- char eventname[8];
{
+ char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"tag\":%s}"), eventname, val, tag);
else
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
}
- event_send_object_data(obj, eventname, data);
+ event_send_object_data(obj, data);
}
// Send out events with a val and text attribute
static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text)
{
char data[512];
- char eventname[8];
{
+ char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
@@ -329,7 +296,7 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16
else
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), eventname, val, text);
}
- event_send_object_data(obj, eventname, data);
+ event_send_object_data(obj, data);
}
// ##################### Event Handlers ########################################################
@@ -435,16 +402,16 @@ void swipe_event_handler(lv_obj_t* obj, lv_event_t event)
lv_gesture_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
switch(dir) {
case LV_GESTURE_DIR_LEFT:
- script_event_handler("left", swipe, NULL);
+ script_event_handler("left", swipe);
break;
case LV_GESTURE_DIR_RIGHT:
- script_event_handler("right", swipe, NULL);
+ script_event_handler("right", swipe);
break;
case LV_GESTURE_DIR_BOTTOM:
- script_event_handler("down", swipe, NULL);
+ script_event_handler("down", swipe);
break;
default:
- script_event_handler("up", swipe, NULL);
+ script_event_handler("up", swipe);
}
}
}
@@ -465,8 +432,8 @@ void textarea_event_handler(lv_obj_t* obj, lv_event_t event)
if(!translate_event(obj, event, hasp_event_id)) return;
char data[1024];
- char eventname[8];
{
+ char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
@@ -477,7 +444,7 @@ void textarea_event_handler(lv_obj_t* obj, lv_event_t event)
lv_textarea_get_text(obj));
}
- event_send_object_data(obj, eventname, data);
+ event_send_object_data(obj, data);
} else if(event == LV_EVENT_FOCUSED) {
lv_textarea_set_cursor_hidden(obj, false);
} else if(event == LV_EVENT_DEFOCUSED) {
@@ -551,17 +518,23 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event)
if(last_value_sent == HASP_EVENT_LOST) return;
- char data[512];
- char eventname[8];
- {
+ if(const char* action = my_obj_get_action(obj)) {
+ char eventname[8];
Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
+ script_event_handler(eventname, action);
+ } else {
+ char data[512];
+ {
+ char eventname[8];
+ Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
- if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
- else
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
+ if(const char* tag = my_obj_get_tag(obj))
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
+ else
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
+ }
+ event_send_object_data(obj, data);
}
- event_send_object_data(obj, eventname, data);
// Update group objects and gpios on release
if(last_value_sent != LV_EVENT_LONG_PRESSED && last_value_sent != LV_EVENT_LONG_PRESSED_REPEAT) {
@@ -868,8 +841,8 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
if(hasp_event_id == HASP_EVENT_CHANGED && last_color_sent.full == color.full) return; // same value as before
char data[512];
- char eventname[8];
{
+ char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
lv_color32_t c32;
@@ -891,7 +864,7 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
hsv.s, hsv.v);
}
- event_send_object_data(obj, eventname, data);
+ event_send_object_data(obj, data);
// event_update_group(obj->user_data.groupid, obj, val, min, max);
}
@@ -918,8 +891,8 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
return; // same object and value as before
char data[512];
- char eventname[8];
{
+ char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
last_value_sent = val;
@@ -934,7 +907,7 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
PSTR("{\"event\":\"%s\",\"val\":\"%d\",\"text\":\"%04d-%02d-%02dT00:00:00Z\"}"), eventname,
date->day, date->year, date->month, date->day);
}
- event_send_object_data(obj, eventname, data);
+ event_send_object_data(obj, data);
// event_update_group(obj->user_data.groupid, obj, val, min, max);
}
diff --git a/src/hasp_config.h b/src/hasp_config.h
index ca5429ae..04160d30 100644
--- a/src/hasp_config.h
+++ b/src/hasp_config.h
@@ -90,7 +90,6 @@ const char FP_GUI_BACKLIGHTINVERT[] PROGMEM = "bcklinv";
const char FP_GUI_POINTER[] PROGMEM = "cursor";
const char FP_GUI_LONG_TIME[] PROGMEM = "long";
const char FP_GUI_REPEAT_TIME[] PROGMEM = "repeat";
-const char FP_GUI_FPS[] PROGMEM = "fps";
const char FP_DEBUG_TELEPERIOD[] PROGMEM = "tele";
const char FP_DEBUG_ANSI[] PROGMEM = "ansi";
const char FP_GPIO_CONFIG[] PROGMEM = "config";
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 5c39f590..9fd55c9b 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -57,8 +57,6 @@ uint32_t screenshotEtag = 0;
void (*drv_display_flush_cb)(struct _disp_drv_t* disp_drv, const lv_area_t* area, lv_color_t* color_p);
static lv_disp_buf_t disp_buf;
-static bool gui_initialized = false;
-static uint32_t anim_fps_deferred = 0;
static inline void gui_init_lvgl()
{
@@ -102,27 +100,6 @@ void gui_hide_pointer(bool hidden)
if(cursor) lv_obj_set_hidden(cursor, hidden || !gui_settings.show_pointer);
}
-bool gui_set_fps(uint32_t fps)
-{
- if(!gui_initialized) {
- LOG_ERROR(TAG_GUI, F("GUI not initialized, deferring FPS setting"));
- anim_fps_deferred = fps;
- return false;
- }
-
- bool changed = false;
- uint32_t period = 1000 / fps;
- // find animation task by its period
- lv_task_t* task = NULL;
- while(task = lv_task_get_next(task)) {
- if(!(task->period == LV_DISP_DEF_REFR_PERIOD)) continue;
- changed |= (task->period != period);
- LOG_INFO(TAG_GUI, F("Changing animation period: %u -> %u (%u FPS)"), task->period, period, fps);
- task->period = period;
- }
- return changed;
-}
-
IRAM_ATTR void gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
{
haspTft.flush_pixels(disp, area, color_p);
@@ -396,13 +373,6 @@ void guiSetup()
}
#endif // ESP32 && HASP_USE_ESP_MQTT
- // apply deferred FPS setting
- gui_initialized = true;
- if(anim_fps_deferred != 0) {
- gui_set_fps(anim_fps_deferred);
- anim_fps_deferred = 0;
- }
-
LOG_INFO(TAG_LVGL, F(D_SERVICE_STARTED));
}
@@ -642,11 +612,6 @@ bool guiSetConfig(const JsonObject& settings)
changed |= status;
}
- if(!settings[FPSTR(FP_GUI_FPS)].isNull()) {
- uint32_t fps = settings[FPSTR(FP_GUI_FPS)].as();
- changed |= gui_set_fps(fps);
- }
-
return changed;
}
#endif // HASP_USE_CONFIG
diff --git a/src/hasp_gui.h b/src/hasp_gui.h
index adb5ddb6..8b5b12af 100644
--- a/src/hasp_gui.h
+++ b/src/hasp_gui.h
@@ -48,7 +48,6 @@ void guiEverySecond(void);
void guiStart(void);
void guiStop(void);
void gui_hide_pointer(bool hidden);
-bool gui_set_fps(uint32_t fps);
/* ===== Special Event Processors ===== */
void guiCalibrate(void);
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
index d9c2f28e..52f8aaa6 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini
@@ -34,8 +34,7 @@ build_flags =
-D HASP_USE_GIFDECODE=0
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
- -D HASP_USE_EVENT_DATA_SUBST=1
- -D MQTT_MAX_PACKET_SIZE=32768
+ -D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux_sdl/linux_fbdev_64bits.ini
index a5e10592..999a73a7 100644
--- a/user_setups/linux_sdl/linux_fbdev_64bits.ini
+++ b/user_setups/linux_sdl/linux_fbdev_64bits.ini
@@ -31,8 +31,7 @@ build_flags =
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
-D HASP_USE_LVGL_TASK=1
- -D HASP_USE_EVENT_DATA_SUBST=1
- -D MQTT_MAX_PACKET_SIZE=32768
+ -D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini
index 9af47c82..222d8660 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux_sdl/linux_sdl_64bits.ini
@@ -34,8 +34,7 @@ build_flags =
-D HASP_USE_GIFDECODE=0
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
- -D HASP_USE_EVENT_DATA_SUBST=1
- -D MQTT_MAX_PACKET_SIZE=32768
+ -D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini
index ac0ddeab..e8f49fad 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi_64bits.ini
@@ -30,8 +30,7 @@ build_flags =
-D HASP_USE_MQTT=1
-D HASP_USE_SYSLOG=0
-D HASP_USE_LVGL_TASK=1
- -D HASP_USE_EVENT_DATA_SUBST=1
- -D MQTT_MAX_PACKET_SIZE=32768
+ -D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
index 9e20993d..850e8ae6 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -34,8 +34,7 @@ build_flags =
-D HASP_USE_JPGDECODE=0
-D HASP_USE_MQTT=1
-D HASP_USE_SYSLOG=0
- -D HASP_USE_EVENT_DATA_SUBST=1
- -D MQTT_MAX_PACKET_SIZE=32768
+ -D MQTT_MAX_PACKET_SIZE=2048
-D HASP_ATTRIBUTE_FAST_MEM=
-D IRAM_ATTR= ; No IRAM_ATTR available
-D PROGMEM= ; No PROGMEM available
From 37e66cdf5b0a6d3cbe117149089ba418b43a5485 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Mon, 12 Feb 2024 18:33:04 +0100
Subject: [PATCH 112/135] Rename PC build envs
---
.github/workflows/build.yaml | 6 +++---
.github/workflows/build_linux.yaml | 4 ++--
.github/workflows/release.yml | 2 +-
platformio_override-template.ini | 4 ++--
.../darwin_sdl.ini} | 20 +++++++++----------
.../linux_fbdev.ini} | 20 +++++++++----------
.../linux_sdl.ini} | 20 +++++++++----------
...windows_gdi_64bits.ini => windows_gdi.ini} | 20 +++++++++----------
...windows_sdl_64bits.ini => windows_sdl.ini} | 20 +++++++++----------
9 files changed, 58 insertions(+), 58 deletions(-)
rename user_setups/{darwin_sdl/darwin_sdl_64bits.ini => darwin/darwin_sdl.ini} (81%)
rename user_setups/{linux_sdl/linux_fbdev_64bits.ini => linux/linux_fbdev.ini} (77%)
rename user_setups/{linux_sdl/linux_sdl_64bits.ini => linux/linux_sdl.ini} (80%)
rename user_setups/win32/{windows_gdi_64bits.ini => windows_gdi.ini} (83%)
rename user_setups/win32/{windows_sdl_64bits.ini => windows_sdl.ini} (84%)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index ee4f01af..4847e5a4 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -158,7 +158,7 @@ jobs:
- name: Enable Linux platform from platformio_override.ini
run: |
sed 's/; user_setups\/linux/user_setups\/linux/g' platformio_override-template.ini > platformio_override.ini
- mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
+ mkdir -p .pio/libdeps/linux_sdl/paho/src
- name: Install SDL2 library
run: |
sudo apt-get update
@@ -172,10 +172,10 @@ jobs:
- name: Enable Linux platform from platformio_override.ini
run: |
sed -i 's/; user_setups\/linux/user_setups\/linux/g' platformio_override.ini
- mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
+ mkdir -p .pio/libdeps/linux_sdl/paho/src
- name: Install SDL2 library
run: |
sudo apt-get update
sudo apt-get install libsdl2-dev
- name: Run PlatformIO
- run: pio run -e linux_sdl_64bits
+ run: pio run -e linux_sdl
diff --git a/.github/workflows/build_linux.yaml b/.github/workflows/build_linux.yaml
index a4baea49..e7e77c94 100644
--- a/.github/workflows/build_linux.yaml
+++ b/.github/workflows/build_linux.yaml
@@ -11,7 +11,7 @@ jobs:
fail-fast: false
matrix:
environments:
- - linux_sdl_64bits
+ - linux_sdl
steps:
- uses: actions/checkout@v3
@@ -43,7 +43,7 @@ jobs:
- name: Enable Linux platform from platformio_override.ini
run: |
sed -i 's/; user_setups\/linux/user_setups\/linux/g' platformio_override.ini
- mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
+ mkdir -p .pio/libdeps/linux_sdl/paho/src
- name: Install SDL2 library
run: |
sudo apt-get update
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 62ef57b4..0d4bb86d 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -39,7 +39,7 @@ jobs:
- name: Enable Linux platform from platformio_override.ini
run: |
sed -i 's/; user_setups\/linux/user_setups\/linux/g' platformio_override.ini
- mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
+ mkdir -p .pio/libdeps/linux_sdl/paho/src
- name: Install SDL2 library
run: |
sudo apt-get update
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index 941fe815..f746bb26 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -6,11 +6,11 @@
[platformio]
extra_configs =
; Uncomment or edit the lines to show more User Setups in the PIO sidebar
- ; user_setups/darwin_sdl/*.ini
+ ; user_setups/darwin/*.ini
; user_setups/esp32/*.ini
; user_setups/esp32s2/*.ini
; user_setups/esp32s3/*.ini
- ; user_setups/linux_sdl/*.ini
+ ; user_setups/linux/*.ini
; user_setups/stm32f4xx/*.ini
; user_setups/win32/*.ini
diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin/darwin_sdl.ini
similarity index 81%
rename from user_setups/darwin_sdl/darwin_sdl_64bits.ini
rename to user_setups/darwin/darwin_sdl.ini
index 52f8aaa6..2b3a3642 100644
--- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini
+++ b/user_setups/darwin/darwin_sdl.ini
@@ -1,4 +1,4 @@
-[env:darwin_sdl_64bits]
+[env:darwin_sdl]
lib_archive = false
platform = native@^1.1.4
extra_scripts =
@@ -49,8 +49,8 @@ build_flags =
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_VERBOSE_MAKEFILE=TRUE
;-D NO_PERSISTENCE
- -I.pio/libdeps/darwin_sdl_64bits/paho/src
- -I.pio/libdeps/darwin_sdl_64bits/ArduinoJson/src
+ -I.pio/libdeps/darwin_sdl/paho/src
+ -I.pio/libdeps/darwin_sdl/ArduinoJson/src
-I lib/ArduinoJson/src
-I lib/lv_fs_if
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
@@ -85,12 +85,12 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../.pio/libdeps/darwin_sdl_64bits/paho/src/*.c>
- -<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.c>
- +<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsync.c>
- +<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsyncUtils.c>
- -<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTVersion.c>
- -<../.pio/libdeps/darwin_sdl_64bits/paho/src/SSLSocket.c>
+ +<../.pio/libdeps/darwin_sdl/paho/src/*.c>
+ -<../.pio/libdeps/darwin_sdl/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/darwin_sdl/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/darwin_sdl/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/darwin_sdl/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/darwin_sdl/paho/src/SSLSocket.c>
-
+
+
@@ -112,4 +112,4 @@ build_src_filter =
+
-
+
- +<../.pio/libdeps/darwin_sdl_64bits/ArduinoJson/src/ArduinoJson.h>
+ +<../.pio/libdeps/darwin_sdl/ArduinoJson/src/ArduinoJson.h>
diff --git a/user_setups/linux_sdl/linux_fbdev_64bits.ini b/user_setups/linux/linux_fbdev.ini
similarity index 77%
rename from user_setups/linux_sdl/linux_fbdev_64bits.ini
rename to user_setups/linux/linux_fbdev.ini
index 999a73a7..c0d70a27 100644
--- a/user_setups/linux_sdl/linux_fbdev_64bits.ini
+++ b/user_setups/linux/linux_fbdev.ini
@@ -1,4 +1,4 @@
-[env:linux_fbdev_64bits]
+[env:linux_fbdev]
platform = native@^1.1.4
extra_scripts =
tools/linux_build_extra.py
@@ -46,8 +46,8 @@ build_flags =
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_VERBOSE_MAKEFILE=TRUE
;-D NO_PERSISTENCE
- -I.pio/libdeps/linux_fbdev_64bits/paho/src
- -I.pio/libdeps/linux_fbdev_64bits/ArduinoJson/src
+ -I.pio/libdeps/linux_fbdev/paho/src
+ -I.pio/libdeps/linux_fbdev/ArduinoJson/src
; ----- Statically linked libraries --------------------
-lm
@@ -71,12 +71,12 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../.pio/libdeps/linux_fbdev_64bits/paho/src/*.c>
- -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTClient.c>
- +<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsync.c>
- +<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTAsyncUtils.c>
- -<../.pio/libdeps/linux_fbdev_64bits/paho/src/MQTTVersion.c>
- -<../.pio/libdeps/linux_fbdev_64bits/paho/src/SSLSocket.c>
+ +<../.pio/libdeps/linux_fbdev/paho/src/*.c>
+ -<../.pio/libdeps/linux_fbdev/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/linux_fbdev/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/linux_fbdev/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/linux_fbdev/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/linux_fbdev/paho/src/SSLSocket.c>
-
+
+
@@ -98,4 +98,4 @@ build_src_filter =
+
-
+
- +<../.pio/libdeps/linux_fbdev_64bits/ArduinoJson/src/ArduinoJson.h>
+ +<../.pio/libdeps/linux_fbdev/ArduinoJson/src/ArduinoJson.h>
diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux/linux_sdl.ini
similarity index 80%
rename from user_setups/linux_sdl/linux_sdl_64bits.ini
rename to user_setups/linux/linux_sdl.ini
index 222d8660..e1239f7d 100644
--- a/user_setups/linux_sdl/linux_sdl_64bits.ini
+++ b/user_setups/linux/linux_sdl.ini
@@ -1,4 +1,4 @@
-[env:linux_sdl_64bits]
+[env:linux_sdl]
platform = native@^1.1.4
extra_scripts =
tools/sdl2_build_extra.py
@@ -49,8 +49,8 @@ build_flags =
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_VERBOSE_MAKEFILE=TRUE
;-D NO_PERSISTENCE
- -I.pio/libdeps/linux_sdl_64bits/paho/src
- -I.pio/libdeps/linux_sdl_64bits/ArduinoJson/src
+ -I.pio/libdeps/linux_sdl/paho/src
+ -I.pio/libdeps/linux_sdl/ArduinoJson/src
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
; ----- Statically linked libraries --------------------
@@ -76,12 +76,12 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../.pio/libdeps/linux_sdl_64bits/paho/src/*.c>
- -<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTClient.c>
- +<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsync.c>
- +<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsyncUtils.c>
- -<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTVersion.c>
- -<../.pio/libdeps/linux_sdl_64bits/paho/src/SSLSocket.c>
+ +<../.pio/libdeps/linux_sdl/paho/src/*.c>
+ -<../.pio/libdeps/linux_sdl/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/linux_sdl/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/linux_sdl/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/linux_sdl/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/linux_sdl/paho/src/SSLSocket.c>
-
+
+
@@ -103,4 +103,4 @@ build_src_filter =
+
-
+
- +<../.pio/libdeps/linux_sdl_64bits/ArduinoJson/src/ArduinoJson.h>
+ +<../.pio/libdeps/linux_sdl/ArduinoJson/src/ArduinoJson.h>
diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi.ini
similarity index 83%
rename from user_setups/win32/windows_gdi_64bits.ini
rename to user_setups/win32/windows_gdi.ini
index e8f49fad..00b6ee1f 100644
--- a/user_setups/win32/windows_gdi_64bits.ini
+++ b/user_setups/win32/windows_gdi.ini
@@ -1,4 +1,4 @@
-[env:windows_gdi_64bits]
+[env:windows_gdi]
platform = native@^1.1.4
extra_scripts =
tools/windows_build_extra.py
@@ -55,8 +55,8 @@ build_flags =
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_VERBOSE_MAKEFILE=TRUE
;-D NO_PERSISTENCE
- -I.pio/libdeps/windows_gdi_64bits/paho/src
- -I.pio/libdeps/windows_gdi_64bits/ArduinoJson/src
+ -I.pio/libdeps/windows_gdi/paho/src
+ -I.pio/libdeps/windows_gdi/ArduinoJson/src
-I lib/lv_fs_if
-I lib/lv_datetime
-mconsole
@@ -100,12 +100,12 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../.pio/libdeps/windows_gdi_64bits/paho/src/*.c>
- -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTClient.c>
- +<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsync.c>
- +<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsyncUtils.c>
- -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTVersion.c>
- -<../.pio/libdeps/windows_gdi_64bits/paho/src/SSLSocket.c>
+ +<../.pio/libdeps/windows_gdi/paho/src/*.c>
+ -<../.pio/libdeps/windows_gdi/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/windows_gdi/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/windows_gdi/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/windows_gdi/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/windows_gdi/paho/src/SSLSocket.c>
-
+
+
@@ -127,5 +127,5 @@ build_src_filter =
+
-
+
- +<../.pio/libdeps/windows_gdi_64bits/ArduinoJson/src/ArduinoJson.h>
+ +<../.pio/libdeps/windows_gdi/ArduinoJson/src/ArduinoJson.h>
+
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl.ini
similarity index 84%
rename from user_setups/win32/windows_sdl_64bits.ini
rename to user_setups/win32/windows_sdl.ini
index 850e8ae6..30364c1c 100644
--- a/user_setups/win32/windows_sdl_64bits.ini
+++ b/user_setups/win32/windows_sdl.ini
@@ -1,4 +1,4 @@
-[env:windows_sdl_64bits]
+[env:windows_sdl]
platform = native@^1.1.4
extra_scripts =
tools/sdl2_build_extra.py
@@ -59,8 +59,8 @@ build_flags =
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_VERBOSE_MAKEFILE=TRUE
;-D NO_PERSISTENCE
- -I.pio/libdeps/windows_sdl_64bits/paho/src
- -I.pio/libdeps/windows_sdl_64bits/ArduinoJson/src
+ -I.pio/libdeps/windows_sdl/paho/src
+ -I.pio/libdeps/windows_sdl/ArduinoJson/src
-I lib/lv_fs_if
-I lib/lv_datetime
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
@@ -106,12 +106,12 @@ lib_ignore =
build_src_filter =
+<*>
-<*.h>
- +<../.pio/libdeps/windows_sdl_64bits/paho/src/*.c>
- -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTClient.c>
- +<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsync.c>
- +<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsyncUtils.c>
- -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTVersion.c>
- -<../.pio/libdeps/windows_sdl_64bits/paho/src/SSLSocket.c>
+ +<../.pio/libdeps/windows_sdl/paho/src/*.c>
+ -<../.pio/libdeps/windows_sdl/paho/src/MQTTClient.c>
+ +<../.pio/libdeps/windows_sdl/paho/src/MQTTAsync.c>
+ +<../.pio/libdeps/windows_sdl/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/windows_sdl/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/windows_sdl/paho/src/SSLSocket.c>
-
+
+
@@ -133,5 +133,5 @@ build_src_filter =
+
-
+
- +<../.pio/libdeps/windows_sdl_64bits/ArduinoJson/src/ArduinoJson.h>
+ +<../.pio/libdeps/windows_sdl/ArduinoJson/src/ArduinoJson.h>
+
From baa125d4b6cc6264be155f792a008faa8241be59 Mon Sep 17 00:00:00 2001
From: Ryan Press
Date: Mon, 12 Feb 2024 10:25:58 -0800
Subject: [PATCH 113/135] enable backlight fade
---
src/dev/esp32/esp32.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp
index dd7f8530..76eece8a 100644
--- a/src/dev/esp32/esp32.cpp
+++ b/src/dev/esp32/esp32.cpp
@@ -295,8 +295,7 @@ bool Esp32Device::get_backlight_invert()
void Esp32Device::set_backlight_level(uint8_t level)
{
_backlight_level = level;
- // update_backlight(true);
- update_backlight(false);
+ update_backlight(true);
}
uint8_t Esp32Device::get_backlight_level()
@@ -307,8 +306,7 @@ uint8_t Esp32Device::get_backlight_level()
void Esp32Device::set_backlight_power(bool power)
{
_backlight_power = power;
- // update_backlight(true);
- update_backlight(false);
+ update_backlight(true);
}
bool Esp32Device::get_backlight_power()
From d71473a4e7ba8892d12d49c89f63568fe12ecfb6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Mon, 12 Feb 2024 19:30:05 +0100
Subject: [PATCH 114/135] Reflect MQTT state with online/offline scripts
---
src/mqtt/hasp_mqtt_paho_async.cpp | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp
index 5485fe9e..71136d07 100644
--- a/src/mqtt/hasp_mqtt_paho_async.cpp
+++ b/src/mqtt/hasp_mqtt_paho_async.cpp
@@ -94,6 +94,9 @@ int mqttPublish(const char* topic, const char* payload, size_t len, bool retain
static void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
+#if HASP_TARGET_PC
+ dispatch_run_script(NULL, "L:/offline.cmd", TAG_HASP);
+#endif
mqttConnecting = false;
mqttConnected = false;
LOG_ERROR(TAG_MQTT, "Connection failed, return code %d (%s)", response->code, response->message);
@@ -101,6 +104,9 @@ static void onConnectFailure(void* context, MQTTAsync_failureData* response)
static void onDisconnect(void* context, MQTTAsync_successData* response)
{
+#if HASP_TARGET_PC
+ dispatch_run_script(NULL, "L:/offline.cmd", TAG_HASP);
+#endif
mqttConnecting = false;
mqttConnected = false;
}
@@ -124,6 +130,9 @@ static void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
static void connlost(void* context, char* cause)
{
+#if HASP_TARGET_PC
+ dispatch_run_script(NULL, "L:/offline.cmd", TAG_HASP);
+#endif
LOG_WARNING(TAG_MQTT, F(D_MQTT_DISCONNECTED ": %s"), cause);
mqttConnecting = false;
mqttConnected = false;
@@ -341,6 +350,10 @@ static void onConnect(void* context, MQTTAsync_successData* response)
#endif
mqttPublish(mqttLwtTopic.c_str(), "online", 6, true);
+
+#if HASP_TARGET_PC
+ dispatch_run_script(NULL, "L:/online.cmd", TAG_HASP);
+#endif
}
void mqttStart()
From 6a8bbce6ecfbe583b2f2bcdb6864aaa0f283dd8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?=
Date: Thu, 15 Feb 2024 17:37:08 +0100
Subject: [PATCH 115/135] Restore lv_fs_if_init() on Arduino build
---
src/hasp_config.cpp | 1 -
src/hasp_gui.cpp | 1 +
src/main.cpp | 5 +++++
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index 4bdb7c80..75ac0bb5 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -265,7 +265,6 @@ DeserializationError configParseFile(String& configFile, JsonDocument& settings)
}
return DeserializationError::InvalidInput;
#elif HASP_TARGET_PC
- lv_fs_if_init();
lv_fs_file_t f;
lv_fs_res_t res;
lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 9fd55c9b..13caf317 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -208,6 +208,7 @@ static inline void gui_init_filesystems()
{
#if LV_USE_FS_IF != 0
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_ENABLED));
+ lv_fs_if_init(); // auxiliary file system drivers
#else
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_DISABLED));
#endif
diff --git a/src/main.cpp b/src/main.cpp
index 68a51af3..b065909c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -48,6 +48,11 @@ void setup()
// Initialize lvgl environment
lv_init();
lv_log_register_print_cb(debugLvglLogEvent);
+#if HASP_USE_CONFIG
+ // initialize FS before running configSetup()
+ // normally, it's initialized in guiSetup(), but Arduino doesn't need FS in configSetup()
+ lv_fs_if_init();
+#endif
#endif
haspDevice.init();
From a3c2e9723bcd8953996da245471ea60f5f94b507 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 17 Feb 2024 14:21:46 +0100
Subject: [PATCH 116/135] Fix for Linux build #641
---
src/dev/esp32/esp32.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/dev/esp32/esp32.h b/src/dev/esp32/esp32.h
index 401a4435..825a0eea 100644
--- a/src/dev/esp32/esp32.h
+++ b/src/dev/esp32/esp32.h
@@ -6,9 +6,9 @@
#include "hasp_conf.h"
#include "../device.h"
-#include "driver/ledc.h"
#if defined(ESP32)
+#include "driver/ledc.h"
#ifndef BACKLIGHT_FREQUENCY
#define BACKLIGHT_FREQUENCY 20000
From 25a73b42556117c309d8b252d6765f192a826bc0 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 17 Feb 2024 14:29:35 +0100
Subject: [PATCH 117/135] Update build script
---
.github/workflows/build.yaml | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index e64de643..ee3d7f48 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -26,12 +26,8 @@ jobs:
env: "az-touch-mod-esp32_ili9341_4MB -e az-touch-mod-esp32_ili9341_8MB"
- env: d1-mini-esp32_ili9341
out: d1-mini-esp32
- - env: d1-r32-waveshare_ili9486
- out: d1-r32-espduino32
- - env: d1-r32-unoshield_ili9341_adc
- out: d1-r32-espduino32
- - env: d1-r32-unoshield_ili9486_adc
- out: d1-r32-espduino32
+ - out: d1-r32-espduino32
+ env: "d1-r32-waveshare_ili9486 -e d1-r32-unoshield_ili9341_adc -e d1-r32-unoshield_ili9486_adc"
- out: dustinwatts
env: "freetouchdeck_4MB -e freetouchdeck_8MB -e esp32-touchdown"
- out: elecrow
From d3b5658385dd9ae1b7fa65db0dc47ad3b8298564 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 17 Feb 2024 15:21:54 +0100
Subject: [PATCH 118/135] Disable fade #641
---
src/dev/esp32/esp32.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp
index 76eece8a..bf54d79a 100644
--- a/src/dev/esp32/esp32.cpp
+++ b/src/dev/esp32/esp32.cpp
@@ -295,7 +295,7 @@ bool Esp32Device::get_backlight_invert()
void Esp32Device::set_backlight_level(uint8_t level)
{
_backlight_level = level;
- update_backlight(true);
+ update_backlight(false);
}
uint8_t Esp32Device::get_backlight_level()
@@ -306,7 +306,7 @@ uint8_t Esp32Device::get_backlight_level()
void Esp32Device::set_backlight_power(bool power)
{
_backlight_power = power;
- update_backlight(true);
+ update_backlight(false);
}
bool Esp32Device::get_backlight_power()
From ac6796b19d86dd6e5676189bb1bc6af9b7f3bbec Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 22 Feb 2024 16:19:28 +0100
Subject: [PATCH 119/135] Update ArduinoJson to 6.21.5
---
user_setups/darwin/darwin_sdl.ini | 2 +-
user_setups/esp32s2/_esp32s2.ini | 1 +
user_setups/linux/linux_fbdev.ini | 2 +-
user_setups/linux/linux_sdl.ini | 2 +-
user_setups/win32/windows_gdi.ini | 2 +-
user_setups/win32/windows_sdl.ini | 2 +-
user_setups/win32/windows_sdl_64bits.ini | 137 +++++++++++++++++++++++
7 files changed, 143 insertions(+), 5 deletions(-)
create mode 100644 user_setups/win32/windows_sdl_64bits.ini
diff --git a/user_setups/darwin/darwin_sdl.ini b/user_setups/darwin/darwin_sdl.ini
index 2b3a3642..b1c4057a 100644
--- a/user_setups/darwin/darwin_sdl.ini
+++ b/user_setups/darwin/darwin_sdl.ini
@@ -70,7 +70,7 @@ lib_deps =
; lv_drivers@~7.9.1
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.5 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
git+https://github.com/lvgl/lv_lib_png.git#release/v7
diff --git a/user_setups/esp32s2/_esp32s2.ini b/user_setups/esp32s2/_esp32s2.ini
index 88bcf8a7..907a0f06 100644
--- a/user_setups/esp32s2/_esp32s2.ini
+++ b/user_setups/esp32s2/_esp32s2.ini
@@ -5,6 +5,7 @@ board_build.mcu = esp32s2
build_flags =
${env.build_flags}
+ -D HASP_TARGET_ARDUINO=1
-D HTTP_UPLOAD_BUFLEN=512 ; lower http upload buffer
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
-D HASP_CONSOLE_BUFFER=256 ; maximum length of a console/telnet command
diff --git a/user_setups/linux/linux_fbdev.ini b/user_setups/linux/linux_fbdev.ini
index c0d70a27..1927c7ab 100644
--- a/user_setups/linux/linux_fbdev.ini
+++ b/user_setups/linux/linux_fbdev.ini
@@ -58,7 +58,7 @@ lib_deps =
;lv_drivers@~7.9.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.5 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
lib_ignore =
diff --git a/user_setups/linux/linux_sdl.ini b/user_setups/linux/linux_sdl.ini
index e1239f7d..2445b8b0 100644
--- a/user_setups/linux/linux_sdl.ini
+++ b/user_setups/linux/linux_sdl.ini
@@ -63,7 +63,7 @@ lib_deps =
;lv_drivers@~7.9.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.5 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
lib_ignore =
diff --git a/user_setups/win32/windows_gdi.ini b/user_setups/win32/windows_gdi.ini
index 00b6ee1f..c887ffd8 100644
--- a/user_setups/win32/windows_gdi.ini
+++ b/user_setups/win32/windows_gdi.ini
@@ -87,7 +87,7 @@ lib_deps =
;lv_drivers@~7.9.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.5 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
lib_ignore =
diff --git a/user_setups/win32/windows_sdl.ini b/user_setups/win32/windows_sdl.ini
index 30364c1c..dfaa7c96 100644
--- a/user_setups/win32/windows_sdl.ini
+++ b/user_setups/win32/windows_sdl.ini
@@ -93,7 +93,7 @@ lib_deps =
;lv_drivers@~7.9.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
- bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
+ bblanchon/ArduinoJson@^6.21.5 ; Json(l) parser
https://github.com/fvanroie/lv_drivers
lib_ignore =
diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini
new file mode 100644
index 00000000..b51ecfb4
--- /dev/null
+++ b/user_setups/win32/windows_sdl_64bits.ini
@@ -0,0 +1,137 @@
+[env:windows_sdl_64bits]
+platform = native@^1.1.4
+extra_scripts =
+ tools/sdl2_build_extra.py
+ tools/windows_build_extra.py
+build_flags =
+ ${env.build_flags}
+ -D HASP_MODEL="Windows App"
+
+ ; ----- Monitor
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=320
+ ; SDL drivers options
+ ;-D LV_LVGL_H_INCLUDE_SIMPLE
+ ;-D LV_DRV_NO_CONF
+ -D USE_MONITOR
+ -D MONITOR_ZOOM=1 ; can be fractional like 1.5 or 2
+ -D USE_MOUSE
+ -D USE_MOUSEWHEEL
+ -D USE_KEYBOARD
+ ; ----- ArduinoJson
+ -D ARDUINOJSON_DECODE_UNICODE=1
+ -D HASP_NUM_PAGES=12
+ -D HASP_USE_SPIFFS=0
+ -D HASP_USE_LITTLEFS=0
+ -D HASP_USE_EEPROM=0
+ -D HASP_USE_GPIO=1
+ -D HASP_USE_CONFIG=0 ; Standalone application, as library
+ -D HASP_USE_DEBUG=1
+ -D HASP_USE_PNGDECODE=1
+ -D HASP_USE_BMPDECODE=1
+ -D HASP_USE_GIFDECODE=0
+ -D HASP_USE_JPGDECODE=0
+ -D HASP_USE_MQTT=1
+ -D HASP_USE_SYSLOG=0
+ -D MQTT_MAX_PACKET_SIZE=2048
+ -D HASP_ATTRIBUTE_FAST_MEM=
+ -D IRAM_ATTR= ; No IRAM_ATTR available
+ -D PROGMEM= ; No PROGMEM available
+
+ ; -- FreeType build options ------------------------
+ -D LV_USE_FT_CACHE_MANAGER=1 ; crashes without cache
+ -D LVGL_FREETYPE_MAX_FACES=64 ; max number of FreeType faces in cache
+ -D LVGL_FREETYPE_MAX_SIZES=4 ; max number of sizes in cache
+ -D LVGL_FREETYPE_MAX_BYTES=16384 ; max bytes in cache
+ -D LVGL_FREETYPE_MAX_BYTES_PSRAM=65536 ; max bytes in cache when using PSRAM
+
+ ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
+ ;-D LV_LOG_PRINTF=1
+ ; Add recursive dirs for hal headers search
+ -D _WIN64
+ -D WINDOWS ; We add this ourselves for code branching in hasp
+ -D WIN32_LEAN_AND_MEAN ; exclude a bunch of Windows header files from windows.h
+ -D PAHO_MQTT_STATIC
+ -DPAHO_WITH_SSL=TRUE
+ -DPAHO_BUILD_DOCUMENTATION=FALSE
+ -DPAHO_BUILD_SAMPLES=FALSE
+ -DCMAKE_BUILD_TYPE=Release
+ -DCMAKE_VERBOSE_MAKEFILE=TRUE
+ ;-D NO_PERSISTENCE
+ -I.pio/libdeps/windows_sdl_64bits/paho/src
+ -I.pio/libdeps/windows_sdl_64bits/ArduinoJson/src
+ -I lib/lv_fs_if
+ -I lib/lv_datetime
+ !python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
+ -mconsole
+ ; ----- Statically linked libraries --------------------
+ -l"ws2_32" ;windsock2
+ -lrpcrt4
+ -lcrypt32
+ -lmingw32
+ -lSDL2main
+ -lSDL2
+ -mwindows
+ -lm
+ -ldinput8
+ ;-ldxguid
+ ;-ldxerr8
+ ;-luser32
+ ;-lgdi32
+ -lwinmm
+ -limm32
+ -lole32
+ -loleaut32
+ ;-lshell32
+ -lversion
+ ;-luuid
+ -lsetupapi
+ ;-lhid
+
+lib_deps =
+ ${env.lib_deps}
+ ;lv_drivers@~7.9.0
+ ;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
+ https://github.com/eclipse/paho.mqtt.c.git
+ bblanchon/ArduinoJson@^6.21.5 ; Json(l) parser
+ https://github.com/fvanroie/lv_drivers
+
+lib_ignore =
+ paho
+ AXP192
+ ArduinoLog
+ lv_lib_qrcode
+ ETHSPI
+
+build_src_filter =
+ +<*>
+ -<*.h>
+ +<../hal/sdl2>
+ +<../.pio/libdeps/windows_sdl_64bits/paho/src/*.c>
+ +<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTClient.c>
+ -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsync.c>
+ -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsyncUtils.c>
+ -<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTVersion.c>
+ -<../.pio/libdeps/windows_sdl_64bits/paho/src/SSLSocket.c>
+ +
+ -
+ -
+ -
+ -
+ -
+ +
+ -
+ +
+ -
+ +
+ +
+ -
+ -
+ -
+ +
+ +
+ +
+ -
+ +
+ +<../.pio/libdeps/windows_sdl_64bits/ArduinoJson/src/ArduinoJson.h>
+ +
From d9d4d8d0c9ad807b67c08893d5d76fcaec2dca1f Mon Sep 17 00:00:00 2001
From: Diogo Gomes
Date: Thu, 22 Feb 2024 23:24:24 +0000
Subject: [PATCH 120/135] fix to compile in MacOS 14
---
src/hasp_debug.cpp | 2 +-
src/main_pc.cpp | 2 +-
tools/osx_build_extra.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index ca648c60..c249ece5 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -29,7 +29,7 @@
#if defined(POSIX)
#include
-#include
+#include
#define cwd getcwd
#endif
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 40431d75..8ad67fa3 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -18,7 +18,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#define cwd getcwd
diff --git a/tools/osx_build_extra.py b/tools/osx_build_extra.py
index ae726458..a36fc387 100644
--- a/tools/osx_build_extra.py
+++ b/tools/osx_build_extra.py
@@ -1,7 +1,7 @@
Import("env")
#env.Replace(CC="gcc-10", CXX="g++-10")
-env.Replace(CC="gcc-12", CXX="g++-12")
+env.Replace(CC="gcc-13", CXX="g++-13")
env.Replace(BUILD_SCRIPT="tools/osx_build_script.py")
From e37d38e399894843fa2b030f850246c5cec783ce Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sun, 25 Feb 2024 20:36:08 +0100
Subject: [PATCH 121/135] Add MDNS discovery
---
src/hasp/hasp_dispatch.cpp | 17 +++++++++++------
src/hasp/hasp_dispatch.h | 1 +
src/sys/svc/hasp_mdns.cpp | 28 ++++++++++++++++++++++------
3 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index d9555c8a..512c49e0 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -1295,13 +1295,8 @@ void dispatch_queue_discovery(const char*, const char*, uint8_t source)
dispatchSecondsToNextDiscovery = seconds;
}
-// Periodically publish a JSON string facilitating plate discovery
-void dispatch_send_discovery(const char*, const char*, uint8_t source)
+void dispatch_get_discovery_data(JsonDocument& doc)
{
-#if HASP_USE_MQTT > 0
-
- StaticJsonDocument<1024> doc;
- char data[1024];
char buffer[64];
doc[F("node")] = haspDevice.get_hostname();
@@ -1326,7 +1321,17 @@ void dispatch_send_discovery(const char*, const char*, uint8_t source)
#if HASP_USE_GPIO > 0
gpio_discovery(input, relay, led, dimmer);
#endif
+}
+// Periodically publish a JSON string facilitating plate discovery
+void dispatch_send_discovery(const char*, const char*, uint8_t source)
+{
+#if HASP_USE_MQTT > 0
+ StaticJsonDocument<1024> doc;
+ char data[1024];
+ char buffer[64];
+
+ dispatch_get_discovery_data(doc);
size_t len = serializeJson(doc, data);
switch(mqtt_send_discovery(data, len)) {
diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h
index 13967871..48cefdc8 100644
--- a/src/hasp/hasp_dispatch.h
+++ b/src/hasp/hasp_dispatch.h
@@ -100,6 +100,7 @@ void dispatch_state_val(const char* topic, hasp_event_t eventid, int32_t val);
void dispatch_state_antiburn(hasp_event_t eventid);
/* ===== Getter and Setter Functions ===== */
+void dispatch_get_discovery_data(JsonDocument& doc);
/* ===== Read/Write Configuration ===== */
diff --git a/src/sys/svc/hasp_mdns.cpp b/src/sys/svc/hasp_mdns.cpp
index 0252fb9c..4ef4582b 100644
--- a/src/sys/svc/hasp_mdns.cpp
+++ b/src/sys/svc/hasp_mdns.cpp
@@ -51,20 +51,36 @@ void mdnsStart()
};*/
if(MDNS.begin(haspDevice.get_hostname())) {
- char value[32];
+ char value[1024]; // 32
char service[12];
char key[12];
char proto[4];
sprintf_P(proto, PSTR("tcp"));
- strcpy_P(service, PSTR("http"));
+ // strcpy_P(service, PSTR("http"));
+ // MDNS.addService(service, proto, 80);
+
+ // strcpy_P(key, PSTR("app_version"));
+ // MDNS.addServiceTxt(service, proto, key, haspDevice.get_version());
+
+ // strcpy_P(key, PSTR("app_name"));
+ // strcpy_P(value, PSTR(D_MANUFACTURER));
+ // MDNS.addServiceTxt(service, proto, key, value);
+
+ strcpy_P(service, PSTR("openhasp"));
MDNS.addService(service, proto, 80);
- strcpy_P(key, PSTR("app_version"));
+ strcpy_P(key, PSTR("version"));
MDNS.addServiceTxt(service, proto, key, haspDevice.get_version());
- strcpy_P(key, PSTR("app_name"));
- strcpy_P(value, PSTR(D_MANUFACTURER));
+ // strcpy_P(key, PSTR("app_name"));
+ // strcpy_P(value, PSTR(D_MANUFACTURER));
+ MDNS.addServiceTxt(service, proto, key, value);
+
+ strcpy_P(key, PSTR("discovery"));
+ StaticJsonDocument<1024> doc;
+ dispatch_get_discovery_data(doc);
+ size_t len = serializeJson(doc, value);
MDNS.addServiceTxt(service, proto, key, value);
// if(debugTelnetEnabled) {
@@ -85,7 +101,7 @@ bool mdns_remove_service(char* service, char* proto)
#endif
#if ESP8266
- return MDNS.removeService(haspDevice.get_hostname(),"_arduino", "_tcp");
+ return MDNS.removeService(haspDevice.get_hostname(), "_arduino", "_tcp");
#endif
}
From cf5c02d487ddfe531ed652d60cc19aca4322386b Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sun, 25 Feb 2024 20:38:09 +0100
Subject: [PATCH 122/135] Add MDNS discovery
---
src/sys/svc/hasp_mdns.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sys/svc/hasp_mdns.cpp b/src/sys/svc/hasp_mdns.cpp
index 4ef4582b..995c6639 100644
--- a/src/sys/svc/hasp_mdns.cpp
+++ b/src/sys/svc/hasp_mdns.cpp
@@ -73,9 +73,9 @@ void mdnsStart()
strcpy_P(key, PSTR("version"));
MDNS.addServiceTxt(service, proto, key, haspDevice.get_version());
- // strcpy_P(key, PSTR("app_name"));
+ // strcpy_P(key, PSTR("name"));
// strcpy_P(value, PSTR(D_MANUFACTURER));
- MDNS.addServiceTxt(service, proto, key, value);
+ // MDNS.addServiceTxt(service, proto, key, value);
strcpy_P(key, PSTR("discovery"));
StaticJsonDocument<1024> doc;
From 510565ca517ea78ebc89ee1a5853f4a1e18e0608 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sun, 25 Feb 2024 21:28:38 +0100
Subject: [PATCH 123/135] Serialize event payloads properly #637
---
src/hasp/hasp_event.cpp | 104 ++++++++++++++++++++++++++--------------
1 file changed, 68 insertions(+), 36 deletions(-)
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index fd5eeaee..f5461817 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -272,12 +272,16 @@ static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val)
{
char data[512];
{
+ StaticJsonDocument<512> doc;
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
- if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"tag\":%s}"), eventname, val, tag);
- else
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
+ doc["event"] = eventname;
+ doc["val"] = val;
+ if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
+ serializeJson(doc, data, sizeof(data));
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"tag\":%s}"), eventname, val, tag);
+ // else
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
}
event_send_object_data(obj, data);
}
@@ -287,14 +291,21 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16
{
char data[512];
{
+ StaticJsonDocument<512> doc;
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
-
- if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\",\"tag\":%s}"), eventname,
- val, text, tag);
- else
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), eventname, val, text);
+ doc["event"] = eventname;
+ doc["val"] = val;
+ doc["text"] = text;
+ if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
+ serializeJson(doc, data, sizeof(data));
+ // if(const char* tag = my_obj_get_tag(obj))
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\",\"tag\":%s}"),
+ // eventname,
+ // val, text, tag);
+ // else
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), eventname, val,
+ // text);
}
event_send_object_data(obj, data);
}
@@ -433,15 +444,19 @@ void textarea_event_handler(lv_obj_t* obj, lv_event_t event)
char data[1024];
{
+ StaticJsonDocument<1024> doc;
char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
-
- if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\",\"tag\":%s}"), eventname,
- lv_textarea_get_text(obj), tag);
- else
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\"}"), eventname,
- lv_textarea_get_text(obj));
+ doc["event"] = eventname;
+ doc["text"] = lv_textarea_get_text(obj);
+ if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
+ serializeJson(doc, data, sizeof(data));
+ // if(const char* tag = my_obj_get_tag(obj))
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\",\"tag\":%s}"), eventname,
+ // lv_textarea_get_text(obj), tag);
+ // else
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\"}"), eventname,
+ // lv_textarea_get_text(obj));
}
event_send_object_data(obj, data);
@@ -525,13 +540,16 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event)
} else {
char data[512];
{
+ StaticJsonDocument<512> doc;
char eventname[8];
Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
-
- if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
- else
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
+ doc["event"] = eventname;
+ if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
+ serializeJson(doc, data, sizeof(data));
+ // if(const char* tag = my_obj_get_tag(obj))
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
+ // else
+ // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
}
event_send_object_data(obj, data);
}
@@ -842,8 +860,10 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
char data[512];
{
- char eventname[8];
- Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
+ StaticJsonDocument<512> doc;
+ char buffer[8];
+ Parser::get_event_name(hasp_event_id, buffer, sizeof(buffer));
+ doc["event"] = buffer;
lv_color32_t c32;
lv_color_hsv_t hsv;
@@ -851,18 +871,30 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
hsv = lv_color_rgb_to_hsv(c32.ch.red, c32.ch.green, c32.ch.blue);
last_color_sent = color;
- if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data),
- PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
- "d,\"v\":%d,\"tag\":%s}"),
- eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
- hsv.s, hsv.v, tag);
- else
- snprintf_P(data, sizeof(data),
- PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
- "d,\"v\":%d}"),
- eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
- hsv.s, hsv.v);
+ snprintf_P(buffer, sizeof(buffer), PSTR("#%02x%02x%02x"), c32.ch.red, c32.ch.green, c32.ch.blue);
+ doc["color"] = buffer;
+ doc["r"] = c32.ch.red;
+ doc["g"] = c32.ch.green;
+ doc["b"] = c32.ch.blue;
+ doc["h"] = hsv.h;
+ doc["s"] = hsv.s;
+ doc["v"] = hsv.v;
+
+ if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
+ serializeJson(doc, data, sizeof(data));
+
+ // if(const char* tag = my_obj_get_tag(obj))
+ // snprintf_P(data, sizeof(data),
+ // PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
+ // "d,\"v\":%d,\"tag\":%s}"),
+ // eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
+ // hsv.s, hsv.v, tag);
+ // else
+ // snprintf_P(data, sizeof(data),
+ // PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
+ // "d,\"v\":%d}"),
+ // eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
+ // hsv.s, hsv.v);
}
event_send_object_data(obj, data);
From 11f695aff72f1dd2bd4dc764215c42cbbffda782 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sun, 25 Feb 2024 23:12:49 +0100
Subject: [PATCH 124/135] Add MDNS discovery
---
src/hasp/hasp_dispatch.cpp | 13 +++++++------
src/sys/svc/hasp_mdns.cpp | 15 +++++----------
2 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 512c49e0..03b0da9d 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -1299,12 +1299,13 @@ void dispatch_get_discovery_data(JsonDocument& doc)
{
char buffer[64];
- doc[F("node")] = haspDevice.get_hostname();
- doc[F("mdl")] = haspDevice.get_model();
- doc[F("mf")] = F(D_MANUFACTURER);
- doc[F("hwid")] = haspDevice.get_hardware_id();
- doc[F("pages")] = haspPages.count();
- doc[F("sw")] = haspDevice.get_version();
+ doc[F("node")] = haspDevice.get_hostname();
+ doc[F("mdl")] = haspDevice.get_model();
+ doc[F("mf")] = F(D_MANUFACTURER);
+ doc[F("hwid")] = haspDevice.get_hardware_id();
+ doc[F("pages")] = haspPages.count();
+ doc[F("sw")] = haspDevice.get_version();
+ doc[F("node_t")] = String("hasp/") + haspDevice.get_hostname() + "/";
#if HASP_USE_HTTP > 0
network_get_ipaddress(buffer, sizeof(buffer));
diff --git a/src/sys/svc/hasp_mdns.cpp b/src/sys/svc/hasp_mdns.cpp
index 995c6639..2817a238 100644
--- a/src/sys/svc/hasp_mdns.cpp
+++ b/src/sys/svc/hasp_mdns.cpp
@@ -70,18 +70,13 @@ void mdnsStart()
strcpy_P(service, PSTR("openhasp"));
MDNS.addService(service, proto, 80);
- strcpy_P(key, PSTR("version"));
- MDNS.addServiceTxt(service, proto, key, haspDevice.get_version());
-
- // strcpy_P(key, PSTR("name"));
- // strcpy_P(value, PSTR(D_MANUFACTURER));
- // MDNS.addServiceTxt(service, proto, key, value);
-
- strcpy_P(key, PSTR("discovery"));
StaticJsonDocument<1024> doc;
dispatch_get_discovery_data(doc);
- size_t len = serializeJson(doc, value);
- MDNS.addServiceTxt(service, proto, key, value);
+
+ JsonObject data = doc.as();
+ for(JsonPair i : data) {
+ MDNS.addServiceTxt(service, proto, i.key().c_str(), i.value().as());
+ }
// if(debugTelnetEnabled) {
strcpy_P(service, PSTR("telnet"));
From 080b41e036b433cfd3ca8fadc78e7b1ba581c0b6 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sun, 25 Feb 2024 23:59:57 +0100
Subject: [PATCH 125/135] Fix FPSTR redefines
---
include/hasp_conf.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index d7b666cb..879f61f8 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -4,6 +4,10 @@
#ifndef HASP_CONF_H
#define HASP_CONF_H
+#if HASP_TARGET_ARDUINO
+#include "Arduino.h"
+#endif
+
#ifdef USE_CONFIG_OVERRIDE
#include "user_config_override.h"
#endif
@@ -207,11 +211,11 @@
#define IRAM_ATTR
#endif
-#ifndef FPSTR
+#if !defined(FPSTR)
#define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
#endif
-#ifndef PGM_P
+#if !defined(PGM_P)
#define PGM_P const char*
#endif
From 4523f134cebfa98bbab5e38afc65b0706b84a039 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Feb 2024 00:47:49 +0100
Subject: [PATCH 126/135] Only serialize text, not tags
---
src/hasp/hasp_event.cpp | 108 +++++++++++++++-------------------------
1 file changed, 40 insertions(+), 68 deletions(-)
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index f5461817..3f210ad1 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -272,16 +272,12 @@ static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val)
{
char data[512];
{
- StaticJsonDocument<512> doc;
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
- doc["event"] = eventname;
- doc["val"] = val;
- if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
- serializeJson(doc, data, sizeof(data));
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"tag\":%s}"), eventname, val, tag);
- // else
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
+ if(const char* tag = my_obj_get_tag(obj))
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"tag\":%s}"), eventname, val, tag);
+ else
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
}
event_send_object_data(obj, data);
}
@@ -291,21 +287,20 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16
{
char data[512];
{
- StaticJsonDocument<512> doc;
+ StaticJsonDocument<256> doc;
+ size_t len = text ? strlen(text) : 0;
+ doc.set(text); // use text as-is
+ char serialized_text[256];
+ len = serializeJson(doc, serialized_text, sizeof(serialized_text));
+
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
- doc["event"] = eventname;
- doc["val"] = val;
- doc["text"] = text;
- if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
- serializeJson(doc, data, sizeof(data));
- // if(const char* tag = my_obj_get_tag(obj))
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\",\"tag\":%s}"),
- // eventname,
- // val, text, tag);
- // else
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), eventname, val,
- // text);
+ if(const char* tag = my_obj_get_tag(obj))
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\",\"tag\":%s}"), eventname,
+ val, serialized_text, tag);
+ else
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), eventname, val,
+ serialized_text);
}
event_send_object_data(obj, data);
}
@@ -444,19 +439,14 @@ void textarea_event_handler(lv_obj_t* obj, lv_event_t event)
char data[1024];
{
- StaticJsonDocument<1024> doc;
char eventname[8];
Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
- doc["event"] = eventname;
- doc["text"] = lv_textarea_get_text(obj);
- if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
- serializeJson(doc, data, sizeof(data));
- // if(const char* tag = my_obj_get_tag(obj))
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\",\"tag\":%s}"), eventname,
- // lv_textarea_get_text(obj), tag);
- // else
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\"}"), eventname,
- // lv_textarea_get_text(obj));
+ if(const char* tag = my_obj_get_tag(obj))
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\",\"tag\":%s}"), eventname,
+ lv_textarea_get_text(obj), tag);
+ else
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"text\":\"%s\"}"), eventname,
+ lv_textarea_get_text(obj));
}
event_send_object_data(obj, data);
@@ -540,16 +530,12 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event)
} else {
char data[512];
{
- StaticJsonDocument<512> doc;
char eventname[8];
Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
- doc["event"] = eventname;
- if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
- serializeJson(doc, data, sizeof(data));
- // if(const char* tag = my_obj_get_tag(obj))
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
- // else
- // snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
+ if(const char* tag = my_obj_get_tag(obj))
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"tag\":%s}"), eventname, tag);
+ else
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
}
event_send_object_data(obj, data);
}
@@ -860,10 +846,8 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
char data[512];
{
- StaticJsonDocument<512> doc;
- char buffer[8];
- Parser::get_event_name(hasp_event_id, buffer, sizeof(buffer));
- doc["event"] = buffer;
+ char eventname[8];
+ Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname));
lv_color32_t c32;
lv_color_hsv_t hsv;
@@ -871,30 +855,18 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
hsv = lv_color_rgb_to_hsv(c32.ch.red, c32.ch.green, c32.ch.blue);
last_color_sent = color;
- snprintf_P(buffer, sizeof(buffer), PSTR("#%02x%02x%02x"), c32.ch.red, c32.ch.green, c32.ch.blue);
- doc["color"] = buffer;
- doc["r"] = c32.ch.red;
- doc["g"] = c32.ch.green;
- doc["b"] = c32.ch.blue;
- doc["h"] = hsv.h;
- doc["s"] = hsv.s;
- doc["v"] = hsv.v;
-
- if(const char* tag = my_obj_get_tag(obj)) doc["tag"] = tag;
- serializeJson(doc, data, sizeof(data));
-
- // if(const char* tag = my_obj_get_tag(obj))
- // snprintf_P(data, sizeof(data),
- // PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
- // "d,\"v\":%d,\"tag\":%s}"),
- // eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
- // hsv.s, hsv.v, tag);
- // else
- // snprintf_P(data, sizeof(data),
- // PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
- // "d,\"v\":%d}"),
- // eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
- // hsv.s, hsv.v);
+ if(const char* tag = my_obj_get_tag(obj))
+ snprintf_P(data, sizeof(data),
+ PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
+ "d,\"v\":%d,\"tag\":%s}"),
+ eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
+ hsv.s, hsv.v, tag);
+ else
+ snprintf_P(data, sizeof(data),
+ PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
+ "d,\"v\":%d}"),
+ eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
+ hsv.s, hsv.v);
}
event_send_object_data(obj, data);
From ff6a8846cef68d63fd342c27a1140855da35ac6f Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Feb 2024 00:59:10 +0100
Subject: [PATCH 127/135] Update copyright
---
include/VersionInfo.h | 2 +-
include/espspi/Ethernet.h | 2 +-
include/hasp_conf.h | 2 +-
include/hasp_macro.h | 2 +-
include/hasp_mem.h | 2 +-
include/lv_symbol_mdi_def.h | 2 +-
include/stm32f4/hal_conf_custom.h | 2 +-
include/user_config_override-template.h | 2 +-
lib/lv_lib_zifont/lv_zifont.cpp | 2 +-
lib/lv_lib_zifont/lv_zifont.h | 2 +-
src/custom/my_custom_fan_template.cpp | 2 +-
src/custom/my_custom_template.cpp | 2 +-
src/custom/my_custom_template.h | 2 +-
src/dev/device.h | 2 +-
src/dev/esp32/esp32.cpp | 2 +-
src/dev/esp32/lanbonl8.cpp | 2 +-
src/dev/esp32/lanbonl8.h | 2 +-
src/dev/esp8266/esp8266.cpp | 2 +-
src/dev/esp8266/esp8266.h | 2 +-
src/dev/posix/hasp_posix.cpp | 2 +-
src/dev/stm32f4/stm32f4.cpp | 2 +-
src/dev/stm32f4/stm32f4.h | 2 +-
src/dev/stm32f7/stm32f7.cpp | 2 +-
src/dev/stm32f7/stm32f7.h | 2 +-
src/dev/win32/hasp_win32.cpp | 2 +-
src/dev/win32/hasp_win32.h | 2 +-
src/drv/old/hasp_drv_ft5206.h | 2 +-
src/drv/old/hasp_drv_ft6336u.h | 2 +-
src/drv/old/hasp_drv_gt911.h | 2 +-
src/drv/old/hasp_drv_tft_espi.cpp | 2 +-
src/drv/old/hasp_drv_tft_espi.h | 2 +-
src/drv/old/hasp_drv_touch.cpp | 2 +-
src/drv/old/hasp_drv_touch.h | 2 +-
src/drv/old/hasp_drv_xpt2046.h | 2 +-
src/drv/tft/tft_defines.h | 2 +-
src/drv/tft/tft_driver.h | 2 +-
src/drv/tft/tft_driver_arduinogfx.h | 2 +-
src/drv/tft/tft_driver_lovyangfx.h | 2 +-
src/drv/tft/tft_driver_posix_fbdev.cpp | 2 +-
src/drv/tft/tft_driver_posix_fbdev.h | 2 +-
src/drv/tft/tft_driver_sdl2.cpp | 2 +-
src/drv/tft/tft_driver_sdl2.h | 2 +-
src/drv/tft/tft_driver_tftespi.cpp | 2 +-
src/drv/tft/tft_driver_tftespi.h | 2 +-
src/drv/tft/tft_driver_win32drv.cpp | 2 +-
src/drv/tft/tft_driver_win32drv.h | 2 +-
src/drv/touch/touch_driver.h | 2 +-
src/drv/touch/touch_driver_analog.h | 2 +-
src/drv/touch/touch_driver_ft6336u.h | 2 +-
src/drv/touch/touch_driver_gslx680.h | 2 +-
src/drv/touch/touch_driver_lovyangfx.h | 2 +-
src/drv/touch/touch_driver_stmpe610.h | 2 +-
src/drv/touch/touch_driver_tsc2007.h | 2 +-
src/drv/touch/touch_helper.h | 2 +-
src/hal/hasp_hal.cpp | 2 +-
src/hal/hasp_hal.h | 2 +-
src/hasp/hasp_attribute.h | 2 +-
src/hasp/hasp_attribute_helper.h | 2 +-
src/hasp/hasp_dispatch.h | 2 +-
src/hasp/hasp_event.cpp | 2 +-
src/hasp/hasp_event.h | 2 +-
src/hasp/hasp_font.h | 2 +-
src/hasp/hasp_lvfs.cpp | 2 +-
src/hasp/hasp_lvfs.h | 2 +-
src/hasp/hasp_mem.cpp | 2 +-
src/hasp/hasp_object.cpp | 2 +-
src/hasp/hasp_page.cpp | 2 +-
src/hasp/hasp_page.h | 2 +-
src/hasp/hasp_parser.cpp | 2 +-
src/hasp/hasp_parser.h | 2 +-
src/hasp/hasp_style.cpp | 2 +-
src/hasp/hasp_task.h | 2 +-
src/hasp/lv_theme_hasp.h | 2 +-
src/hasp_debug.h | 2 +-
src/hasp_eeprom.cpp | 2 +-
src/hasp_eeprom.h | 2 +-
src/hasp_gui.h | 2 +-
src/log/hasp_debug.cpp | 2 +-
src/main_pc.cpp | 2 +-
src/mqtt/hasp_mqtt_ha.cpp | 2 +-
src/mqtt/hasp_mqtt_ha.h | 2 +-
src/mqtt/hasp_mqtt_paho_async.cpp | 2 +-
src/sys/net/hasp_ethernet_esp32.cpp | 2 +-
src/sys/net/hasp_ethernet_esp32.h | 2 +-
src/sys/net/hasp_ethernet_stm32.cpp | 2 +-
src/sys/net/hasp_ethernet_stm32.h | 2 +-
src/sys/net/hasp_network.cpp | 2 +-
src/sys/net/hasp_network.h | 2 +-
src/sys/svc/hasp_http_async.cpp | 2 +-
src/sys/svc/hasp_mdns.cpp | 2 +-
src/sys/svc/hasp_ota.h | 2 +-
src/sys/svc/hasp_slave.cpp | 2 +-
src/sys/svc/hasp_slave.h | 2 +-
src/sys/svc/hasp_telnet.h | 2 +-
94 files changed, 94 insertions(+), 94 deletions(-)
diff --git a/include/VersionInfo.h b/include/VersionInfo.h
index 885dc775..55609e90 100644
--- a/include/VersionInfo.h
+++ b/include/VersionInfo.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* This file is used during the build of the paho library */
diff --git a/include/espspi/Ethernet.h b/include/espspi/Ethernet.h
index b5b35acf..d8f5baf3 100644
--- a/include/espspi/Ethernet.h
+++ b/include/espspi/Ethernet.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef WIFISPI_H
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index 879f61f8..978aa450 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_CONF_H
diff --git a/include/hasp_macro.h b/include/hasp_macro.h
index 7dc1f82b..44b6ed8b 100644
--- a/include/hasp_macro.h
+++ b/include/hasp_macro.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_MACRO_H
diff --git a/include/hasp_mem.h b/include/hasp_mem.h
index 7b5223c8..31d0705e 100644
--- a/include/hasp_mem.h
+++ b/include/hasp_mem.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_MEM_H
diff --git a/include/lv_symbol_mdi_def.h b/include/lv_symbol_mdi_def.h
index 23c8e3e6..9ee037a5 100644
--- a/include/lv_symbol_mdi_def.h
+++ b/include/lv_symbol_mdi_def.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef LV_SYMBOL_MDI_DEF_H
diff --git a/include/stm32f4/hal_conf_custom.h b/include/stm32f4/hal_conf_custom.h
index c6d8ba32..193ca5a1 100644
--- a/include/stm32f4/hal_conf_custom.h
+++ b/include/stm32f4/hal_conf_custom.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* Include the normal default core configuration */
diff --git a/include/user_config_override-template.h b/include/user_config_override-template.h
index 83f4e3a3..2d6c97c7 100644
--- a/include/user_config_override-template.h
+++ b/include/user_config_override-template.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/***************************************************
diff --git a/lib/lv_lib_zifont/lv_zifont.cpp b/lib/lv_lib_zifont/lv_zifont.cpp
index 3db55627..7a3b7977 100644
--- a/lib/lv_lib_zifont/lv_zifont.cpp
+++ b/lib/lv_lib_zifont/lv_zifont.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/*********************
diff --git a/lib/lv_lib_zifont/lv_zifont.h b/lib/lv_lib_zifont/lv_zifont.h
index 31090b59..a5d5e7f2 100644
--- a/lib/lv_lib_zifont/lv_zifont.h
+++ b/lib/lv_lib_zifont/lv_zifont.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef LV_ZIFONT_H
diff --git a/src/custom/my_custom_fan_template.cpp b/src/custom/my_custom_fan_template.cpp
index 8318bffe..b7bed86d 100644
--- a/src/custom/my_custom_fan_template.cpp
+++ b/src/custom/my_custom_fan_template.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
// USAGE: - Copy this file and rename it to my_custom_fan_rotator.cpp, also copy my_custom_template.h and rename it to my_custom.h
diff --git a/src/custom/my_custom_template.cpp b/src/custom/my_custom_template.cpp
index c6cd66ac..b41da916 100644
--- a/src/custom/my_custom_template.cpp
+++ b/src/custom/my_custom_template.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
// USAGE: - Copy this file and rename it to my_custom.cpp
diff --git a/src/custom/my_custom_template.h b/src/custom/my_custom_template.h
index 01784d2a..111df88f 100644
--- a/src/custom/my_custom_template.h
+++ b/src/custom/my_custom_template.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
// USAGE: - Copy this file and rename it to my_custom.h
diff --git a/src/dev/device.h b/src/dev/device.h
index a17ef6dd..c6ec426f 100644
--- a/src/dev/device.h
+++ b/src/dev/device.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_H
diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp
index bf54d79a..3882c53d 100644
--- a/src/dev/esp32/esp32.cpp
+++ b/src/dev/esp32/esp32.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(ESP32)
diff --git a/src/dev/esp32/lanbonl8.cpp b/src/dev/esp32/lanbonl8.cpp
index 5104c7ba..be5513a5 100644
--- a/src/dev/esp32/lanbonl8.cpp
+++ b/src/dev/esp32/lanbonl8.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "lanbonl8.h"
diff --git a/src/dev/esp32/lanbonl8.h b/src/dev/esp32/lanbonl8.h
index 5f4ed667..79e1a691 100644
--- a/src/dev/esp32/lanbonl8.h
+++ b/src/dev/esp32/lanbonl8.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_LANBONL8_H
diff --git a/src/dev/esp8266/esp8266.cpp b/src/dev/esp8266/esp8266.cpp
index be671830..a18d74e9 100644
--- a/src/dev/esp8266/esp8266.cpp
+++ b/src/dev/esp8266/esp8266.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(ESP8266)
diff --git a/src/dev/esp8266/esp8266.h b/src/dev/esp8266/esp8266.h
index 04087798..0f295424 100644
--- a/src/dev/esp8266/esp8266.h
+++ b/src/dev/esp8266/esp8266.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_ESP8266_H
diff --git a/src/dev/posix/hasp_posix.cpp b/src/dev/posix/hasp_posix.cpp
index ad020e4b..1e779b2e 100644
--- a/src/dev/posix/hasp_posix.cpp
+++ b/src/dev/posix/hasp_posix.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(POSIX)
diff --git a/src/dev/stm32f4/stm32f4.cpp b/src/dev/stm32f4/stm32f4.cpp
index d735891a..7a007aba 100644
--- a/src/dev/stm32f4/stm32f4.cpp
+++ b/src/dev/stm32f4/stm32f4.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(STM32F4xx)
diff --git a/src/dev/stm32f4/stm32f4.h b/src/dev/stm32f4/stm32f4.h
index 89af1699..2b4822d3 100644
--- a/src/dev/stm32f4/stm32f4.h
+++ b/src/dev/stm32f4/stm32f4.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_STM32F4_H
diff --git a/src/dev/stm32f7/stm32f7.cpp b/src/dev/stm32f7/stm32f7.cpp
index 11497812..288d5594 100644
--- a/src/dev/stm32f7/stm32f7.cpp
+++ b/src/dev/stm32f7/stm32f7.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(STM32F7xx)
diff --git a/src/dev/stm32f7/stm32f7.h b/src/dev/stm32f7/stm32f7.h
index 1254acb5..8ae7079c 100644
--- a/src/dev/stm32f7/stm32f7.h
+++ b/src/dev/stm32f7/stm32f7.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_STM32F4_H
diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp
index 591ccb75..985a3e68 100644
--- a/src/dev/win32/hasp_win32.cpp
+++ b/src/dev/win32/hasp_win32.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(WINDOWS)
diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h
index 09f56773..a378b0bc 100644
--- a/src/dev/win32/hasp_win32.h
+++ b/src/dev/win32/hasp_win32.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_WINDOWS_H
diff --git a/src/drv/old/hasp_drv_ft5206.h b/src/drv/old/hasp_drv_ft5206.h
index ce25edaf..5d0ee0d7 100644
--- a/src/drv/old/hasp_drv_ft5206.h
+++ b/src/drv/old/hasp_drv_ft5206.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DRV_FT5206_H
diff --git a/src/drv/old/hasp_drv_ft6336u.h b/src/drv/old/hasp_drv_ft6336u.h
index e672651b..8a17726e 100644
--- a/src/drv/old/hasp_drv_ft6336u.h
+++ b/src/drv/old/hasp_drv_ft6336u.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DRV_FT6336U_H
diff --git a/src/drv/old/hasp_drv_gt911.h b/src/drv/old/hasp_drv_gt911.h
index 74d22fde..e95665a7 100644
--- a/src/drv/old/hasp_drv_gt911.h
+++ b/src/drv/old/hasp_drv_gt911.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/*
diff --git a/src/drv/old/hasp_drv_tft_espi.cpp b/src/drv/old/hasp_drv_tft_espi.cpp
index a27411bf..7d3e4bfa 100644
--- a/src/drv/old/hasp_drv_tft_espi.cpp
+++ b/src/drv/old/hasp_drv_tft_espi.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/*********************
diff --git a/src/drv/old/hasp_drv_tft_espi.h b/src/drv/old/hasp_drv_tft_espi.h
index faa00cd9..d3721b82 100644
--- a/src/drv/old/hasp_drv_tft_espi.h
+++ b/src/drv/old/hasp_drv_tft_espi.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef TFT_ESPI_DRV_H
diff --git a/src/drv/old/hasp_drv_touch.cpp b/src/drv/old/hasp_drv_touch.cpp
index ef4c7b93..b667f8d1 100644
--- a/src/drv/old/hasp_drv_touch.cpp
+++ b/src/drv/old/hasp_drv_touch.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/drv/old/hasp_drv_touch.h b/src/drv/old/hasp_drv_touch.h
index 237a6c47..b4fb398e 100644
--- a/src/drv/old/hasp_drv_touch.h
+++ b/src/drv/old/hasp_drv_touch.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DRV_TOUCH_H
diff --git a/src/drv/old/hasp_drv_xpt2046.h b/src/drv/old/hasp_drv_xpt2046.h
index 93889cb4..f00960db 100644
--- a/src/drv/old/hasp_drv_xpt2046.h
+++ b/src/drv/old/hasp_drv_xpt2046.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DRV_XPT2046B_H
diff --git a/src/drv/tft/tft_defines.h b/src/drv/tft/tft_defines.h
index b886f8f9..ab789682 100644
--- a/src/drv/tft/tft_defines.h
+++ b/src/drv/tft/tft_defines.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TFT_DEFINES_H
diff --git a/src/drv/tft/tft_driver.h b/src/drv/tft/tft_driver.h
index 4a9dff48..c8bed996 100644
--- a/src/drv/tft/tft_driver.h
+++ b/src/drv/tft/tft_driver.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_BASE_TFT_DRIVER_H
diff --git a/src/drv/tft/tft_driver_arduinogfx.h b/src/drv/tft/tft_driver_arduinogfx.h
index 6db9546b..8d6d1f80 100644
--- a/src/drv/tft/tft_driver_arduinogfx.h
+++ b/src/drv/tft/tft_driver_arduinogfx.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_ARDUINOGFX_DRIVER_H
diff --git a/src/drv/tft/tft_driver_lovyangfx.h b/src/drv/tft/tft_driver_lovyangfx.h
index 4d6a5d09..e82fad0a 100644
--- a/src/drv/tft/tft_driver_lovyangfx.h
+++ b/src/drv/tft/tft_driver_lovyangfx.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_LOVYANGFX_DRIVER_H
diff --git a/src/drv/tft/tft_driver_posix_fbdev.cpp b/src/drv/tft/tft_driver_posix_fbdev.cpp
index 7abafa58..a6ec8d91 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.cpp
+++ b/src/drv/tft/tft_driver_posix_fbdev.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if USE_FBDEV && HASP_TARGET_PC
diff --git a/src/drv/tft/tft_driver_posix_fbdev.h b/src/drv/tft/tft_driver_posix_fbdev.h
index 643126bf..8cf8862b 100644
--- a/src/drv/tft/tft_driver_posix_fbdev.h
+++ b/src/drv/tft/tft_driver_posix_fbdev.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_FBDEV_DRIVER_H
diff --git a/src/drv/tft/tft_driver_sdl2.cpp b/src/drv/tft/tft_driver_sdl2.cpp
index c6c94651..6f14b1a9 100644
--- a/src/drv/tft/tft_driver_sdl2.cpp
+++ b/src/drv/tft/tft_driver_sdl2.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if USE_MONITOR && HASP_TARGET_PC
diff --git a/src/drv/tft/tft_driver_sdl2.h b/src/drv/tft/tft_driver_sdl2.h
index 32ce9e6d..54f65e89 100644
--- a/src/drv/tft/tft_driver_sdl2.h
+++ b/src/drv/tft/tft_driver_sdl2.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_SDL2_DRIVER_H
diff --git a/src/drv/tft/tft_driver_tftespi.cpp b/src/drv/tft/tft_driver_tftespi.cpp
index 291f3b20..6db53134 100644
--- a/src/drv/tft/tft_driver_tftespi.cpp
+++ b/src/drv/tft/tft_driver_tftespi.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if defined(ARDUINO) && defined(USER_SETUP_LOADED)
diff --git a/src/drv/tft/tft_driver_tftespi.h b/src/drv/tft/tft_driver_tftespi.h
index 3d72003c..94e32fa3 100644
--- a/src/drv/tft/tft_driver_tftespi.h
+++ b/src/drv/tft/tft_driver_tftespi.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TFTESPI_DRIVER_H
diff --git a/src/drv/tft/tft_driver_win32drv.cpp b/src/drv/tft/tft_driver_win32drv.cpp
index 9e32cb59..7c6e8732 100644
--- a/src/drv/tft/tft_driver_win32drv.cpp
+++ b/src/drv/tft/tft_driver_win32drv.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if USE_WIN32DRV && HASP_TARGET_PC
diff --git a/src/drv/tft/tft_driver_win32drv.h b/src/drv/tft/tft_driver_win32drv.h
index eefcd4eb..dabd0da4 100644
--- a/src/drv/tft/tft_driver_win32drv.h
+++ b/src/drv/tft/tft_driver_win32drv.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_WIN32DRV_DRIVER_H
diff --git a/src/drv/touch/touch_driver.h b/src/drv/touch/touch_driver.h
index 7e729180..054e8cad 100644
--- a/src/drv/touch/touch_driver.h
+++ b/src/drv/touch/touch_driver.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_BASE_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_driver_analog.h b/src/drv/touch/touch_driver_analog.h
index 75cdf071..4648ef27 100644
--- a/src/drv/touch/touch_driver_analog.h
+++ b/src/drv/touch/touch_driver_analog.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_ANALOG_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_driver_ft6336u.h b/src/drv/touch/touch_driver_ft6336u.h
index efc419cf..4ee5c2d3 100644
--- a/src/drv/touch/touch_driver_ft6336u.h
+++ b/src/drv/touch/touch_driver_ft6336u.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_FT6336T_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_driver_gslx680.h b/src/drv/touch/touch_driver_gslx680.h
index ca022960..82f23a90 100644
--- a/src/drv/touch/touch_driver_gslx680.h
+++ b/src/drv/touch/touch_driver_gslx680.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_GSL1680_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_driver_lovyangfx.h b/src/drv/touch/touch_driver_lovyangfx.h
index 21302165..355123b3 100644
--- a/src/drv/touch/touch_driver_lovyangfx.h
+++ b/src/drv/touch/touch_driver_lovyangfx.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_LOVYANGFX_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_driver_stmpe610.h b/src/drv/touch/touch_driver_stmpe610.h
index c3a605da..1b52653e 100644
--- a/src/drv/touch/touch_driver_stmpe610.h
+++ b/src/drv/touch/touch_driver_stmpe610.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_STMPE610_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_driver_tsc2007.h b/src/drv/touch/touch_driver_tsc2007.h
index 7688842c..2c27ee5d 100644
--- a/src/drv/touch/touch_driver_tsc2007.h
+++ b/src/drv/touch/touch_driver_tsc2007.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TSC2007_TOUCH_DRIVER_H
diff --git a/src/drv/touch/touch_helper.h b/src/drv/touch/touch_helper.h
index 3f11cd13..54b656f3 100644
--- a/src/drv/touch/touch_helper.h
+++ b/src/drv/touch/touch_helper.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TOUCH_HELPER_H
diff --git a/src/hal/hasp_hal.cpp b/src/hal/hasp_hal.cpp
index 1918fc9c..7a9c8278 100644
--- a/src/hal/hasp_hal.cpp
+++ b/src/hal/hasp_hal.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_hal.h"
diff --git a/src/hal/hasp_hal.h b/src/hal/hasp_hal.h
index d1c34d53..e9c29332 100644
--- a/src/hal/hasp_hal.h
+++ b/src/hal/hasp_hal.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_HAL_H
diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h
index c5c1b742..1e431a2f 100644
--- a/src/hasp/hasp_attribute.h
+++ b/src/hasp/hasp_attribute.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_ATTRIBUTE_H
diff --git a/src/hasp/hasp_attribute_helper.h b/src/hasp/hasp_attribute_helper.h
index 2b48bcbd..ee078300 100644
--- a/src/hasp/hasp_attribute_helper.h
+++ b/src/hasp/hasp_attribute_helper.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h
index 48cefdc8..545d4617 100644
--- a/src/hasp/hasp_dispatch.h
+++ b/src/hasp/hasp_dispatch.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DISPATCH_H
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index 3f210ad1..62b32dc9 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* ********************************************************************************************
diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h
index 0bbd55ca..f4c5a06b 100644
--- a/src/hasp/hasp_event.h
+++ b/src/hasp/hasp_event.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_EVENT_H
diff --git a/src/hasp/hasp_font.h b/src/hasp/hasp_font.h
index f2e7eee3..c98351bd 100644
--- a/src/hasp/hasp_font.h
+++ b/src/hasp/hasp_font.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_FONT_H
diff --git a/src/hasp/hasp_lvfs.cpp b/src/hasp/hasp_lvfs.cpp
index 3275dc48..32ba5b63 100644
--- a/src/hasp/hasp_lvfs.cpp
+++ b/src/hasp/hasp_lvfs.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "lv_fs_if.h"
diff --git a/src/hasp/hasp_lvfs.h b/src/hasp/hasp_lvfs.h
index 40099f38..e86bfc71 100644
--- a/src/hasp/hasp_lvfs.h
+++ b/src/hasp/hasp_lvfs.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_LVFS_H
diff --git a/src/hasp/hasp_mem.cpp b/src/hasp/hasp_mem.cpp
index f0859a36..09267fa1 100644
--- a/src/hasp/hasp_mem.cpp
+++ b/src/hasp/hasp_mem.cpp
@@ -1,5 +1,5 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include
diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp
index f7e436cf..68b1f8eb 100644
--- a/src/hasp/hasp_object.cpp
+++ b/src/hasp/hasp_object.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* ********************************************************************************************
diff --git a/src/hasp/hasp_page.cpp b/src/hasp/hasp_page.cpp
index 50b80343..23e72c2a 100644
--- a/src/hasp/hasp_page.cpp
+++ b/src/hasp/hasp_page.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/hasp/hasp_page.h b/src/hasp/hasp_page.h
index cfc9b27a..44c85d56 100644
--- a/src/hasp/hasp_page.h
+++ b/src/hasp/hasp_page.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_PAGES_H
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index 8660060c..a44a9741 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifdef ARDUINO
diff --git a/src/hasp/hasp_parser.h b/src/hasp/hasp_parser.h
index 4b9a8748..d1c44bea 100644
--- a/src/hasp/hasp_parser.h
+++ b/src/hasp/hasp_parser.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_PARSER_H
diff --git a/src/hasp/hasp_style.cpp b/src/hasp/hasp_style.cpp
index f0281998..b783f006 100644
--- a/src/hasp/hasp_style.cpp
+++ b/src/hasp/hasp_style.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_attribute.h" /*To see all the hashes*/
diff --git a/src/hasp/hasp_task.h b/src/hasp/hasp_task.h
index eef11077..1630900c 100644
--- a/src/hasp/hasp_task.h
+++ b/src/hasp/hasp_task.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TASK_H
diff --git a/src/hasp/lv_theme_hasp.h b/src/hasp/lv_theme_hasp.h
index c7dd2c32..a1995bed 100644
--- a/src/hasp/lv_theme_hasp.h
+++ b/src/hasp/lv_theme_hasp.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef LV_THEME_HASP_H
diff --git a/src/hasp_debug.h b/src/hasp_debug.h
index c025ff99..ea77d54a 100644
--- a/src/hasp_debug.h
+++ b/src/hasp_debug.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEBUG_H
diff --git a/src/hasp_eeprom.cpp b/src/hasp_eeprom.cpp
index 4a576c4a..dc3f83da 100644
--- a/src/hasp_eeprom.cpp
+++ b/src/hasp_eeprom.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_conf.h" // load first
diff --git a/src/hasp_eeprom.h b/src/hasp_eeprom.h
index 4d6cde2e..fa10b893 100644
--- a/src/hasp_eeprom.h
+++ b/src/hasp_eeprom.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_EEPROM_H
diff --git a/src/hasp_gui.h b/src/hasp_gui.h
index 8b5b12af..dd3680a8 100644
--- a/src/hasp_gui.h
+++ b/src/hasp_gui.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_GUI_H
diff --git a/src/log/hasp_debug.cpp b/src/log/hasp_debug.cpp
index dafed245..cbca09c6 100644
--- a/src/log/hasp_debug.cpp
+++ b/src/log/hasp_debug.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* ===========================================================================
diff --git a/src/main_pc.cpp b/src/main_pc.cpp
index 8ad67fa3..e61b3b06 100644
--- a/src/main_pc.cpp
+++ b/src/main_pc.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#if HASP_TARGET_PC
diff --git a/src/mqtt/hasp_mqtt_ha.cpp b/src/mqtt/hasp_mqtt_ha.cpp
index f7040e07..cc0e0130 100644
--- a/src/mqtt/hasp_mqtt_ha.cpp
+++ b/src/mqtt/hasp_mqtt_ha.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "ArduinoJson.h"
diff --git a/src/mqtt/hasp_mqtt_ha.h b/src/mqtt/hasp_mqtt_ha.h
index a49e1830..37abbed3 100644
--- a/src/mqtt/hasp_mqtt_ha.h
+++ b/src/mqtt/hasp_mqtt_ha.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_MQTT_HA_H
diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp
index 71136d07..6c4e35f2 100644
--- a/src/mqtt/hasp_mqtt_paho_async.cpp
+++ b/src/mqtt/hasp_mqtt_paho_async.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* Multi threaded asynchronous paho client */
diff --git a/src/sys/net/hasp_ethernet_esp32.cpp b/src/sys/net/hasp_ethernet_esp32.cpp
index 0ece6cb7..5c435437 100644
--- a/src/sys/net/hasp_ethernet_esp32.cpp
+++ b/src/sys/net/hasp_ethernet_esp32.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_conf.h"
diff --git a/src/sys/net/hasp_ethernet_esp32.h b/src/sys/net/hasp_ethernet_esp32.h
index d3359a2c..401e2249 100644
--- a/src/sys/net/hasp_ethernet_esp32.h
+++ b/src/sys/net/hasp_ethernet_esp32.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_ETHERNET_ESP32_H
diff --git a/src/sys/net/hasp_ethernet_stm32.cpp b/src/sys/net/hasp_ethernet_stm32.cpp
index 6923cba4..26203575 100644
--- a/src/sys/net/hasp_ethernet_stm32.cpp
+++ b/src/sys/net/hasp_ethernet_stm32.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_conf.h"
diff --git a/src/sys/net/hasp_ethernet_stm32.h b/src/sys/net/hasp_ethernet_stm32.h
index 10064158..0bf1c4c7 100644
--- a/src/sys/net/hasp_ethernet_stm32.h
+++ b/src/sys/net/hasp_ethernet_stm32.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_ETHERNET_STM32_H
diff --git a/src/sys/net/hasp_network.cpp b/src/sys/net/hasp_network.cpp
index 395f3a2f..88fd9d11 100644
--- a/src/sys/net/hasp_network.cpp
+++ b/src/sys/net/hasp_network.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/sys/net/hasp_network.h b/src/sys/net/hasp_network.h
index 47ec456a..95891fb8 100644
--- a/src/sys/net/hasp_network.h
+++ b/src/sys/net/hasp_network.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_NETWORK_H
diff --git a/src/sys/svc/hasp_http_async.cpp b/src/sys/svc/hasp_http_async.cpp
index 683d2f50..e4e882ef 100644
--- a/src/sys/svc/hasp_http_async.cpp
+++ b/src/sys/svc/hasp_http_async.cpp
@@ -489,7 +489,7 @@ void webHandleAbout(AsyncWebServerRequest* request)
String httpMessage((char*)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("
openHASP Copyright© 2019-2022 Francis Van Roie ");
+ httpMessage += F("
openHASP Copyright© 2019-2024 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");
diff --git a/src/sys/svc/hasp_mdns.cpp b/src/sys/svc/hasp_mdns.cpp
index 2817a238..2e00239d 100644
--- a/src/sys/svc/hasp_mdns.cpp
+++ b/src/sys/svc/hasp_mdns.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasp_conf.h"
diff --git a/src/sys/svc/hasp_ota.h b/src/sys/svc/hasp_ota.h
index f338ad6f..be412060 100644
--- a/src/sys/svc/hasp_ota.h
+++ b/src/sys/svc/hasp_ota.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_OTA_H
diff --git a/src/sys/svc/hasp_slave.cpp b/src/sys/svc/hasp_slave.cpp
index f055710e..227492fa 100644
--- a/src/sys/svc/hasp_slave.cpp
+++ b/src/sys/svc/hasp_slave.cpp
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#include "hasplib.h"
diff --git a/src/sys/svc/hasp_slave.h b/src/sys/svc/hasp_slave.h
index 9fd36749..0a05bc80 100644
--- a/src/sys/svc/hasp_slave.h
+++ b/src/sys/svc/hasp_slave.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TASMOTACLIENT_H
diff --git a/src/sys/svc/hasp_telnet.h b/src/sys/svc/hasp_telnet.h
index 91324c69..8f9fbd0e 100644
--- a/src/sys/svc/hasp_telnet.h
+++ b/src/sys/svc/hasp_telnet.h
@@ -1,4 +1,4 @@
-/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
+/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_TELNET_H
From ce99b815b929bc8aa400878993e6c223c481111d Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Feb 2024 01:17:07 +0100
Subject: [PATCH 128/135] Remove double quotes #637
---
src/hasp/hasp_event.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index 62b32dc9..0b52e91b 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -296,10 +296,10 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\",\"tag\":%s}"), eventname,
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":%s,\"tag\":%s}"), eventname,
val, serialized_text, tag);
else
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), eventname, val,
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":%s}"), eventname, val,
serialized_text);
}
event_send_object_data(obj, data);
From 82a382ad57638cfa8184ceb30b4ae7b2373b7dec Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Feb 2024 21:47:50 +0100
Subject: [PATCH 129/135] Fix Guition ESP32-S3-4848S040
---
platformio_override-template.ini | 2 +-
user_setups/esp32s3/esp32-s3-4848S040.ini | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index f746bb26..a267bd8b 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -39,6 +39,7 @@ extra_default_envs =
; esp32-one_st7796
; esp32-s3-4827s043c_16MB
; esp32-s3-4827s043r_16MB
+ ; esp32-s3-4848S040_16MB
; esp32-s3-8048s043c_16MB
; esp32-touchdown
; freetouchdeck_4MB
@@ -77,7 +78,6 @@ extra_default_envs =
; wt-86-32-3zw1
; yeacreate-nscreen32
; wz2432r028
- ; esp32-s3-4848S040
;endregion
;region -- Define your local COM ports for each environment ---
diff --git a/user_setups/esp32s3/esp32-s3-4848S040.ini b/user_setups/esp32s3/esp32-s3-4848S040.ini
index db5a5b6e..c82bf4ce 100644
--- a/user_setups/esp32s3/esp32-s3-4848S040.ini
+++ b/user_setups/esp32s3/esp32-s3-4848S040.ini
@@ -5,7 +5,7 @@
; - gt911 touch controller ;
;***************************************************;
-[esp32-s3-4848S040]
+[esp32-s3-4848s040]
extends = arduino_esp32s3_v2
board = esp32-s3-devkitc-1
board_build.arduino.memory_type = qio_opi
@@ -82,5 +82,5 @@ lib_deps =
${arduinogfx.lib_deps}
${goodix.lib_deps}
-[env:esp32-s3-4848S040]
-extends = esp32-s3-4848S040, flash_16mb
\ No newline at end of file
+[env:esp32-s3-4848s040_16MB]
+extends = esp32-s3-4848s040, flash_16mb
\ No newline at end of file
From 677e8cc1e707b69c9ad8d177ee2d386e3d713cb8 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Feb 2024 21:52:27 +0100
Subject: [PATCH 130/135] Update Guition
---
.github/workflows/build.yaml | 4 ++--
user_setups/esp32s3/esp32-s3-4848S040.ini | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 93ab81f7..4e250b1b 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -34,6 +34,8 @@ jobs:
env: "esp32-terminal-rgb_16MB -e esp32-terminal-spi_16MB"
- out: globalsecurity
env: gs-t3e_16MB
+ - out: guition
+ env: esp32-s3-4848s040_16MB
- out: lanbon
env: lanbon_l8
- out: lilygo-ttgo
@@ -56,8 +58,6 @@ jobs:
env: "wt32-sc01_4MB -e wt32-sc01_16MB -e wt-86-32-3zw1 -e wt32-sc01-plus_8MB -e wt32-sc01-plus_16MB"
- out: yeacreate
env: yeacreate-nscreen32
- - out: guition
- env: esp32-s3-4848S040
steps:
- uses: actions/checkout@v4
diff --git a/user_setups/esp32s3/esp32-s3-4848S040.ini b/user_setups/esp32s3/esp32-s3-4848S040.ini
index c82bf4ce..a07a6bb3 100644
--- a/user_setups/esp32s3/esp32-s3-4848S040.ini
+++ b/user_setups/esp32s3/esp32-s3-4848S040.ini
@@ -1,5 +1,5 @@
;***************************************************;
-; Generic T3E with TFT 3.95" ;
+; Generic Guition with TFT 3.95" ;
; - Custom esp32-s3 board ;
; - st7701s TFT ;
; - gt911 touch controller ;
From e1e2ff3833f86dd0df2535661d73d53656dcf7e0 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 27 Feb 2024 00:06:46 +0100
Subject: [PATCH 131/135] Add esp32-2432s028r-st7789_4MB
---
.github/workflows/build.yaml | 2 +-
user_setups/esp32/esp32-2832s028.ini | 30 ++++++++++++++++++++++++++--
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 4e250b1b..80d8c4ab 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -51,7 +51,7 @@ jobs:
- out: seeed-studios
env: "sensecap-indicator-d1_8MB"
- out: sunton
- env: "esp32-2432s028r_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB"
+ env: "esp32-2432s028r_4MB -e esp32-2432s028r-st7789_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB"
- out: waveshare
env: "esp32-one_ili9486 -e esp32-one_st7796"
- out: wireless-tag
diff --git a/user_setups/esp32/esp32-2832s028.ini b/user_setups/esp32/esp32-2832s028.ini
index c9a96cc8..5cc2802a 100644
--- a/user_setups/esp32/esp32-2832s028.ini
+++ b/user_setups/esp32/esp32-2832s028.ini
@@ -16,7 +16,6 @@ build_flags =
;region -- TFT_eSPI build options ------------------------
; -D USER_SETUP_LOADED=1
-D LGFX_USE_V1=1
- -D ILI9341_DRIVER=1
-D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
-D TFT_WIDTH=240
-D TFT_HEIGHT=320
@@ -28,7 +27,6 @@ build_flags =
-D TFT_MISO=12
-D TFT_BCKL=21
-D SUPPORT_TRANSACTIONS
- -D SPI_FREQUENCY=55000000
-D SPI_READ_FREQUENCY=20000000
-D TOUCH_OFFSET_ROTATION=0 ; 1=swap xy, 2=invert x, 4=inverty
@@ -47,6 +45,7 @@ lib_deps =
extends = esp32-2432s028r, flash_4mb
build_flags =
${esp32-2432s028r.build_flags}
+ -D ILI9341_DRIVER=1
-D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
-D HASP_USE_LGFX_TOUCH=1
-D TOUCH_CS=33
@@ -56,6 +55,33 @@ build_flags =
-D TOUCH_SDA=-1
-D TOUCH_SCL=-1
-D TOUCH_IRQ=36
+ -D SPI_FREQUENCY=55000000
+ -D SPI_TOUCH_FREQUENCY=2500000
+
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
+
+lib_deps =
+ ${esp32-2432s028r.lib_deps}
+ ;${tft_espi.lib_deps}
+ ${lovyangfx.lib_deps}
+ ;${goodix.lib_deps}
+
+[env:esp32-2432s028r-st7789_4MB]
+extends = esp32-2432s028r, flash_4mb
+build_flags =
+ ${esp32-2432s028r.build_flags}
+ -D ST7789_DRIVER=1
+ -D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
+ -D HASP_USE_LGFX_TOUCH=1
+ -D TOUCH_CS=33
+ -D TOUCH_SCLK=25
+ -D TOUCH_MOSI=32
+ -D TOUCH_MISO=39
+ -D TOUCH_SDA=-1
+ -D TOUCH_SCL=-1
+ -D TOUCH_IRQ=36
+ -D SPI_FREQUENCY=24000000
-D SPI_TOUCH_FREQUENCY=2500000
; -- Debugging options -----------------------------
From 5dc9d48c7ec08cebf6d6dd7fab6760a01afab69e Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 27 Feb 2024 23:54:55 +0100
Subject: [PATCH 132/135] Add esp32-2432s028r-ili9342_4MB
---
.github/workflows/build.yaml | 2 +-
src/drv/tft/tft_driver_lovyangfx.cpp | 27 +++++++++++++++++----------
user_setups/esp32/esp32-2832s028.ini | 28 ++++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 80d8c4ab..6e56959c 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -51,7 +51,7 @@ jobs:
- out: seeed-studios
env: "sensecap-indicator-d1_8MB"
- out: sunton
- env: "esp32-2432s028r_4MB -e esp32-2432s028r-st7789_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB"
+ env: "esp32-2432s028r_4MB -e esp32-2432s028r-ili9342_4MB -e esp32-2432s028r-st7789_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB"
- out: waveshare
env: "esp32-one_ili9486 -e esp32-one_st7796"
- out: wireless-tag
diff --git a/src/drv/tft/tft_driver_lovyangfx.cpp b/src/drv/tft/tft_driver_lovyangfx.cpp
index e4f73ea4..9d6d9a6a 100644
--- a/src/drv/tft/tft_driver_lovyangfx.cpp
+++ b/src/drv/tft/tft_driver_lovyangfx.cpp
@@ -187,7 +187,7 @@ static lgfx::Bus_SPI* init_spi_bus(Preferences* prefs)
static void configure_panel(lgfx::Panel_Device* panel, Preferences* prefs)
{
- auto cfg = panel->config(); // Get the structure for display panel settings.
+ auto cfg = panel->config(); // Get the structure for display panel settings.
cfg.pin_cs = prefs->getInt("cs", TFT_CS); // CS required
cfg.pin_rst = prefs->getInt("rst", TFT_RST); // RST sum development board RST linkage
@@ -201,27 +201,27 @@ static void configure_panel(lgfx::Panel_Device* panel, Preferences* prefs)
cfg.memory_width = prefs->getUInt("memory_width", cfg.panel_width); // Maximum width supported by driver IC
cfg.memory_height = prefs->getUInt("memory_height", cfg.panel_height); // Maximum height supported by driver IC
- cfg.offset_x = prefs->getUInt("offset_x", 0); // Amount of offset in the X direction of the panel
- cfg.offset_y = prefs->getUInt("offset_y", 0); // Amount of offset in the Y direction of the panel
+ cfg.offset_x = prefs->getUInt("offset_x", 0); // Amount of offset in the X direction of the panel
+ cfg.offset_y = prefs->getUInt("offset_y", 0); // Amount of offset in the Y direction of the panel
cfg.offset_rotation =
- prefs->getUInt("offset_rotation", TFT_OFFSET_ROTATION); // Offset of the rotation 0 ~ 7 (4 ~ 7 is upside down)
+ prefs->getUInt("offset_rotation", TFT_OFFSET_ROTATION); // Offset of the rotation 0 ~ 7 (4 ~ 7 is upside down)
cfg.dummy_read_pixel = prefs->getUInt("dummy_read_pixel", 8); // Number of dummy read bits before pixel read
cfg.dummy_read_bits =
prefs->getUInt("dummy_read_bits", 1); // bits of dummy read before reading data other than pixels
cfg.readable = prefs->getBool("readable", false); // true if data can be read
-#ifdef INVERT_COLORS // This is configurable un Web UI
+#ifdef INVERT_COLORS // This is configurable un Web UI
cfg.invert =
prefs->getBool("invert", INVERT_COLORS != 0); // true if the light and darkness of the panel is reversed
#else
- cfg.invert = prefs->getBool("invert", false); // true if the light and darkness of the panel is reversed
+ cfg.invert = prefs->getBool("invert", false); // true if the light and darkness of the panel is reversed
#endif
#ifdef TFT_RGB_ORDER
cfg.rgb_order =
prefs->getBool("rgb_order", TFT_RGB_ORDER != 0); // true if the red and blue of the panel are swapped
#else
- cfg.rgb_order = prefs->getBool("rgb_order", false); // true if the red and blue of the panel are swapped
+ cfg.rgb_order = prefs->getBool("rgb_order", false); // true if the red and blue of the panel are swapped
#endif
bool dlen_16bit = false;
@@ -453,7 +453,7 @@ lgfx::ITouch* _init_touch(Preferences* preferences)
touch->config(cfg);
return touch;
}
-#endif
+#endif
#endif // HASP_USE_LGFX_TOUCH
@@ -592,7 +592,7 @@ void LovyanGfx::init(int w, int h)
lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, 0x12, 0x04, ~0, axp_i2c_freq); // LDO2 enable
lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, 0x92, 0x00, 0xF8,
axp_i2c_freq); // GPIO1 OpenDrain (M5Tough TOUCH)
- lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, 0x95, 0x84, 0x72, axp_i2c_freq); // GPIO4 enable
+ lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, 0x95, 0x84, 0x72, axp_i2c_freq); // GPIO4 enable
if(/*use_reset*/ true) {
lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, 0x96, 0, ~0x02, axp_i2c_freq); // GPIO4 LOW (LCD RST)
lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, 0x94, 0, ~0x02,
@@ -639,7 +639,14 @@ void LovyanGfx::init(int w, int h)
_panel_instance->setLight(new Light_M5Tough());
#elif defined(ESP32_2432S028R)
+
+#if defined(ILI9341_DRIVER)
auto _panel_instance = new lgfx::Panel_ILI9341();
+#elif defined(ILI9342_DRIVER)
+ auto _panel_instance = new lgfx::Panel_ILI9342();
+#elif defined(ST7789_DRIVER)
+ auto _panel_instance = new lgfx::Panel_ST7789();
+#endif
auto _bus_instance = new lgfx::Bus_SPI();
auto _touch_instance = new lgfx::Touch_XPT2046();
@@ -675,7 +682,7 @@ void LovyanGfx::init(int w, int h)
cfg.dummy_read_pixel = 8;
cfg.dummy_read_bits = 1;
cfg.readable = true;
- cfg.invert = false;
+ cfg.invert = INVERT_COLORS;
cfg.rgb_order = false;
cfg.dlen_16bit = false;
cfg.bus_shared = false;
diff --git a/user_setups/esp32/esp32-2832s028.ini b/user_setups/esp32/esp32-2832s028.ini
index 5cc2802a..086a9a3c 100644
--- a/user_setups/esp32/esp32-2832s028.ini
+++ b/user_setups/esp32/esp32-2832s028.ini
@@ -92,3 +92,31 @@ lib_deps =
;${tft_espi.lib_deps}
${lovyangfx.lib_deps}
;${goodix.lib_deps}
+
+
+[env:esp32-2432s028r-ili9342_4MB]
+extends = esp32-2432s028r, flash_4mb
+build_flags =
+ ${esp32-2432s028r.build_flags}
+ -D ILI9342_DRIVER=1
+ -D INVERT_COLORS=1
+ -D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
+ -D HASP_USE_LGFX_TOUCH=1
+ -D TOUCH_CS=33
+ -D TOUCH_SCLK=25
+ -D TOUCH_MOSI=32
+ -D TOUCH_MISO=39
+ -D TOUCH_SDA=-1
+ -D TOUCH_SCL=-1
+ -D TOUCH_IRQ=36
+ -D SPI_FREQUENCY=55000000
+ -D SPI_TOUCH_FREQUENCY=2500000
+
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
+
+lib_deps =
+ ${esp32-2432s028r.lib_deps}
+ ;${tft_espi.lib_deps}
+ ${lovyangfx.lib_deps}
+ ;${goodix.lib_deps}
From 50817f057e6f7f07a7000cee0c1fa873b2d65a79 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Wed, 28 Feb 2024 00:11:58 +0100
Subject: [PATCH 133/135] Add esp32-2432s028r-ili9342_4MB
---
user_setups/esp32/{esp32-2832s028.ini => esp32-2432s028.ini} | 2 ++
1 file changed, 2 insertions(+)
rename user_setups/esp32/{esp32-2832s028.ini => esp32-2432s028.ini} (98%)
diff --git a/user_setups/esp32/esp32-2832s028.ini b/user_setups/esp32/esp32-2432s028.ini
similarity index 98%
rename from user_setups/esp32/esp32-2832s028.ini
rename to user_setups/esp32/esp32-2432s028.ini
index 086a9a3c..8c1cee0a 100644
--- a/user_setups/esp32/esp32-2832s028.ini
+++ b/user_setups/esp32/esp32-2432s028.ini
@@ -46,6 +46,7 @@ extends = esp32-2432s028r, flash_4mb
build_flags =
${esp32-2432s028r.build_flags}
-D ILI9341_DRIVER=1
+ -D INVERT_COLORS=0
-D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
-D HASP_USE_LGFX_TOUCH=1
-D TOUCH_CS=33
@@ -72,6 +73,7 @@ extends = esp32-2432s028r, flash_4mb
build_flags =
${esp32-2432s028r.build_flags}
-D ST7789_DRIVER=1
+ -D INVERT_COLORS=0
-D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
-D HASP_USE_LGFX_TOUCH=1
-D TOUCH_CS=33
From 006d4ffb3ff38cb9f7c9218587d57b7de323149b Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Wed, 28 Feb 2024 01:54:46 +0100
Subject: [PATCH 134/135] Rotate screen for ili9342 build #544
---
user_setups/esp32/esp32-2432s028.ini | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/user_setups/esp32/esp32-2432s028.ini b/user_setups/esp32/esp32-2432s028.ini
index 8c1cee0a..338e60b2 100644
--- a/user_setups/esp32/esp32-2432s028.ini
+++ b/user_setups/esp32/esp32-2432s028.ini
@@ -16,9 +16,6 @@ build_flags =
;region -- TFT_eSPI build options ------------------------
; -D USER_SETUP_LOADED=1
-D LGFX_USE_V1=1
- -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
- -D TFT_WIDTH=240
- -D TFT_HEIGHT=320
-D TFT_RST=-1
-D TFT_SCLK=14
-D TFT_DC=2
@@ -47,6 +44,9 @@ build_flags =
${esp32-2432s028r.build_flags}
-D ILI9341_DRIVER=1
-D INVERT_COLORS=0
+ -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=320
-D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
-D HASP_USE_LGFX_TOUCH=1
-D TOUCH_CS=33
@@ -74,6 +74,9 @@ build_flags =
${esp32-2432s028r.build_flags}
-D ST7789_DRIVER=1
-D INVERT_COLORS=0
+ -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=320
-D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
-D HASP_USE_LGFX_TOUCH=1
-D TOUCH_CS=33
@@ -102,6 +105,9 @@ build_flags =
${esp32-2432s028r.build_flags}
-D ILI9342_DRIVER=1
-D INVERT_COLORS=1
+ -D TFT_ROTATION=4 ; 0=0, 1=90, 2=180 or 3=270 degree
+ -D TFT_WIDTH=320
+ -D TFT_HEIGHT=240
-D TOUCH_DRIVER=0x2046 ; XPT2606 Resistive touch panel driver
-D HASP_USE_LGFX_TOUCH=1
-D TOUCH_CS=33
From ded1d3e4a4547ed5c57b0d915a08a9e0273d70c3 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 29 Feb 2024 21:29:42 +0100
Subject: [PATCH 135/135] Add esp32-2432s032c_4MB
---
.github/workflows/build.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 6e56959c..55fe197d 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -51,7 +51,7 @@ jobs:
- out: seeed-studios
env: "sensecap-indicator-d1_8MB"
- out: sunton
- env: "esp32-2432s028r_4MB -e esp32-2432s028r-ili9342_4MB -e esp32-2432s028r-st7789_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB"
+ env: "esp32-2432s028r_4MB -e esp32-2432s028r-ili9342_4MB -e esp32-2432s032c_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB"
- out: waveshare
env: "esp32-one_ili9486 -e esp32-one_st7796"
- out: wireless-tag