connectcore-demo-example: management: implement management section
Reboot and firmware update operations. https://onedigi.atlassian.net/browse/DEL-7742 Signed-off-by: Tatiana Leon <Tatiana.Leon@digi.com>
This commit is contained in:
parent
2bfc4d728d
commit
f9853cf8e1
|
|
@ -22,6 +22,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
|
import shutil
|
||||||
import signal
|
import signal
|
||||||
import socketserver
|
import socketserver
|
||||||
import stat
|
import stat
|
||||||
|
|
@ -53,6 +54,7 @@ stop_event = Event()
|
||||||
last_cpu_work = 0
|
last_cpu_work = 0
|
||||||
last_cpu_total = 0
|
last_cpu_total = 0
|
||||||
led_status = {}
|
led_status = {}
|
||||||
|
fw_process = None
|
||||||
|
|
||||||
|
|
||||||
class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
|
@ -71,8 +73,14 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
"""
|
"""
|
||||||
Override.
|
Override.
|
||||||
"""
|
"""
|
||||||
# Forbidden.
|
if re.search("/ping", self.path) is not None:
|
||||||
self._set_headers(403)
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
# Send the JSON value.
|
||||||
|
self.wfile.write("{}".encode(encoding="utf_8"))
|
||||||
|
else:
|
||||||
|
# Forbidden.
|
||||||
|
self._set_headers(403)
|
||||||
|
|
||||||
def do_POST(self):
|
def do_POST(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -101,6 +109,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
"memory_total": mem_info.get("MemTotal", NOT_AVAILABLE) if mem_info else NOT_AVAILABLE,
|
"memory_total": mem_info.get("MemTotal", NOT_AVAILABLE) if mem_info else NOT_AVAILABLE,
|
||||||
"flash_size": get_storage_size(),
|
"flash_size": get_storage_size(),
|
||||||
"video_resolution": get_video_resolution(),
|
"video_resolution": get_video_resolution(),
|
||||||
|
"fw_store_path": get_fw_store_path(),
|
||||||
"bluetooth_mac": get_bt_mac("hci0"),
|
"bluetooth_mac": get_bt_mac("hci0"),
|
||||||
"wifi_mac": read_file("/sys/class/net/wlan0/address").strip().upper() if "wlan0" in list_net_ifaces() else ZERO_MAC,
|
"wifi_mac": read_file("/sys/class/net/wlan0/address").strip().upper() if "wlan0" in list_net_ifaces() else ZERO_MAC,
|
||||||
"wifi_ip": get_iface_ip("wlan0") if "wlan0" in list_net_ifaces() else ZERO_IP,
|
"wifi_ip": get_iface_ip("wlan0") if "wlan0" in list_net_ifaces() else ZERO_IP,
|
||||||
|
|
@ -202,8 +211,9 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
# Get the JSON data.
|
# Get the JSON data.
|
||||||
data = self.rfile.read(int(self.headers["Content-Length"]))
|
data = self.rfile.read(int(self.headers["Content-Length"]))
|
||||||
path = json.loads(data.decode("utf-8")).get("directory", None)
|
path = json.loads(data.decode("utf-8")).get("directory", None)
|
||||||
|
filters = json.loads(data.decode("utf-8")).get("filters", None)
|
||||||
|
|
||||||
log.debug("List directory: %s", path)
|
log.debug("List directory: %s (filters %s)", path, filters)
|
||||||
|
|
||||||
if not path or not os.path.exists(path):
|
if not path or not os.path.exists(path):
|
||||||
error = "Invalid path" if not path else "No such file or directory"
|
error = "Invalid path" if not path else "No such file or directory"
|
||||||
|
|
@ -212,27 +222,15 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
return
|
return
|
||||||
|
|
||||||
work_path = os.path.realpath(path)
|
work_path = os.path.realpath(path)
|
||||||
content = []
|
tmp_list = []
|
||||||
|
|
||||||
dir_list = {
|
for item in os.listdir(work_path):
|
||||||
"current_dir": path,
|
|
||||||
"files": content,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add item '..'
|
|
||||||
if os.path.dirname(work_path) != work_path:
|
|
||||||
content.append({
|
|
||||||
"type": "dir",
|
|
||||||
"name": os.path.join(path, ".."),
|
|
||||||
"last_modified": os.stat(os.path.join(path, "..")),
|
|
||||||
})
|
|
||||||
|
|
||||||
dir_contents = os.listdir(work_path)
|
|
||||||
dir_contents.sort()
|
|
||||||
for item in dir_contents:
|
|
||||||
item_path = os.path.join(path, item)
|
item_path = os.path.join(path, item)
|
||||||
item_work_path = os.path.realpath(item_path)
|
item_work_path = os.path.realpath(item_path)
|
||||||
st = os.stat(item_work_path)
|
st = os.stat(item_work_path)
|
||||||
|
if not os.path.isdir(item_work_path):
|
||||||
|
if not filter_by_extension(item_path, filters):
|
||||||
|
continue
|
||||||
item = {
|
item = {
|
||||||
"type": "dir" if os.path.isdir(item_work_path) else "file",
|
"type": "dir" if os.path.isdir(item_work_path) else "file",
|
||||||
"name": os.path.join(path, item),
|
"name": os.path.join(path, item),
|
||||||
|
|
@ -240,10 +238,20 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
}
|
}
|
||||||
if os.path.isfile(item_work_path):
|
if os.path.isfile(item_work_path):
|
||||||
item["size"] = st[stat.ST_SIZE]
|
item["size"] = st[stat.ST_SIZE]
|
||||||
content.append(item)
|
tmp_list.append(item)
|
||||||
|
|
||||||
|
f_list = sorted(tmp_list, key=lambda item: (item["type"], os.path.basename(item["name"])))
|
||||||
|
|
||||||
|
# Add item '..'
|
||||||
|
if os.path.dirname(work_path) != work_path:
|
||||||
|
f_list.insert(0, {
|
||||||
|
"type": "dir",
|
||||||
|
"name": os.path.join(path, ".."),
|
||||||
|
"last_modified": os.stat(os.path.join(path, "..")),
|
||||||
|
})
|
||||||
|
|
||||||
# Send the JSON value.
|
# Send the JSON value.
|
||||||
self.wfile.write(json.dumps(dir_list).encode(encoding="utf_8"))
|
self.wfile.write(json.dumps({"current_dir": path, "files": f_list}).encode(encoding="utf_8"))
|
||||||
elif re.search("/ajax/fs_remove_file", self.path) is not None:
|
elif re.search("/ajax/fs_remove_file", self.path) is not None:
|
||||||
# Set the response headers.
|
# Set the response headers.
|
||||||
self._set_headers(200)
|
self._set_headers(200)
|
||||||
|
|
@ -326,10 +334,23 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
data = cgi.parse_multipart(self.rfile, pdict)
|
data = cgi.parse_multipart(self.rfile, pdict)
|
||||||
path = data.get("path", [None])[0]
|
path = data.get("path", [None])[0]
|
||||||
f_data = data.get("file", [bytes()])[0]
|
f_data = data.get("file", [bytes()])[0]
|
||||||
|
overwrite = data.get("overwrite", [False])[0]
|
||||||
|
error = None
|
||||||
|
|
||||||
log.debug("Upload file: %s", path)
|
log.debug("Upload file: %s (overwrite %s)", path, overwrite)
|
||||||
if not path or os.path.exists(path):
|
|
||||||
error = "Invalid path" if not path else "File already exists"
|
if not path:
|
||||||
|
error = "Invalid path"
|
||||||
|
elif os.path.exists(path):
|
||||||
|
if not overwrite:
|
||||||
|
error = "File already exists"
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
os.remove(path)
|
||||||
|
except OSError as e:
|
||||||
|
error = e.strerror
|
||||||
|
|
||||||
|
if error:
|
||||||
log.error("Error uploading file '%s': %s", path, error)
|
log.error("Error uploading file '%s': %s", path, error)
|
||||||
self.wfile.write(json.dumps({"error": error}).encode(encoding="utf_8"))
|
self.wfile.write(json.dumps({"error": error}).encode(encoding="utf_8"))
|
||||||
return
|
return
|
||||||
|
|
@ -342,6 +363,88 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
log.error("Error uploading file '%s': %s", path, e.strerror)
|
log.error("Error uploading file '%s': %s", path, e.strerror)
|
||||||
self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8"))
|
self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8"))
|
||||||
|
elif re.search("/ajax/reboot_device", self.path) is not None:
|
||||||
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
|
||||||
|
log.debug("Reboot device")
|
||||||
|
|
||||||
|
# Send the JSON value.
|
||||||
|
self.wfile.write("{}".encode(encoding="utf_8"))
|
||||||
|
|
||||||
|
exec_cmd("reboot")
|
||||||
|
elif re.search("/ajax/update_firmware", self.path) is not None:
|
||||||
|
global fw_process
|
||||||
|
|
||||||
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
# Get the JSON data.
|
||||||
|
data = self.rfile.read(int(self.headers["Content-Length"]))
|
||||||
|
path = json.loads(data.decode("utf-8")).get("file", None)
|
||||||
|
|
||||||
|
log.debug("Update firmware with file %s", path)
|
||||||
|
|
||||||
|
if is_dual_system():
|
||||||
|
cmd = "firmware-update-dual.sh %s" % path
|
||||||
|
else:
|
||||||
|
if not path.startswith(get_fw_store_path()):
|
||||||
|
# Move the package to /mnt/update
|
||||||
|
update_path = os.path.join(get_fw_store_path(), os.path.basename(path))
|
||||||
|
if os.path.exists(update_path):
|
||||||
|
os.remove(update_path)
|
||||||
|
shutil.move(path, update_path)
|
||||||
|
path = update_path
|
||||||
|
cmd = "update-firmware --reboot-timeout=1 %s" % path
|
||||||
|
|
||||||
|
log.debug("Update cmd: %s", cmd)
|
||||||
|
|
||||||
|
try:
|
||||||
|
fw_process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
shell=True, text=True)
|
||||||
|
self.wfile.write("{}".encode(encoding="utf_8"))
|
||||||
|
except OSError as e:
|
||||||
|
log.error("Error updating firmware '%s': %s", path, e.strerror)
|
||||||
|
self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8"))
|
||||||
|
fw_process = None
|
||||||
|
except subprocess.SubprocessError as e:
|
||||||
|
log.error("Error updating firmware '%s': %s", path, e.stdout)
|
||||||
|
self.wfile.write(json.dumps({"error": e.stdout}).encode(encoding="utf_8"))
|
||||||
|
fw_process = None
|
||||||
|
|
||||||
|
if is_dual_system() and os.path.exists(path):
|
||||||
|
os.remove(path)
|
||||||
|
elif re.search("/ajax/check_firmware_update_running", self.path) is not None:
|
||||||
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
|
||||||
|
is_running = (fw_process.poll() is not None) if fw_process else False
|
||||||
|
|
||||||
|
log.debug("Update firmware is running %s", is_running)
|
||||||
|
|
||||||
|
self.wfile.write(json.dumps({"update-running": is_running}).encode(encoding="utf_8"))
|
||||||
|
elif re.search("/ajax/check_firmware_update_status", self.path) is not None:
|
||||||
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
|
||||||
|
status = "successful"
|
||||||
|
if fw_process:
|
||||||
|
ret = fw_process.poll()
|
||||||
|
if ret is None:
|
||||||
|
status = "active"
|
||||||
|
elif ret != 0:
|
||||||
|
status = "failed"
|
||||||
|
|
||||||
|
log.debug("Update firmware status %s", status)
|
||||||
|
|
||||||
|
self.wfile.write(json.dumps({"status": status}).encode(encoding="utf_8"))
|
||||||
|
elif re.search("/ajax/check_firmware_update_progress", self.path) is not None:
|
||||||
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
progress = 100
|
||||||
|
if fw_process and fw_process.poll() is None:
|
||||||
|
progress = "?"
|
||||||
|
self.wfile.write(json.dumps({"progress": progress, "message": "Updating firmare"}).encode(encoding="utf_8"))
|
||||||
else:
|
else:
|
||||||
# Forbidden.
|
# Forbidden.
|
||||||
self._set_headers(403)
|
self._set_headers(403)
|
||||||
|
|
@ -368,6 +471,27 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
|
||||||
|
|
||||||
|
def filter_by_extension(name, filters):
|
||||||
|
"""
|
||||||
|
Returns whether the provided name ends with one of the provided filters.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (String): Name of the file to check.
|
||||||
|
filters (String): Comma-separated extensions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Boolean: True if the file ends with one of the filters, False otherwise.
|
||||||
|
"""
|
||||||
|
if not filters:
|
||||||
|
return True
|
||||||
|
|
||||||
|
for ext in filters.split(","):
|
||||||
|
if name.endswith(ext):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False;
|
||||||
|
|
||||||
|
|
||||||
def get_uptime():
|
def get_uptime():
|
||||||
"""
|
"""
|
||||||
Gets the system uptime in seconds.
|
Gets the system uptime in seconds.
|
||||||
|
|
@ -473,6 +597,30 @@ def get_video_resolution():
|
||||||
return res.split(":")[1].strip()
|
return res.split(":")[1].strip()
|
||||||
|
|
||||||
|
|
||||||
|
def is_dual_system():
|
||||||
|
"""
|
||||||
|
Returns wherther is a dual system.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Boolean: True for dual systems, False otherwise.
|
||||||
|
"""
|
||||||
|
res = exec_cmd("fdisk -l | grep recovery")
|
||||||
|
return res[0] != 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_fw_store_path():
|
||||||
|
"""
|
||||||
|
Returns the path to store an image before an update.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
String: Absolute path to store a firmware image.
|
||||||
|
"""
|
||||||
|
if is_dual_system():
|
||||||
|
return "/home/root/"
|
||||||
|
|
||||||
|
return "/mnt/update/"
|
||||||
|
|
||||||
|
|
||||||
def get_mem_info():
|
def get_mem_info():
|
||||||
"""
|
"""
|
||||||
Gets a dictionary with memory info.
|
Gets a dictionary with memory info.
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ Digi Demo - Management
|
||||||
|
|
||||||
<link rel="stylesheet" href="./static/css/general.css">
|
<link rel="stylesheet" href="./static/css/general.css">
|
||||||
<link rel="stylesheet" href="./static/css/toastr.css">
|
<link rel="stylesheet" href="./static/css/toastr.css">
|
||||||
<link rel="stylesheet" href="./static/css/xterm.css">
|
|
||||||
|
|
||||||
<!-- JS, Popper.js, and jQuery -->
|
<!-- JS, Popper.js, and jQuery -->
|
||||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||||
|
|
@ -41,7 +40,7 @@ Digi Demo - Management
|
||||||
<div>
|
<div>
|
||||||
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||||
</div>
|
</div>
|
||||||
<div id="device-name"></div>
|
<div id="device-name">DEY DEVICE</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
@ -55,7 +54,7 @@ Digi Demo - Management
|
||||||
|
|
||||||
<ul id="sections" data-pjax class="list-group">
|
<ul id="sections" data-pjax class="list-group">
|
||||||
<li>
|
<li>
|
||||||
<a data-pjax href="/dashboard/" class="list-group-item list-group-item-action d-flex align-items-center">
|
<a data-pjax href="index.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||||
<span class="digi-menu-icon fas fa-tachometer-alt fa-fw fa-lg mr-3"></span>
|
<span class="digi-menu-icon fas fa-tachometer-alt fa-fw fa-lg mr-3"></span>
|
||||||
<span class="menu-collapsed">Dashboard</span>
|
<span class="menu-collapsed">Dashboard</span>
|
||||||
|
|
@ -63,15 +62,15 @@ Digi Demo - Management
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a data-pjax href="/history/" class="list-group-item list-group-item-action d-flex align-items-center">
|
<a data-pjax href="multimedia.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||||
<span class="digi-menu-icon fas fa-chart-area fa-fw fa-lg mr-3"></span>
|
<span class="digi-menu-icon fas fa-film fa-fw fa-lg mr-3"></span>
|
||||||
<span class="menu-collapsed">Historical data</span>
|
<span class="menu-collapsed">Multimedia</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a data-pjax href="/management/" class="list-group-item list-group-item-action d-flex align-items-center">
|
<a data-pjax href="management.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||||
<span class="digi-menu-icon fas fa-cog fa-fw fa-lg mr-3"></span>
|
<span class="digi-menu-icon fas fa-cog fa-fw fa-lg mr-3"></span>
|
||||||
<span class="menu-collapsed">Management</span>
|
<span class="menu-collapsed">Management</span>
|
||||||
|
|
@ -99,7 +98,7 @@ Digi Demo - Management
|
||||||
<div id="pjax-container">
|
<div id="pjax-container">
|
||||||
|
|
||||||
<!-- <input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()" accept=".swu,.json,.txt"/>-->
|
<!-- <input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()" accept=".swu,.json,.txt"/>-->
|
||||||
<input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()"/>
|
<input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()" accept=".swu"/>
|
||||||
<div class="row justify-content-lg-center">
|
<div class="row justify-content-lg-center">
|
||||||
<div class="col-lg-12 col-xl-12">
|
<div class="col-lg-12 col-xl-12">
|
||||||
<div id="loading_popup" class="popup popup-loading shadow">
|
<div id="loading_popup" class="popup popup-loading shadow">
|
||||||
|
|
@ -122,6 +121,13 @@ Digi Demo - Management
|
||||||
<div id="confirm_dialog_yes_button" class="device-card-button confirm-dialog-button">Yes</div>
|
<div id="confirm_dialog_yes_button" class="device-card-button confirm-dialog-button">Yes</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="rebooted_dialog" class="popup popup-info shadow d-none">
|
||||||
|
<div class="popup-title"><p><i class="fa fa-check success-message fa-lg"></i> Device rebooted</p></div>
|
||||||
|
<div class="popup-text">Reload the page to continue.</div>
|
||||||
|
<div class="confirm-dialog-buttons-container" style="padding-top: 30px;">
|
||||||
|
<div id="reload_button" class="device-card-button confirm-dialog-button" onclick="document.location.replace('index.html')">Reload</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="loading_wrapper" class="loading-wrapper element-grayed">
|
<div id="loading_wrapper" class="loading-wrapper element-grayed">
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
@ -164,10 +170,6 @@ Digi Demo - Management
|
||||||
<span class="fas fa-upload fa-lg"></span>
|
<span class="fas fa-upload fa-lg"></span>
|
||||||
<span class="firmware-tab-text">Upload file</span>
|
<span class="firmware-tab-text">Upload file</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="firmware_tab_fileset_header" class="firmware-tab-header" onclick="showFirmwareTab(ID_FIRMWARE_TAB_FILESET)">
|
|
||||||
<span class="fas fa-database fa-lg"></span>
|
|
||||||
<span class="firmware-tab-text">Download from storage</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="firmware-tab-container">
|
<div class="firmware-tab-container">
|
||||||
<div id="firmware_tab_upload" class="firmware-tab firmware-tab-upload">
|
<div id="firmware_tab_upload" class="firmware-tab firmware-tab-upload">
|
||||||
|
|
@ -177,18 +179,6 @@ Digi Demo - Management
|
||||||
<div id="firmware_file_label" class="firmware-file-label">No file chosen</div>
|
<div id="firmware_file_label" class="firmware-file-label">No file chosen</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="firmware_tab_fileset" class="firmware-tab firmware-tab-fileset">
|
|
||||||
<div>Download and install firmware from Digi Remote Manager storage.</div>
|
|
||||||
<div class="fileset-items-header">
|
|
||||||
<div class="fileset-entry-icon"></div>
|
|
||||||
<div class="fileset-entry-name">Name</div>
|
|
||||||
<div class="fileset-entry-path">Path</div>
|
|
||||||
<div class="fileset-entry-size">Size</div>
|
|
||||||
<div class="fileset-entry-last-modified">Last modified</div>
|
|
||||||
</div>
|
|
||||||
<div id="fileset_items_container" class="fileset-items-container"></div>
|
|
||||||
<div id="refresh_fileset_button" class="device-card-button refresh-fileset-button" onclick="refreshFilesetFiles()">Refresh</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="update_firmware_progress" class="update-firmware-progress">
|
<div id="update_firmware_progress" class="update-firmware-progress">
|
||||||
<div id="update_firmware_progress_title" class="update-firmware-progress-title">Firmware update in progress...</div>
|
<div id="update_firmware_progress_title" class="update-firmware-progress-title">Firmware update in progress...</div>
|
||||||
|
|
@ -199,13 +189,61 @@ Digi Demo - Management
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="update_firmware_button" class="device-card-button update-firmware-button management-button-disabled" onclick="askUpdateFirmware()">Update Firmware</div>
|
<div id="update_firmware_button" class="device-card-button update-firmware-button management-button-disabled" onclick="askUpdateFirmware()">Update Firmware</div>
|
||||||
<div id="cancel_update_firmware_button" class="device-card-button cancel-firmware-update-button management-button-disabled" onclick="askCancelFirmwareUpdate()">Cancel update</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> <!-- card body -->
|
||||||
</div>
|
</div> <!-- card shadow -->
|
||||||
</div>
|
<div id="filesystem_panel" class="filesystem-panel">
|
||||||
</div>
|
<div class="filesystem-background"></div>
|
||||||
</div>
|
<div id="filesystem_container" class="filesystem-container">
|
||||||
|
<div id="filesystem_header" class="device-card-header">
|
||||||
|
<span class="fas fa-folder-open fa-lg mr-2"></span>
|
||||||
|
<span>Device's file system</span>
|
||||||
|
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeFileSystem()"></div>
|
||||||
|
</div>
|
||||||
|
<div id="filesystem_hover_background" class="filesystem-hover-background"></div>
|
||||||
|
<div id="filesystem_dir_name_panel" class="filesystem-dir-name-panel">
|
||||||
|
<div class="filesystem-dir-name-background"></div>
|
||||||
|
<div class="filesystem-dir-name-container">
|
||||||
|
<div class="device-card-header">
|
||||||
|
<span class="fas fa-folder-plus fa-lg mr-2"></span>
|
||||||
|
<span>Create new directory</span>
|
||||||
|
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeDirectoryNamePanel()"></div>
|
||||||
|
</div>
|
||||||
|
<div class="filesystem-dir-name-label">Enter the new directory name</div>
|
||||||
|
<input id="filesystem_directory_name" class="filesystem-dir-name-input" type="text"/>
|
||||||
|
<div id="filesystem_directory_name_error" class="filesystem-dir-name-error"></div>
|
||||||
|
<div id="filesystem_directory_name_button" class="device-card-button filesystem-dir-name-button filesystem-dir-name-button-disabled" onclick="onCreateDirectory()">Create directory</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="filesystem_toolbar" class="filesystem-toolbar">
|
||||||
|
<div class="filesystem-current-directory-container">
|
||||||
|
<div class="filesystem-current-directory-label">Current dir:</div>
|
||||||
|
<div id="current_directory" class="filesystem-current-directory"></div>
|
||||||
|
</div>
|
||||||
|
<div id="filesystem_toolbar_buttons_container" class="filesystem-toolbar-buttons-container">
|
||||||
|
<div id="filesystem_select_file_button" class="filesystem-button fas fa-bolt fa-2x" onclick="selectFirmwareFile()" title="Select firmware file"></div>
|
||||||
|
<div id="filesystem_create_directory_button" class="filesystem-button fas fa-folder-plus fa-2x" onclick="openDirectoryNamePanel()" title="Create directory"></div>
|
||||||
|
<div id="filesystem_upload_file_button" class="filesystem-button fas fa-upload fa-2x" onclick="openFileBrowser()" title="Upload file"></div>
|
||||||
|
<div id="filesystem_download_file_button" class="filesystem-button fas fa-file-download fa-2x" onclick="downloadSelectedFile()" title="Download file"></div>
|
||||||
|
<div id="filesystem_remove_file_button" class="filesystem-button fas fa-trash fa-2x" onclick="askRemoveFile()" title="Remove file"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="filesystem_items_header" class="filesystem-items-header">
|
||||||
|
<div class="filesystem-entry-icon"></div>
|
||||||
|
<div class="filesystem-entry-name">Name</div>
|
||||||
|
<div class="filesystem-entry-size">Size</div>
|
||||||
|
<div class="filesystem-entry-last-modified">Last modified</div>
|
||||||
|
</div>
|
||||||
|
<div id="filesystem_items_container" class="filesystem-items-container"></div>
|
||||||
|
<div id="filesystem_loading" class="popup shadow" style="top: 33%">
|
||||||
|
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||||
|
<div class="popup-text">Loading...</div>
|
||||||
|
</div>
|
||||||
|
</div> <!-- filesystem_container -->
|
||||||
|
</div> <!-- filesystem_panel -->
|
||||||
|
</div> <!-- loading wrapper -->
|
||||||
|
</div> <!-- col -->
|
||||||
|
</div> <!-- row justify -->
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -223,10 +261,10 @@ Digi Demo - Management
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</div>
|
</div> <!-- pjax-container -->
|
||||||
|
|
||||||
</div>
|
</div> <!-- container fluid -->
|
||||||
</div>
|
</div> <!--bg light -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
@ -252,11 +290,8 @@ Digi Demo - Management
|
||||||
<script type="text/javascript" src="./static/js/ccimx8m-nano.js"></script>
|
<script type="text/javascript" src="./static/js/ccimx8m-nano.js"></script>
|
||||||
<script type="text/javascript" src="./static/js/ccimx8x-sbc-pro.js"></script>
|
<script type="text/javascript" src="./static/js/ccimx8x-sbc-pro.js"></script>
|
||||||
<script type="text/javascript" src="./static/js/dashboard.js"></script>
|
<script type="text/javascript" src="./static/js/dashboard.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/multimedia.js"></script>
|
||||||
<script type="text/javascript" src="./static/js/management.js"></script>
|
<script type="text/javascript" src="./static/js/management.js"></script>
|
||||||
<script type="text/javascript" src="./static/js/history.js"></script>
|
|
||||||
<script type="text/javascript" src="./static/js/xterm.js"></script>
|
|
||||||
<script type="text/javascript" src="./static/js/xterm-addon-fit.js"></script>
|
|
||||||
<script type="text/javascript" src="./static/js/console.js"></script>
|
|
||||||
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
@ -298,10 +333,6 @@ Digi Demo - Management
|
||||||
|
|
||||||
// Set the selected section.
|
// Set the selected section.
|
||||||
setSelectedSection();
|
setSelectedSection();
|
||||||
|
|
||||||
// Set the name of the selected device.
|
|
||||||
$("#device-name").html("DEY device".toUpperCase());
|
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,7 @@ body {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
|
min-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup i {
|
.popup i {
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ const ID_ETHERNET_STATE = "ethernet_state";
|
||||||
const ID_FILES = "files";
|
const ID_FILES = "files";
|
||||||
const ID_FLASH_MEMORY = "flash_memory";
|
const ID_FLASH_MEMORY = "flash_memory";
|
||||||
const ID_FLASH_SIZE = "flash_size";
|
const ID_FLASH_SIZE = "flash_size";
|
||||||
|
const ID_FW_STORE_PATH = "fw_store_path";
|
||||||
const ID_HAS_ARROW = "has-arrow";
|
const ID_HAS_ARROW = "has-arrow";
|
||||||
const ID_HAS_PANEL = "has-panel";
|
const ID_HAS_PANEL = "has-panel";
|
||||||
const ID_ICON = "icon";
|
const ID_ICON = "icon";
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
// Constants.
|
// Constants.
|
||||||
const ID_CURRENT_DIRECTORY = "current_directory";
|
const ID_CURRENT_DIRECTORY = "current_directory";
|
||||||
const ID_FILE_SYSTEM_CONTAINER = "filesystem_container";
|
const ID_FILE_SYSTEM_CONTAINER = "filesystem_container";
|
||||||
|
const ID_FILE_SYSTEM_CREATE_DIR_BUTTON = "filesystem_create_directory_button";
|
||||||
const ID_FILE_SYSTEM_DIR_NAME = "filesystem_directory_name";
|
const ID_FILE_SYSTEM_DIR_NAME = "filesystem_directory_name";
|
||||||
const ID_FILE_SYSTEM_DIR_NAME_BUTTON = "filesystem_directory_name_button";
|
const ID_FILE_SYSTEM_DIR_NAME_BUTTON = "filesystem_directory_name_button";
|
||||||
const ID_FILE_SYSTEM_DIR_NAME_ERROR = "filesystem_directory_name_error";
|
const ID_FILE_SYSTEM_DIR_NAME_ERROR = "filesystem_directory_name_error";
|
||||||
|
|
@ -29,6 +30,7 @@ const ID_FILE_SYSTEM_ITEMS_HEADER = "filesystem_items_header";
|
||||||
const ID_FILE_SYSTEM_LOADING = "filesystem_loading";
|
const ID_FILE_SYSTEM_LOADING = "filesystem_loading";
|
||||||
const ID_FILE_SYSTEM_PANEL = "filesystem_panel";
|
const ID_FILE_SYSTEM_PANEL = "filesystem_panel";
|
||||||
const ID_FILE_SYSTEM_REMOVE_FILE_BUTTON = "filesystem_remove_file_button";
|
const ID_FILE_SYSTEM_REMOVE_FILE_BUTTON = "filesystem_remove_file_button";
|
||||||
|
const ID_FILE_SYSTEM_SELECT_FILE_BUTTON = "filesystem_select_file_button";
|
||||||
const ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON = "filesystem_upload_file_button";
|
const ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON = "filesystem_upload_file_button";
|
||||||
const ID_FILE_SYSTEM_TOOLBAR = "filesystem_toolbar";
|
const ID_FILE_SYSTEM_TOOLBAR = "filesystem_toolbar";
|
||||||
const ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER = "filesystem_toolbar_buttons_container";
|
const ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER = "filesystem_toolbar_buttons_container";
|
||||||
|
|
@ -52,18 +54,18 @@ const PREFIX_FS = "fs_";
|
||||||
const REGEX_DIRECTORY_NAME = '^[^\\s^\x00-\x1f\\?*:"";<>|\\/.][^\x00-\x1f\\?*:"";<>|\\/]*[^\\s^\x00-\x1f\\?*:"";<>|\\/.]+$';
|
const REGEX_DIRECTORY_NAME = '^[^\\s^\x00-\x1f\\?*:"";<>|\\/.][^\x00-\x1f\\?*:"";<>|\\/]*[^\\s^\x00-\x1f\\?*:"";<>|\\/.]+$';
|
||||||
|
|
||||||
const TEMPLATE_DIRECTORY = "" +
|
const TEMPLATE_DIRECTORY = "" +
|
||||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='listDirectory(\"{2}\")'>" +
|
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='listDirectory(\"{2}\", filters=\"{3}\")'>" +
|
||||||
" <div class='fas fa-folder fa-lg filesystem-entry-icon'></div>" +
|
" <div class='fas fa-folder fa-lg filesystem-entry-icon'></div>" +
|
||||||
" <div class='filesystem-entry-name'>{3}</div>" +
|
" <div class='filesystem-entry-name'>{4}</div>" +
|
||||||
" <div class='filesystem-entry-size'></div>" +
|
" <div class='filesystem-entry-size'></div>" +
|
||||||
" <div class='filesystem-entry-last-modified'>{4}</div>" +
|
" <div class='filesystem-entry-last-modified'>{5}</div>" +
|
||||||
"</div>";
|
"</div>";
|
||||||
const TEMPLATE_FILE = "" +
|
const TEMPLATE_FILE = "" +
|
||||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='selectFileSystemEntry(\"fs_{2}\")' ondblclick='downloadFile(\"{3}\")'>" +
|
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='selectFileSystemEntry(\"fs_{2}\", filters=\"{3}\")' ondblclick='downloadFile(\"{4}\")'>" +
|
||||||
" <div class='fas fa-file fa-lg filesystem-entry-icon'></div>" +
|
" <div class='fas fa-file fa-lg filesystem-entry-icon'></div>" +
|
||||||
" <div class='filesystem-entry-name'>{4}</div>" +
|
" <div class='filesystem-entry-name'>{5}</div>" +
|
||||||
" <div class='filesystem-entry-size'>{5}</div>" +
|
" <div class='filesystem-entry-size'>{6}</div>" +
|
||||||
" <div class='filesystem-entry-last-modified'>{6}</div>" +
|
" <div class='filesystem-entry-last-modified'>{7}</div>" +
|
||||||
"</div>";
|
"</div>";
|
||||||
|
|
||||||
const ERROR_DIR_NAME_EMPTY = "Directory name cannot be empty.";
|
const ERROR_DIR_NAME_EMPTY = "Directory name cannot be empty.";
|
||||||
|
|
@ -77,7 +79,7 @@ var selectedFileSystemEntry = null;
|
||||||
var filesystemResizeObserver = null;
|
var filesystemResizeObserver = null;
|
||||||
|
|
||||||
// Opens the file system panel.
|
// Opens the file system panel.
|
||||||
function openFileSystem() {
|
function openFileSystem(showButtons=true, filters="") {
|
||||||
// Check if the file system is showing.
|
// Check if the file system is showing.
|
||||||
if (isFileSystemShowing())
|
if (isFileSystemShowing())
|
||||||
return;
|
return;
|
||||||
|
|
@ -100,19 +102,23 @@ function openFileSystem() {
|
||||||
// Show the file system.
|
// Show the file system.
|
||||||
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
||||||
fileSystemContainer.style.visibility = "visible";
|
fileSystemContainer.style.visibility = "visible";
|
||||||
if (is_local_access()) {
|
if (!showButtons || is_local_access()) {
|
||||||
document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON).style.display = "none";
|
document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON).style.display = "none";
|
||||||
document.getElementById(ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON).style.display = "none";
|
document.getElementById(ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON).style.display = "none";
|
||||||
document.getElementById(ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER).style.width = "90px";
|
document.getElementById(ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER).style.width = "auto";
|
||||||
|
}
|
||||||
|
if (!showButtons) {
|
||||||
|
document.getElementById(ID_FILE_SYSTEM_CREATE_DIR_BUTTON).style.display = "none";
|
||||||
|
document.getElementById(ID_FILE_SYSTEM_REMOVE_FILE_BUTTON).style.display = "none";
|
||||||
}
|
}
|
||||||
// List root directory.
|
// List root directory.
|
||||||
listDirectory(ROOT_DIRECTORY);
|
listDirectory(ROOT_DIRECTORY, filters=filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the file system window is open or not.
|
// Returns whether the file system window is open or not.
|
||||||
function isFileSystemShowing() {
|
function isFileSystemShowing() {
|
||||||
// Sanity checks.
|
// Sanity checks.
|
||||||
if (!isDashboardShowing())
|
if (!isDashboardShowing() && !isManagementShowing())
|
||||||
return false;
|
return false;
|
||||||
// Initialize variables.
|
// Initialize variables.
|
||||||
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
||||||
|
|
@ -178,26 +184,63 @@ function clearFileSystemEntries() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enables/disabled the file system buttons.
|
// Enables/disabled the file system buttons.
|
||||||
function enableFileSystemButtons(enable) {
|
function enableFileSystemButtons(enable, filters="") {
|
||||||
// Initialize variables.
|
// Initialize variables.
|
||||||
var downloadButton = document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON);
|
var downloadButton = document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON);
|
||||||
var removeButton = document.getElementById(ID_FILE_SYSTEM_REMOVE_FILE_BUTTON);
|
var removeButton = document.getElementById(ID_FILE_SYSTEM_REMOVE_FILE_BUTTON);
|
||||||
|
var selectFwButton = document.getElementById(ID_FILE_SYSTEM_SELECT_FILE_BUTTON);
|
||||||
// Apply enable state.
|
// Apply enable state.
|
||||||
if (!enable) {
|
if (!enable) {
|
||||||
downloadButton.disabled = true;
|
if (removeButton) {
|
||||||
removeButton.disabled = true;
|
removeButton.disabled = true;
|
||||||
downloadButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
removeButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||||
removeButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
}
|
||||||
|
if (downloadButton) {
|
||||||
|
downloadButton.disabled = true;
|
||||||
|
downloadButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||||
|
}
|
||||||
|
if (selectFwButton) {
|
||||||
|
selectFwButton.disabled = true;
|
||||||
|
selectFwButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
downloadButton.disabled = false;
|
if (removeButton) {
|
||||||
removeButton.disabled = false;
|
removeButton.disabled = false;
|
||||||
downloadButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
removeButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||||
removeButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
}
|
||||||
|
if (downloadButton) {
|
||||||
|
downloadButton.disabled = false;
|
||||||
|
downloadButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||||
|
}
|
||||||
|
if (selectFwButton) {
|
||||||
|
enable = false;
|
||||||
|
if (filters) {
|
||||||
|
var filePath = selectedFileSystemEntry.substring(PREFIX_FS.length);
|
||||||
|
var filter_list = filters.split(",");
|
||||||
|
for (var i = 0; i < filter_list.length; i++) {
|
||||||
|
if (filePath.endsWith(filter_list[i])) {
|
||||||
|
enable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!filters || enable) {
|
||||||
|
selectFwButton.disabled = false;
|
||||||
|
selectFwButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Downloads the selected file.
|
||||||
|
function selectFirmwareFile() {
|
||||||
|
// Build file path.
|
||||||
|
var filePath = selectedFileSystemEntry.substring(PREFIX_FS.length);
|
||||||
|
firmwareFileChanged(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
// Selects the given file system entry.
|
// Selects the given file system entry.
|
||||||
function selectFileSystemEntry(entryID) {
|
function selectFileSystemEntry(entryID, filters="") {
|
||||||
// Unselect all entries.
|
// Unselect all entries.
|
||||||
unselectFileSystemEntries();
|
unselectFileSystemEntries();
|
||||||
// Set selected style to the selected device div.
|
// Set selected style to the selected device div.
|
||||||
|
|
@ -207,7 +250,7 @@ function selectFileSystemEntry(entryID) {
|
||||||
// Save selected entry.
|
// Save selected entry.
|
||||||
selectedFileSystemEntry = entryID;
|
selectedFileSystemEntry = entryID;
|
||||||
// Enable buttons.
|
// Enable buttons.
|
||||||
enableFileSystemButtons(true);
|
enableFileSystemButtons(true, filters=filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unselects all the file system entries.
|
// Unselects all the file system entries.
|
||||||
|
|
@ -227,7 +270,7 @@ function unselectFileSystemEntries() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lists the contents of the given directory.
|
// Lists the contents of the given directory.
|
||||||
function listDirectory(directory) {
|
function listDirectory(directory, filters="") {
|
||||||
// Build path.
|
// Build path.
|
||||||
var path = currentDirectory;
|
var path = currentDirectory;
|
||||||
if (path == null || currentDirectory == directory)
|
if (path == null || currentDirectory == directory)
|
||||||
|
|
@ -253,14 +296,15 @@ function listDirectory(directory) {
|
||||||
$.post(
|
$.post(
|
||||||
"http://" + getServerAddress() + "/ajax/fs_list_directory",
|
"http://" + getServerAddress() + "/ajax/fs_list_directory",
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
"directory": path
|
"directory": path,
|
||||||
|
"filters": filters,
|
||||||
}),
|
}),
|
||||||
function(data) {
|
function(data) {
|
||||||
// Process only if the file system window is showing.
|
// Process only if the file system window is showing.
|
||||||
if (!isFileSystemShowing())
|
if (!isFileSystemShowing())
|
||||||
return;
|
return;
|
||||||
// Process answer.
|
// Process answer.
|
||||||
processListDirectoryResponse(data);
|
processListDirectoryResponse(data, filters=filters);
|
||||||
}
|
}
|
||||||
).fail(function(response) {
|
).fail(function(response) {
|
||||||
// Process only if the file system window is showing.
|
// Process only if the file system window is showing.
|
||||||
|
|
@ -274,7 +318,7 @@ function listDirectory(directory) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Processes the list directory response.
|
// Processes the list directory response.
|
||||||
function processListDirectoryResponse(response) {
|
function processListDirectoryResponse(response, filters="") {
|
||||||
// Check if there was any error in the request.
|
// Check if there was any error in the request.
|
||||||
if (checkErrorResponse(response, false)) {
|
if (checkErrorResponse(response, false)) {
|
||||||
// Hide the loading status.
|
// Hide the loading status.
|
||||||
|
|
@ -307,10 +351,10 @@ function processListDirectoryResponse(response) {
|
||||||
}
|
}
|
||||||
var entryDiv = document.createElement("div");
|
var entryDiv = document.createElement("div");
|
||||||
if (entry[ID_TYPE] == FS_TYPE_FILE)
|
if (entry[ID_TYPE] == FS_TYPE_FILE)
|
||||||
entryDiv.innerHTML = TEMPLATE_FILE.format(name, name, name, name, name,
|
entryDiv.innerHTML = TEMPLATE_FILE.format(name, name, name, filters, name, name,
|
||||||
sizeToHumanRead(entry[ID_SIZE]), lastModified);
|
sizeToHumanRead(entry[ID_SIZE]), lastModified);
|
||||||
else if (entry[ID_TYPE] == FS_TYPE_DIRECTORY)
|
else if (entry[ID_TYPE] == FS_TYPE_DIRECTORY)
|
||||||
entryDiv.innerHTML = TEMPLATE_DIRECTORY.format(name, name, name, name, lastModified);
|
entryDiv.innerHTML = TEMPLATE_DIRECTORY.format(name, name, name, filters, name, lastModified);
|
||||||
if (entryDiv.innerHTML != null && entryDiv.innerHTML != "")
|
if (entryDiv.innerHTML != null && entryDiv.innerHTML != "")
|
||||||
fileSystemEntriesDiv.appendChild(entryDiv);
|
fileSystemEntriesDiv.appendChild(entryDiv);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,6 @@
|
||||||
|
|
||||||
// Constants.
|
// Constants.
|
||||||
const ID_REBOOT_BUTTON = "reboot_button";
|
const ID_REBOOT_BUTTON = "reboot_button";
|
||||||
const ID_CANCEL_FIRMWARE_UPDATE_BUTTON = "cancel_update_firmware_button";
|
|
||||||
const ID_FILESET_ITEMS_CONTAINER = "fileset_items_container";
|
|
||||||
const ID_FIRMWARE_TAB_FILESET = "firmware_tab_fileset";
|
|
||||||
const ID_FIRMWARE_TAB_FILESET_HEADER = "firmware_tab_fileset_header";
|
|
||||||
const ID_FIRMWARE_TAB_UPLOAD = "firmware_tab_upload";
|
const ID_FIRMWARE_TAB_UPLOAD = "firmware_tab_upload";
|
||||||
const ID_FIRMWARE_TAB_UPLOAD_HEADER = "firmware_tab_upload_header";
|
const ID_FIRMWARE_TAB_UPLOAD_HEADER = "firmware_tab_upload_header";
|
||||||
const ID_SELECT_FIRMWARE_BUTTON = "select_firmware_button";
|
const ID_SELECT_FIRMWARE_BUTTON = "select_firmware_button";
|
||||||
|
|
@ -35,16 +31,11 @@ const ID_UPDATE_RUNNING = "update_running";
|
||||||
const CLASS_FIRMWARE_TAB = "firmware-tab";
|
const CLASS_FIRMWARE_TAB = "firmware-tab";
|
||||||
const CLASS_FIRMWARE_TAB_HEADER = "firmware-tab-header";
|
const CLASS_FIRMWARE_TAB_HEADER = "firmware-tab-header";
|
||||||
const CLASS_FIRMWARE_TAB_HEADER_ACTIVE = "firmware-tab-header-active";
|
const CLASS_FIRMWARE_TAB_HEADER_ACTIVE = "firmware-tab-header-active";
|
||||||
const CLASS_FILESET_ENTRY_NAME = "fileset-entry-name";
|
|
||||||
const CLASS_FILESET_ENTRY_PATH = "fileset-entry-path";
|
|
||||||
const CLASS_FILESET_ENTRY_SELECTED = "fileset-entry-selected";
|
|
||||||
const CLASS_MANAGEMENT_BUTTON_DISABLED = "management-button-disabled";
|
const CLASS_MANAGEMENT_BUTTON_DISABLED = "management-button-disabled";
|
||||||
const CLASS_PROGRESS_BAR_ERROR = "update-firmware-progress-bar-error";
|
const CLASS_PROGRESS_BAR_ERROR = "update-firmware-progress-bar-error";
|
||||||
const CLASS_PROGRESS_BAR_INFO = "update-firmware-progress-bar-info";
|
const CLASS_PROGRESS_BAR_INFO = "update-firmware-progress-bar-info";
|
||||||
const CLASS_PROGRESS_BAR_SUCCESS = "update-firmware-progress-bar-success";
|
const CLASS_PROGRESS_BAR_SUCCESS = "update-firmware-progress-bar-success";
|
||||||
const CLASS_SAVE_BUTTON_DISABLED = "system-monitor-save-disabled";
|
|
||||||
|
|
||||||
const TITLE_CONFIRM_CANCEL_UPDATE = "Cancel firmware update";
|
|
||||||
const TITLE_CONFIRM_FIRMWARE_UPDATE = "Confirm firmware update";
|
const TITLE_CONFIRM_FIRMWARE_UPDATE = "Confirm firmware update";
|
||||||
const TITLE_CONFIRM_REBOOT = "Confirm reboot";
|
const TITLE_CONFIRM_REBOOT = "Confirm reboot";
|
||||||
const TITLE_DEVICE_REBOOTING = "Device Rebooting";
|
const TITLE_DEVICE_REBOOTING = "Device Rebooting";
|
||||||
|
|
@ -52,9 +43,7 @@ const TITLE_FIRMWARE_UPDATE_ERROR = "Firmware update failed!";
|
||||||
const TITLE_FIRMWARE_UPDATE_IN_PROGRESS = "Firmware update in progress...";
|
const TITLE_FIRMWARE_UPDATE_IN_PROGRESS = "Firmware update in progress...";
|
||||||
const TITLE_FIRMWARE_UPDATE_SUCCESS = "Firmware update succeeded!";
|
const TITLE_FIRMWARE_UPDATE_SUCCESS = "Firmware update succeeded!";
|
||||||
|
|
||||||
const MESSAGE_CANCELING_FIRMWARE_UPDATE = "Canceling firmware update...";
|
|
||||||
const MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS = "Checking firmware update...";
|
const MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS = "Checking firmware update...";
|
||||||
const MESSAGE_CONFIRM_CANCEL_UPDATE = "This action will cancel the ongoing firmware update process. Do you want to continue?";
|
|
||||||
const MESSAGE_CONFIRM_FIRMWARE_UPDATE = "This action will update the device firmware. Do you want to continue?";
|
const MESSAGE_CONFIRM_FIRMWARE_UPDATE = "This action will update the device firmware. Do you want to continue?";
|
||||||
const MESSAGE_CONFIRM_REBOOT = "This action will reboot the device and connection will be lost. Do you want to continue?";
|
const MESSAGE_CONFIRM_REBOOT = "This action will reboot the device and connection will be lost. Do you want to continue?";
|
||||||
const MESSAGE_DEVICE_REBOOTING = "The device is rebooting. Please wait...";
|
const MESSAGE_DEVICE_REBOOTING = "The device is rebooting. Please wait...";
|
||||||
|
|
@ -68,23 +57,10 @@ const MESSAGE_UPLOAD_COMPLETE = "Firmware file upload complete";
|
||||||
const MESSAGE_UPDATING_FIRMWARE = "Updating firmware...";
|
const MESSAGE_UPDATING_FIRMWARE = "Updating firmware...";
|
||||||
const MESSAGE_UPLOADING_FIRMWARE = "Uploading firmware file...";
|
const MESSAGE_UPLOADING_FIRMWARE = "Uploading firmware file...";
|
||||||
|
|
||||||
const REGEX_INTEGER = '^[0-9]+$';
|
|
||||||
|
|
||||||
const UPDATE_ERROR = "error";
|
const UPDATE_ERROR = "error";
|
||||||
const UPDATE_INFO = "info";
|
const UPDATE_INFO = "info";
|
||||||
const UPDATE_SUCCESS = "success";
|
const UPDATE_SUCCESS = "success";
|
||||||
|
|
||||||
const DEMO_FILE_SET = "ConnectCoreDemo";
|
|
||||||
|
|
||||||
const TEMPLATE_FILESET_FILE = "" +
|
|
||||||
"<div id='file_{0}' class='fileset-entry' title='{1}' onclick='selectFilesetEntry(\"file_{2}\")'>" +
|
|
||||||
" <div class='fas fa-file fa-lg fileset-entry-icon'></div>" +
|
|
||||||
" <div class='fileset-entry-name'>{3}</div>" +
|
|
||||||
" <div class='fileset-entry-path'>{4}</div>" +
|
|
||||||
" <div class='fileset-entry-size'>{5}</div>" +
|
|
||||||
" <div class='fileset-entry-last-modified'>{6}</div>" +
|
|
||||||
"</div>";
|
|
||||||
|
|
||||||
const FIRMWARE_UPDATE_CHECK_INTERVAL = 10000;
|
const FIRMWARE_UPDATE_CHECK_INTERVAL = 10000;
|
||||||
|
|
||||||
// Variables.
|
// Variables.
|
||||||
|
|
@ -93,10 +69,8 @@ var managementInfoRead = false;
|
||||||
var deviceRebooting = false;
|
var deviceRebooting = false;
|
||||||
var updatingFirmware = false;
|
var updatingFirmware = false;
|
||||||
var firmwareUpdateTimer = null;
|
var firmwareUpdateTimer = null;
|
||||||
var uploadProgressSocket = null;
|
|
||||||
var uploadFirmwareAjaxRequest = null;
|
var uploadFirmwareAjaxRequest = null;
|
||||||
var filesLoaded = false;
|
var fwStorageDir = "/home/root/";
|
||||||
var selectedFilesetEntry = null;
|
|
||||||
|
|
||||||
// Initializes the management page.
|
// Initializes the management page.
|
||||||
function initializeManagementPage() {
|
function initializeManagementPage() {
|
||||||
|
|
@ -124,10 +98,14 @@ function readDeviceInfoManagement() {
|
||||||
showLoadingPopup(true, MESSAGE_LOADING_INFORMATION);
|
showLoadingPopup(true, MESSAGE_LOADING_INFORMATION);
|
||||||
// Send request to retrieve device information.
|
// Send request to retrieve device information.
|
||||||
$.post(
|
$.post(
|
||||||
"../ajax/get_device_info",
|
"http://" + getServerAddress() + "/ajax/get_device_info",
|
||||||
function(data) {
|
function(data) {
|
||||||
|
readingManagementInfo = false;
|
||||||
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
return;
|
return;
|
||||||
|
// Hide the loading panel.
|
||||||
|
showLoadingPopup(false);
|
||||||
// Process device information answer.
|
// Process device information answer.
|
||||||
processDeviceInfoManagementResponse(data);
|
processDeviceInfoManagementResponse(data);
|
||||||
}
|
}
|
||||||
|
|
@ -150,15 +128,18 @@ function processDeviceInfoManagementResponse(response) {
|
||||||
if (!checkErrorResponse(response, false)) {
|
if (!checkErrorResponse(response, false)) {
|
||||||
// Fill device info.
|
// Fill device info.
|
||||||
fillDeviceInfo(response);
|
fillDeviceInfo(response);
|
||||||
} else {
|
fwStorageDir = response[ID_FW_STORE_PATH];
|
||||||
readingManagementInfo = false;
|
// Flag device info read.
|
||||||
// Hide the loading panel.
|
managementInfoRead = true;
|
||||||
showLoadingPopup(false);
|
// Check if there is a firmware update running.
|
||||||
|
checkFirmwareUpdateRunning();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fills device information.
|
// Fills device information.
|
||||||
function fillDeviceInfo(deviceData) {
|
function fillDeviceInfo(deviceData) {
|
||||||
|
// Set the device type.
|
||||||
|
updateFieldValue(ID_DEVICE_NAME, deviceData[ID_DEVICE_TYPE].toUpperCase());
|
||||||
// Set DEY version.
|
// Set DEY version.
|
||||||
updateFieldValue(ID_DEY_VERSION, deviceData[ID_DEY_VERSION]);
|
updateFieldValue(ID_DEY_VERSION, deviceData[ID_DEY_VERSION]);
|
||||||
// Set Kernel version.
|
// Set Kernel version.
|
||||||
|
|
@ -188,7 +169,7 @@ function rebootDevice() {
|
||||||
showLoadingPopup(true, MESSAGE_SENDING_REBOOT);
|
showLoadingPopup(true, MESSAGE_SENDING_REBOOT);
|
||||||
// Send request to reboot the device.
|
// Send request to reboot the device.
|
||||||
$.post(
|
$.post(
|
||||||
"../ajax/reboot_device",
|
"http://" + getServerAddress() + "/ajax/reboot_device",
|
||||||
function(data) {
|
function(data) {
|
||||||
// Process only in the management page.
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
|
|
@ -209,43 +190,78 @@ function rebootDevice() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onConnectivity(cb) {
|
||||||
|
$.get("http://" + getServerAddress() + "/ping", function() {
|
||||||
|
cb();
|
||||||
|
}).fail(function() {
|
||||||
|
onConnectivity(cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showRebootInfo() {
|
||||||
|
// Show info dialog.
|
||||||
|
showInfoPopup(true, TITLE_DEVICE_REBOOTING, "Waiting for connectivity after reboot <span class=\"dots\"></span>");
|
||||||
|
deviceRebooting = true;
|
||||||
|
managementInfoRead = false;
|
||||||
|
prevDeviceConnectionStatus = false;
|
||||||
|
|
||||||
|
var dotsInterval = setInterval(function() {
|
||||||
|
var dots = $("#info_popup .dots");
|
||||||
|
dots.text(dots.text() === "..." ? "" : dots.text() + ".");
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
onConnectivity(function() {
|
||||||
|
clearInterval(dotsInterval);
|
||||||
|
showInfoPopup(false);
|
||||||
|
showPopup(ID_LOADING_WRAPPER, "rebooted_dialog", true);
|
||||||
|
});
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
// Processes the response of the reboot device request.
|
// Processes the response of the reboot device request.
|
||||||
function processRebootDeviceResponse(response) {
|
function processRebootDeviceResponse(response) {
|
||||||
// Check if there was any error in the request.
|
// Check if there was any error in the request.
|
||||||
if (!checkErrorResponse(response, false)) {
|
if (!checkErrorResponse(response, false))
|
||||||
// Show info dialog.
|
showRebootInfo();
|
||||||
showInfoPopup(true, TITLE_DEVICE_REBOOTING, MESSAGE_DEVICE_REBOOTING);
|
|
||||||
deviceRebooting = true;
|
|
||||||
managementInfoRead = false;
|
|
||||||
// TODO: This should not be necessary when implementing device connection monitor.
|
|
||||||
prevDeviceConnectionStatus = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opens the firmware file browser.
|
// Opens the firmware file browser.
|
||||||
function openFirmwareBrowser() {
|
function openFirmwareBrowser() {
|
||||||
document.getElementById(ID_UPDATE_FIRMWARE_FILE).click();
|
if (is_local_access())
|
||||||
|
openFileSystem(showButtons=false, filters=".swu");
|
||||||
|
else
|
||||||
|
document.getElementById(ID_UPDATE_FIRMWARE_FILE).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads the device status.
|
// Reads the device status.
|
||||||
function firmwareFileChanged() {
|
function firmwareFileChanged(fileName="") {
|
||||||
// Execute only in the management page.
|
// Execute only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
return;
|
return;
|
||||||
|
closeFileSystem();
|
||||||
// Initialize variables.
|
// Initialize variables.
|
||||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||||
var firmwareFileLabelElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE_LABEL);
|
var firmwareFileLabelElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE_LABEL);
|
||||||
// Hide progress bar.
|
// Hide progress bar.
|
||||||
showFirmwareUpdateProgress(false);
|
showFirmwareUpdateProgress(false);
|
||||||
if (firmwareFileElement.files.length == 0) {
|
if (fileName == "" && firmwareFileElement.files.length == 0) {
|
||||||
// No file selected.
|
// No file selected.
|
||||||
firmwareFileLabelElement.innerHTML = MESSAGE_NO_FILE_SELECTED;
|
firmwareFileLabelElement.innerHTML = MESSAGE_NO_FILE_SELECTED;
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var firmwareFile = firmwareFileElement.files[0];
|
var firmwareFile = "";
|
||||||
|
// Build file path.
|
||||||
|
if (is_local_access()) {
|
||||||
|
firmwareFile = currentDirectory + fileName;
|
||||||
|
// Hide the loading status.
|
||||||
|
showFileSystemLoading(false);
|
||||||
|
} else {
|
||||||
|
firmwareFile = firmwareFileElement.files[0].name;
|
||||||
|
}
|
||||||
// Update firmware file name.
|
// Update firmware file name.
|
||||||
firmwareFileLabelElement.innerHTML = firmwareFile.name;
|
firmwareFileLabelElement.innerHTML = firmwareFile;
|
||||||
// Enable button.
|
// Enable button.
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
||||||
}
|
}
|
||||||
|
|
@ -270,19 +286,13 @@ function askUpdateFirmware() {
|
||||||
showFirmwareUpdateProgress(true);
|
showFirmwareUpdateProgress(true);
|
||||||
// Disable management page controls.
|
// Disable management page controls.
|
||||||
enableManagementPageControls(false);
|
enableManagementPageControls(false);
|
||||||
// Enable cancel button.
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
|
||||||
// Check active tab.
|
// Check active tab.
|
||||||
if (activeTab == ID_FIRMWARE_TAB_UPLOAD) {
|
if (activeTab == ID_FIRMWARE_TAB_UPLOAD) {
|
||||||
// Upload firmware.
|
if (!is_local_access())
|
||||||
uploadFirmwareFile();
|
// Upload firmware.
|
||||||
} else if (activeTab == ID_FIRMWARE_TAB_FILESET) {
|
uploadFirmwareFile();
|
||||||
// Build file path.
|
else
|
||||||
var filesetEntryElement = document.getElementById(selectedFilesetEntry);
|
updateFirmware(document.getElementById(ID_UPDATE_FIRMWARE_FILE_LABEL).innerHTML);
|
||||||
var fileName = filesetEntryElement.getElementsByClassName(CLASS_FILESET_ENTRY_NAME)[0].innerHTML;
|
|
||||||
var filePath = filesetEntryElement.getElementsByClassName(CLASS_FILESET_ENTRY_PATH)[0].innerHTML;
|
|
||||||
// Update firmware.
|
|
||||||
updateFirmware(DEMO_FILE_SET + "/" + filePath + "/" + fileName);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
|
|
@ -300,15 +310,13 @@ function uploadFirmwareFile() {
|
||||||
setFirmwareUpdateProgressInfo(0, MESSAGE_UPLOADING_FIRMWARE);
|
setFirmwareUpdateProgressInfo(0, MESSAGE_UPLOADING_FIRMWARE);
|
||||||
// Prepare data.
|
// Prepare data.
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append("file_set", DEMO_FILE_SET);
|
formData.append("path", fwStorageDir + firmwareFile.name);
|
||||||
formData.append("file_name", firmwareFile.name);
|
|
||||||
formData.append("file", firmwareFile);
|
formData.append("file", firmwareFile);
|
||||||
// Register websocket to receive upload progress.
|
formData.append("overwrite", true);
|
||||||
subscribeUploadFileProgress(firmwareFile.name);
|
// Send request.
|
||||||
// Send request
|
$.ajax({
|
||||||
uploadFirmwareAjaxRequest = $.ajax({
|
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: "../ajax/upload_firmware",
|
url: "http://" + getServerAddress() + "/ajax/fs_upload_file",
|
||||||
data: formData,
|
data: formData,
|
||||||
cache: false,
|
cache: false,
|
||||||
async: true,
|
async: true,
|
||||||
|
|
@ -318,9 +326,6 @@ function uploadFirmwareFile() {
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
// Reset request variable.
|
// Reset request variable.
|
||||||
uploadFirmwareAjaxRequest = null;
|
uploadFirmwareAjaxRequest = null;
|
||||||
// Close progress socket.
|
|
||||||
if (uploadProgressSocket != null && uploadProgressSocket != "undefined")
|
|
||||||
uploadProgressSocket.close();
|
|
||||||
// Process only in the management page.
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
return;
|
return;
|
||||||
|
|
@ -330,9 +335,6 @@ function uploadFirmwareFile() {
|
||||||
error: function(response) {
|
error: function(response) {
|
||||||
// Reset request variable.
|
// Reset request variable.
|
||||||
uploadFirmwareAjaxRequest = null;
|
uploadFirmwareAjaxRequest = null;
|
||||||
// Close progress socket.
|
|
||||||
if (uploadProgressSocket != null && uploadProgressSocket != "undefined")
|
|
||||||
uploadProgressSocket.close();
|
|
||||||
// Process only in the management page.
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
return;
|
return;
|
||||||
|
|
@ -366,26 +368,7 @@ function processUploadFirmwareFileResponse(response) {
|
||||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||||
var firmwareFile = firmwareFileElement.files[0];
|
var firmwareFile = firmwareFileElement.files[0];
|
||||||
// Send the update request.
|
// Send the update request.
|
||||||
//updateFirmware(DEMO_FILE_SET + "/" + getDeviceID() + "/" + firmwareFile.name);
|
updateFirmware(fwStorageDir + firmwareFile.name);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribes to firmware update progress.
|
|
||||||
function subscribeUploadFileProgress(fileName) {
|
|
||||||
// Create the web socket.
|
|
||||||
var socketPrefix = window.location.protocol == "https:" ? "wss" : "ws";
|
|
||||||
uploadProgressSocket = new WebSocket(socketPrefix + "://" + window.location.host + "/ws/file_upload_progress/" + fileName);
|
|
||||||
// Define the callback to be notified when firmware update progress is received.
|
|
||||||
uploadProgressSocket.onmessage = function(e) {
|
|
||||||
// Process only in the management page.
|
|
||||||
if (!isManagementShowing()) {
|
|
||||||
// Close the socket.
|
|
||||||
uploadProgressSocket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Update progress.
|
|
||||||
var data = JSON.parse(e.data);
|
|
||||||
setFirmwareUpdateProgressInfo(data[ID_PROGRESS], MESSAGE_UPLOADING_FIRMWARE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,11 +376,9 @@ function subscribeUploadFileProgress(fileName) {
|
||||||
function updateFirmware(filePath) {
|
function updateFirmware(filePath) {
|
||||||
// Update status.
|
// Update status.
|
||||||
setFirmwareUpdateProgressInfo(0, MESSAGE_SENDING_UPLOAD_REQUEST);
|
setFirmwareUpdateProgressInfo(0, MESSAGE_SENDING_UPLOAD_REQUEST);
|
||||||
// Disable the cancel button.
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, false);
|
|
||||||
// Send request to update the firmware.
|
// Send request to update the firmware.
|
||||||
$.post(
|
$.post(
|
||||||
"../ajax/update_firmware",
|
"http://" + getServerAddress() + "/ajax/update_firmware",
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
"file": filePath
|
"file": filePath
|
||||||
}),
|
}),
|
||||||
|
|
@ -435,8 +416,6 @@ function processUpdateFirmwareResponse(response) {
|
||||||
// Enable the page controls.
|
// Enable the page controls.
|
||||||
enableManagementPageControls(true);
|
enableManagementPageControls(true);
|
||||||
} else {
|
} else {
|
||||||
// Enable the cancel button.
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
|
||||||
// Update progress status.
|
// Update progress status.
|
||||||
setFirmwareUpdateProgressInfo(100, MESSAGE_SENDING_FIRMWARE_UPDATE_REQUEST);
|
setFirmwareUpdateProgressInfo(100, MESSAGE_SENDING_FIRMWARE_UPDATE_REQUEST);
|
||||||
// Start timer to check firmware update status periodically.
|
// Start timer to check firmware update status periodically.
|
||||||
|
|
@ -476,7 +455,7 @@ function checkFirmwareUpdateStatus() {
|
||||||
}
|
}
|
||||||
// Send request to check firmware update status.
|
// Send request to check firmware update status.
|
||||||
$.post(
|
$.post(
|
||||||
"../ajax/check_firmware_update_status",
|
"http://" + getServerAddress() + "/ajax/check_firmware_update_status",
|
||||||
function(data) {
|
function(data) {
|
||||||
// Process only in the management page.
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
|
|
@ -488,8 +467,13 @@ function checkFirmwareUpdateStatus() {
|
||||||
// Process only in the management page.
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
return;
|
return;
|
||||||
// Process error.
|
$.get("http://" + getServerAddress() + "/ping", function() {
|
||||||
processAjaxErrorResponse(response);
|
// Process error.
|
||||||
|
processAjaxErrorResponse(response);
|
||||||
|
}).fail(function() {
|
||||||
|
if (!deviceRebooting)
|
||||||
|
showRebootInfo();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -516,6 +500,7 @@ function processCheckFirmwareUpdateStatusResponse(response) {
|
||||||
managementInfoRead = false;
|
managementInfoRead = false;
|
||||||
// Set update as successful.
|
// Set update as successful.
|
||||||
setFirmwareUpdateProgressSuccess(response[ID_MESSAGE]);
|
setFirmwareUpdateProgressSuccess(response[ID_MESSAGE]);
|
||||||
|
showRebootInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -532,7 +517,7 @@ function checkFirmwareUpdateRunning() {
|
||||||
showLoadingPopup(true, MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS);
|
showLoadingPopup(true, MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS);
|
||||||
// Send request to check firmware update running.
|
// Send request to check firmware update running.
|
||||||
$.post(
|
$.post(
|
||||||
"../ajax/check_firmware_update_running",
|
"http://" + getServerAddress() + "/ajax/check_firmware_update_running",
|
||||||
function(data) {
|
function(data) {
|
||||||
// Process only in the management page.
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
|
|
@ -561,8 +546,6 @@ function processCheckFirmwareUpdateRunningResponse(response) {
|
||||||
updatingFirmware = true;
|
updatingFirmware = true;
|
||||||
// Disable page controls.
|
// Disable page controls.
|
||||||
enableManagementPageControls(false);
|
enableManagementPageControls(false);
|
||||||
// Enable cancel button.
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
|
||||||
// Show firmware update progress.
|
// Show firmware update progress.
|
||||||
showFirmwareUpdateProgress(true);
|
showFirmwareUpdateProgress(true);
|
||||||
// Update the firmware update progress.
|
// Update the firmware update progress.
|
||||||
|
|
@ -585,7 +568,7 @@ function checkFirmwareUpdateProgress() {
|
||||||
showLoadingPopup(false);
|
showLoadingPopup(false);
|
||||||
// Send request to check firmware update progress.
|
// Send request to check firmware update progress.
|
||||||
$.post(
|
$.post(
|
||||||
"../ajax/check_firmware_update_progress",
|
"http://" + getServerAddress() + "/ajax/check_firmware_update_progress",
|
||||||
function(data) {
|
function(data) {
|
||||||
// Process only in the management page.
|
// Process only in the management page.
|
||||||
if (!isManagementShowing())
|
if (!isManagementShowing())
|
||||||
|
|
@ -611,212 +594,6 @@ function processCheckFirmwareUpdateProgressResponse(response) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asks user to cancel the firmware update process
|
|
||||||
function askCancelFirmwareUpdate() {
|
|
||||||
showConfirmDialog(TITLE_CONFIRM_CANCEL_UPDATE, MESSAGE_CONFIRM_CANCEL_UPDATE,
|
|
||||||
function() {
|
|
||||||
cancelFirmwareUpdate();
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancels an ongoing firmware update.
|
|
||||||
function cancelFirmwareUpdate() {
|
|
||||||
// Sanity checks
|
|
||||||
if (!isManagementShowing() || !updatingFirmware)
|
|
||||||
return;
|
|
||||||
// Check the type of the firmware update.
|
|
||||||
if (uploadFirmwareAjaxRequest != null)
|
|
||||||
cancelFirmwareUploadProcess();
|
|
||||||
else
|
|
||||||
cancelFirmwareUpdateProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancels the firmware upload process.
|
|
||||||
function cancelFirmwareUploadProcess() {
|
|
||||||
// Sanity checks
|
|
||||||
if (!isManagementShowing())
|
|
||||||
return;
|
|
||||||
// Send request to cancel firmware upload.
|
|
||||||
uploadProgressSocket.send("cancel");
|
|
||||||
// Abort AJAX request.
|
|
||||||
uploadFirmwareAjaxRequest.abort();
|
|
||||||
uploadFirmwareAjaxRequest = null;
|
|
||||||
// Flag the update variable.
|
|
||||||
updatingFirmware = false;
|
|
||||||
// Enable page controls.
|
|
||||||
enableManagementPageControls(true);
|
|
||||||
// Hide he firmware update progress.
|
|
||||||
showFirmwareUpdateProgress(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancels the remote firmware update process.
|
|
||||||
function cancelFirmwareUpdateProcess() {
|
|
||||||
// Sanity checks
|
|
||||||
if (!isManagementShowing())
|
|
||||||
return;
|
|
||||||
// Disable cancel button.
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, false);
|
|
||||||
// Show loading popup.
|
|
||||||
showLoadingPopup(true, MESSAGE_CANCELING_FIRMWARE_UPDATE);
|
|
||||||
// Send request to cancel firmware update.
|
|
||||||
$.post(
|
|
||||||
"../ajax/cancel_firmware_update",
|
|
||||||
function(data) {
|
|
||||||
// Process only in the management page.
|
|
||||||
if (!isManagementShowing())
|
|
||||||
return;
|
|
||||||
// Hide loading popup.
|
|
||||||
showLoadingPopup(false);
|
|
||||||
// Process cancel firmware update answer.
|
|
||||||
processCancelFirmwareUpdateResponse(data);
|
|
||||||
}
|
|
||||||
).fail(function(response) {
|
|
||||||
// Process only in the management page.
|
|
||||||
if (!isManagementShowing())
|
|
||||||
return;
|
|
||||||
// Hide loading popup.
|
|
||||||
showLoadingPopup(false);
|
|
||||||
// Process error.
|
|
||||||
processAjaxErrorResponse(response);
|
|
||||||
// Enable cancel button again.
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processes the response of the cancel firmware update request.
|
|
||||||
function processCancelFirmwareUpdateResponse(response) {
|
|
||||||
// Check if there was any error in the request.
|
|
||||||
if (checkErrorResponse(response, false)) {
|
|
||||||
// Enable cancel button again.
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
|
||||||
} else {
|
|
||||||
// Flag the update variable.
|
|
||||||
updatingFirmware = false;
|
|
||||||
// Enable page controls.
|
|
||||||
enableManagementPageControls(true);
|
|
||||||
// Hide firmware update progress.
|
|
||||||
showFirmwareUpdateProgress(false);
|
|
||||||
// Stop the firmware update timer.
|
|
||||||
stopFirmwareUpdateTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clears the fileset file list.
|
|
||||||
function clearFilesetList() {
|
|
||||||
// Initialize variables.
|
|
||||||
var filesetEntriesContainerElement = document.getElementById(ID_FILESET_ITEMS_CONTAINER);
|
|
||||||
// Clear the fileset file list.
|
|
||||||
if (filesetEntriesContainerElement != null && filesetEntriesContainerElement != "undefined") {
|
|
||||||
while (filesetEntriesContainerElement.firstChild)
|
|
||||||
filesetEntriesContainerElement.removeChild(filesetEntriesContainerElement.lastChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh the fileset list of files.
|
|
||||||
function refreshFilesetFiles() {
|
|
||||||
// Sanity checks
|
|
||||||
if (!isManagementShowing())
|
|
||||||
return;
|
|
||||||
// Flag files loaded.
|
|
||||||
filesLoaded = false;
|
|
||||||
// Reset fileset files.
|
|
||||||
listFilesetFiles(DEMO_FILE_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lists all the files of a fileset.
|
|
||||||
function listFilesetFiles(fileSet) {
|
|
||||||
// Sanity checks
|
|
||||||
if (!isManagementShowing() || filesLoaded)
|
|
||||||
return;
|
|
||||||
// Unselect all fileset entries.
|
|
||||||
unselectFilesetEntries();
|
|
||||||
// Clear the fileset list.
|
|
||||||
clearFilesetList();
|
|
||||||
// Show loading popup.
|
|
||||||
showLoadingPopup(true, MESSAGE_LOADING_FILES);
|
|
||||||
// Send request to list files.
|
|
||||||
$.post(
|
|
||||||
"../ajax/list_fileset_files",
|
|
||||||
JSON.stringify({
|
|
||||||
"file_set": fileSet
|
|
||||||
}),
|
|
||||||
function(data) {
|
|
||||||
// Process only in the management page.
|
|
||||||
if (!isManagementShowing())
|
|
||||||
return;
|
|
||||||
// Hide loading popup.
|
|
||||||
showLoadingPopup(false);
|
|
||||||
// Process answer.
|
|
||||||
processListFilesetFilesResponse(data);
|
|
||||||
}
|
|
||||||
).fail(function(response) {
|
|
||||||
// Process only in the management page.
|
|
||||||
if (!isManagementShowing())
|
|
||||||
return;
|
|
||||||
// Hide loading popup.
|
|
||||||
showLoadingPopup(false);
|
|
||||||
// Process error.
|
|
||||||
processAjaxErrorResponse(response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processes the response of the list fileset files request.
|
|
||||||
function processListFilesetFilesResponse(response) {
|
|
||||||
// Check if there was any error in the request.
|
|
||||||
if (!checkErrorResponse(response, false)) {
|
|
||||||
// Parse the files contained in the fileset.
|
|
||||||
var files = response[ID_FILES];
|
|
||||||
// Add the files to the list.
|
|
||||||
if (files != null && files != "undefined") {
|
|
||||||
var filesetEntriesContainerElement = document.getElementById(ID_FILESET_ITEMS_CONTAINER);
|
|
||||||
for (var entry of response[ID_FILES]) {
|
|
||||||
var name = entry[ID_NAME];
|
|
||||||
var entryDiv = document.createElement("div");
|
|
||||||
entryDiv.innerHTML = TEMPLATE_FILESET_FILE.format(name, name, name, name, entry[ID_PATH],
|
|
||||||
sizeToHumanRead(entry[ID_SIZE]), transformDate(entry[ID_LAST_MODIFIED]));
|
|
||||||
filesetEntriesContainerElement.appendChild(entryDiv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Flag fileset list variable.
|
|
||||||
filesLoaded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Selects a file from the fileset list
|
|
||||||
function selectFilesetEntry(entryID) {
|
|
||||||
// Unselect all entries.
|
|
||||||
unselectFilesetEntries();
|
|
||||||
// Set selected style to the selected div.
|
|
||||||
var entryElement = document.getElementById(entryID)
|
|
||||||
if (entryElement != null) {
|
|
||||||
entryElement.classList.add(CLASS_FILESET_ENTRY_SELECTED);
|
|
||||||
selectedFilesetEntry = entryID;
|
|
||||||
// Enable update firmware button.
|
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
|
||||||
// Hide firmware update progress.
|
|
||||||
showFirmwareUpdateProgress(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unselects all the fileset entries.
|
|
||||||
function unselectFilesetEntries() {
|
|
||||||
// Initialize variables.
|
|
||||||
var fileSystemEntriesDiv = document.getElementById(ID_FILESET_ITEMS_CONTAINER);
|
|
||||||
var children = fileSystemEntriesDiv.children;
|
|
||||||
// Remove selected class from all entries.
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
var entry = children[i].children[0];
|
|
||||||
entry.classList.remove(CLASS_FILESET_ENTRY_SELECTED);
|
|
||||||
}
|
|
||||||
selectedFilesetEntry = null;
|
|
||||||
// Disable firmware update button.
|
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enables/disables the management page controls.
|
// Enables/disables the management page controls.
|
||||||
function enableManagementPageControls(enable) {
|
function enableManagementPageControls(enable) {
|
||||||
// Reboot button.
|
// Reboot button.
|
||||||
|
|
@ -829,32 +606,16 @@ function enableManagementPageControls(enable) {
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||||
else
|
else
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, enable);
|
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, enable);
|
||||||
} else if (activeTab == ID_FIRMWARE_TAB_FILESET) {
|
|
||||||
if (!filesLoaded || selectedFilesetEntry == null)
|
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
|
||||||
else
|
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, enable);
|
|
||||||
}
|
}
|
||||||
// Cancel update button.
|
|
||||||
if (isFirmwareUpdateRunning() && enable)
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, enable);
|
|
||||||
else
|
|
||||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, false);
|
|
||||||
// Tabs.
|
// Tabs.
|
||||||
var tabUploadElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD);
|
var tabUploadElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD);
|
||||||
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
||||||
var tabFilesetElement = document.getElementById(ID_FIRMWARE_TAB_FILESET);
|
|
||||||
var tabFilesetHeaderElement = document.getElementById(ID_FIRMWARE_TAB_FILESET_HEADER);
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
tabUploadElement.classList.remove((CLASS_DISABLED_DIV));
|
tabUploadElement.classList.remove((CLASS_DISABLED_DIV));
|
||||||
tabUploadHeaderElement.classList.remove((CLASS_DISABLED_DIV));
|
tabUploadHeaderElement.classList.remove((CLASS_DISABLED_DIV));
|
||||||
tabFilesetElement.classList.remove((CLASS_DISABLED_DIV));
|
|
||||||
tabFilesetHeaderElement.classList.remove((CLASS_DISABLED_DIV));
|
|
||||||
} else {
|
} else {
|
||||||
tabUploadElement.classList.add((CLASS_DISABLED_DIV));
|
tabUploadElement.classList.add((CLASS_DISABLED_DIV));
|
||||||
tabUploadHeaderElement.classList.add((CLASS_DISABLED_DIV));
|
tabUploadHeaderElement.classList.add((CLASS_DISABLED_DIV));
|
||||||
tabFilesetElement.classList.add((CLASS_DISABLED_DIV));
|
|
||||||
tabFilesetHeaderElement.classList.add((CLASS_DISABLED_DIV));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -875,12 +636,9 @@ function enableManagementButton(buttonID, enable) {
|
||||||
function getActiveFirmwareUpdateTab() {
|
function getActiveFirmwareUpdateTab() {
|
||||||
// Initialize variables.
|
// Initialize variables.
|
||||||
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
||||||
var tabFilesetHeaderElement = document.getElementById(ID_FIRMWARE_TAB_FILESET_HEADER);
|
|
||||||
// Check the active tab.
|
// Check the active tab.
|
||||||
if (tabUploadHeaderElement.classList.contains(CLASS_FIRMWARE_TAB_HEADER_ACTIVE))
|
if (tabUploadHeaderElement.classList.contains(CLASS_FIRMWARE_TAB_HEADER_ACTIVE))
|
||||||
return ID_FIRMWARE_TAB_UPLOAD;
|
return ID_FIRMWARE_TAB_UPLOAD;
|
||||||
else if (tabFilesetHeaderElement.classList.contains(CLASS_FIRMWARE_TAB_HEADER_ACTIVE))
|
|
||||||
return ID_FIRMWARE_TAB_FILESET;
|
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -923,15 +681,6 @@ function showFirmwareTab(tabID) {
|
||||||
showFirmwareUpdateProgress(false);
|
showFirmwareUpdateProgress(false);
|
||||||
// Perform additional actions on each tab.
|
// Perform additional actions on each tab.
|
||||||
switch(tabID) {
|
switch(tabID) {
|
||||||
case ID_FIRMWARE_TAB_FILESET:
|
|
||||||
if (filesLoaded && selectedFilesetEntry != null) {
|
|
||||||
// Enable firmware update button.
|
|
||||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
|
||||||
} else if (!filesLoaded) {
|
|
||||||
// Refresh fileset entries.
|
|
||||||
listFilesetFiles(DEMO_FILE_SET);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ID_FIRMWARE_TAB_UPLOAD:
|
case ID_FIRMWARE_TAB_UPLOAD:
|
||||||
// Check if there is a file in the file input.
|
// Check if there is a file in the file input.
|
||||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||||
|
|
@ -998,8 +747,16 @@ function updateFirmwareUpdateProgress(status, progress, title=null, message=null
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Update the progress bar percent.
|
// Update the progress bar percent.
|
||||||
progressBarElement.style.width = progress + "%";
|
if (progress != "?") {
|
||||||
progressBarElement.innerHTML = progress + "%";
|
progressBarElement.style.width = progress + "%";
|
||||||
|
progressBarElement.innerHTML = progress + "%";
|
||||||
|
} else {
|
||||||
|
let html = progressBarElement.innerHTML;
|
||||||
|
if (html.startsWith("."))
|
||||||
|
progressBarElement.innerHTML = html + ".";
|
||||||
|
else
|
||||||
|
progressBarElement.innerHTML = ".";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Update the progress title.
|
// Update the progress title.
|
||||||
var progressTitleElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS_TITLE);
|
var progressTitleElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS_TITLE);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue