check image before uploading
This commit is contained in:
parent
32ee425a5a
commit
d3e1e9b3e8
|
@ -334,4 +334,7 @@ body {
|
||||||
background-color: blue;
|
background-color: blue;
|
||||||
width: 0px;
|
width: 0px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
|
.error{
|
||||||
|
color: red;
|
||||||
}
|
}
|
|
@ -88,6 +88,10 @@
|
||||||
<span class="label">New Firmware</span>
|
<span class="label">New Firmware</span>
|
||||||
<input type="file" name="file1" id="uploadFile">
|
<input type="file" name="file1" id="uploadFile">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span class="label"></span>
|
||||||
|
<span id="imageProperties" class="value"></span>
|
||||||
|
</div>
|
||||||
<div id="uploadProgress">
|
<div id="uploadProgress">
|
||||||
<div id="uploadDone"></div>
|
<div id="uploadDone"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
178
web/index.js
178
web/index.js
|
@ -1453,54 +1453,125 @@ function uploadBin(){
|
||||||
let progressEl=document.getElementById("uploadDone");
|
let progressEl=document.getElementById("uploadDone");
|
||||||
if (! el) return;
|
if (! el) return;
|
||||||
if ( el.files.length < 1) return;
|
if ( el.files.length < 1) return;
|
||||||
ensurePass()
|
let file=el.files[0];
|
||||||
.then (function(hash){
|
checkImageFile(file)
|
||||||
let file=el.files[0];
|
.then(function (result) {
|
||||||
let len=file.size;
|
let currentType;
|
||||||
let req = new XMLHttpRequest();
|
let currentVersion;
|
||||||
req.onloadend=function(){
|
forEl('.status-version', function (el) { currentVersion = el.textContent });
|
||||||
let result="unknown error";
|
forEl('.status-fwtype', function (el) { currentType = el.textContent });
|
||||||
try{
|
let confirmText = 'Ready to update firmware?\n';
|
||||||
let jresult=JSON.parse(req.responseText);
|
if (currentType != result.fwtype) {
|
||||||
if (jresult.status == 'OK'){
|
confirmText += "WARNING: image has different type: " + result.fwtype + "\n";
|
||||||
result='';
|
confirmText += "** Really update anyway? - device can become unusable **";
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
if (jresult.status) {
|
if (currentVersion == result.version) {
|
||||||
result=jresult.status;
|
confirmText += "WARNING: image has the same version as current " + result.version;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
confirmText += "version in image: " + result.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!confirm(confirmText)) return;
|
||||||
|
ensurePass()
|
||||||
|
.then(function (hash) {
|
||||||
|
let len = file.size;
|
||||||
|
let req = new XMLHttpRequest();
|
||||||
|
req.onloadend = function () {
|
||||||
|
let result = "unknown error";
|
||||||
|
try {
|
||||||
|
let jresult = JSON.parse(req.responseText);
|
||||||
|
if (jresult.status == 'OK') {
|
||||||
|
result = '';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (jresult.status) {
|
||||||
|
result = jresult.status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
result = "Error " + req.status;
|
||||||
|
}
|
||||||
|
if (progressEl) {
|
||||||
|
progressEl.style.width = 0;
|
||||||
|
}
|
||||||
|
if (!result) {
|
||||||
|
alertRestart();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert("update error: " + result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (e){
|
req.onerror = function (e) {
|
||||||
result="Error "+req.status;
|
alert("unable to upload: " + e);
|
||||||
}
|
|
||||||
if (progressEl){
|
|
||||||
progressEl.style.width=0;
|
|
||||||
}
|
|
||||||
if (! result){
|
|
||||||
alertRestart();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
alert("update error: "+result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.onerror=function(e){
|
|
||||||
alert("unable to upload: "+e);
|
|
||||||
}
|
|
||||||
if (progressEl){
|
|
||||||
progressEl.style.width=0;
|
|
||||||
req.upload.onprogress=function(ev){
|
|
||||||
if (ev.lengthComputable){
|
|
||||||
let percent=100*ev.loaded/ev.total;
|
|
||||||
progressEl.style.width=percent+"%";
|
|
||||||
}
|
}
|
||||||
}
|
if (progressEl) {
|
||||||
}
|
progressEl.style.width = 0;
|
||||||
let formData = new FormData();
|
req.upload.onprogress = function (ev) {
|
||||||
formData.append("file1", el.files[0]);
|
if (ev.lengthComputable) {
|
||||||
req.open("POST", '/api/update?_hash='+encodeURIComponent(hash));
|
let percent = 100 * ev.loaded / ev.total;
|
||||||
req.send(formData);
|
progressEl.style.width = percent + "%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append("file1", el.files[0]);
|
||||||
|
req.open("POST", '/api/update?_hash=' + encodeURIComponent(hash));
|
||||||
|
req.send(formData);
|
||||||
|
})
|
||||||
|
.catch(function (e) { });
|
||||||
})
|
})
|
||||||
.catch(function(e){});
|
.catch(function (e) {
|
||||||
|
alert("This file is an invalid image file:\n" + e);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let HDROFFSET=288;
|
||||||
|
let VERSIONOFFSET=16;
|
||||||
|
let NAMEOFFSET=48;
|
||||||
|
let MINSIZE=HDROFFSET+NAMEOFFSET+32;
|
||||||
|
let imageCheckBytes={
|
||||||
|
0: 0xe9, //image magic
|
||||||
|
288: 0x32, //app header magic
|
||||||
|
289: 0x54,
|
||||||
|
290: 0xcd,
|
||||||
|
291: 0xab
|
||||||
|
};
|
||||||
|
function decodeFromBuffer(buffer,start,length){
|
||||||
|
while (length > 0 && buffer[start+length-1] == 0){
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
if (length <= 0) return "";
|
||||||
|
let decoder=new TextDecoder();
|
||||||
|
let rt=decoder.decode(buffer.slice(
|
||||||
|
start,
|
||||||
|
start+length));
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
function checkImageFile(file){
|
||||||
|
return new Promise(function(resolve,reject){
|
||||||
|
if (! file) reject("no file");
|
||||||
|
if (file.size < MINSIZE) reject("file is too small");
|
||||||
|
let slice=file.slice(0,MINSIZE);
|
||||||
|
let reader=new FileReader();
|
||||||
|
reader.addEventListener('load',function(e){
|
||||||
|
let content=new Uint8Array(e.target.result);
|
||||||
|
for (let idx in imageCheckBytes){
|
||||||
|
if (content[idx] != imageCheckBytes[idx] ){
|
||||||
|
reject("missing magic byte at position "+idx+", expected "+
|
||||||
|
imageCheckBytes[idx]+", got "+content[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let version=decodeFromBuffer(content,HDROFFSET+VERSIONOFFSET,32);
|
||||||
|
let fwtype=decodeFromBuffer(content,HDROFFSET+NAMEOFFSET,32);
|
||||||
|
let rt={
|
||||||
|
fwtype:fwtype,
|
||||||
|
version: version,
|
||||||
|
};
|
||||||
|
resolve(rt);
|
||||||
|
});
|
||||||
|
reader.readAsArrayBuffer(slice);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
window.setInterval(update, 1000);
|
window.setInterval(update, 1000);
|
||||||
window.setInterval(function () {
|
window.setInterval(function () {
|
||||||
|
@ -1550,4 +1621,23 @@ window.addEventListener('load', function () {
|
||||||
even=!even;
|
even=!even;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
forEl('#uploadFile',function(el){
|
||||||
|
el.addEventListener('change',function(ev){
|
||||||
|
if (ev.target.files.length < 1) return;
|
||||||
|
let file=ev.target.files[0];
|
||||||
|
checkImageFile(file)
|
||||||
|
.then(function(res){
|
||||||
|
forEl('#imageProperties',function(iel){
|
||||||
|
iel.textContent=res.fwtype+", "+res.version;
|
||||||
|
iel.classList.remove("error");
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(function(e){
|
||||||
|
forEl('#imageProperties',function(iel){
|
||||||
|
iel.textContent=e;
|
||||||
|
iel.classList.add("error");
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
});
|
});
|
Loading…
Reference in New Issue