connectcore-demo-example: add network configuration section
Signed-off-by: David Escalona <david.escalona@digi.com>
This commit is contained in:
parent
14f849fb8d
commit
4f9717a2d3
|
|
@ -29,10 +29,10 @@ import socketserver
|
||||||
import stat
|
import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from digi.apix.bluetooth import BluetoothException, BluetoothDevice
|
from digi.apix.bluetooth import BluetoothException, BluetoothDevice, BluetoothProfile
|
||||||
from digi.apix.exceptions import DigiAPIXException
|
from digi.apix.exceptions import DigiAPIXException
|
||||||
from digi.apix.network import NetworkException, NetStatus, NetworkInterface
|
from digi.apix.network import IPMode, NetworkException, NetStatus, NetworkInterface, NetworkProfile
|
||||||
from digi.apix.wifi import WifiException, WifiInterface
|
from digi.apix.wifi import SecurityMode, WifiException, WifiInterface, WifiProfile
|
||||||
from logging.handlers import SysLogHandler
|
from logging.handlers import SysLogHandler
|
||||||
from subprocess import call, TimeoutExpired
|
from subprocess import call, TimeoutExpired
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
@ -56,6 +56,13 @@ ZERO_MAC = "00:00:00:00:00:00"
|
||||||
ZERO_IP = "0.0.0.0"
|
ZERO_IP = "0.0.0.0"
|
||||||
NOT_AVAILABLE = "N/A"
|
NOT_AVAILABLE = "N/A"
|
||||||
|
|
||||||
|
ELEMENT_BLUETOOTH = "bluetooth"
|
||||||
|
ELEMENT_ETHERNET = "ethernet"
|
||||||
|
ELEMENT_WIFI = "wifi"
|
||||||
|
|
||||||
|
PREFIX_ETHERNET = "eth"
|
||||||
|
PREFIX_WIFI = "wlan"
|
||||||
|
|
||||||
# Variables.
|
# Variables.
|
||||||
log = logging.getLogger(APP_NAME)
|
log = logging.getLogger(APP_NAME)
|
||||||
last_cpu_work = 0
|
last_cpu_work = 0
|
||||||
|
|
@ -210,7 +217,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
# Fill bluetooth devices data.
|
# Fill bluetooth devices data.
|
||||||
try:
|
try:
|
||||||
bt_devices = BluetoothDevice.list_devices()
|
bt_devices = BluetoothDevice.list_devices() or []
|
||||||
for device in bt_devices:
|
for device in bt_devices:
|
||||||
try:
|
try:
|
||||||
bt_device = BluetoothDevice.get(device)
|
bt_device = BluetoothDevice.get(device)
|
||||||
|
|
@ -226,7 +233,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
# Fill ethernet interfaces data.
|
# Fill ethernet interfaces data.
|
||||||
try:
|
try:
|
||||||
interfaces = NetworkInterface.list_interfaces()
|
interfaces = NetworkInterface.list_interfaces() or []
|
||||||
for iface in interfaces:
|
for iface in interfaces:
|
||||||
try:
|
try:
|
||||||
net_iface = NetworkInterface.get(iface)
|
net_iface = NetworkInterface.get(iface)
|
||||||
|
|
@ -242,7 +249,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
# Fill WiFi interfaces data.
|
# Fill WiFi interfaces data.
|
||||||
try:
|
try:
|
||||||
interfaces = WifiInterface.list_interfaces()
|
interfaces = WifiInterface.list_interfaces() or []
|
||||||
for iface in interfaces:
|
for iface in interfaces:
|
||||||
try:
|
try:
|
||||||
wifi_iface = WifiInterface.get(iface)
|
wifi_iface = WifiInterface.get(iface)
|
||||||
|
|
@ -567,7 +574,34 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
progress = 100
|
progress = 100
|
||||||
if fw_process and fw_process.poll() is None:
|
if fw_process and fw_process.poll() is None:
|
||||||
progress = "?"
|
progress = "?"
|
||||||
self.wfile.write(json.dumps({"progress": progress, "message": "Updating firmare"}).encode(encoding="utf_8"))
|
self.wfile.write(json.dumps({"progress": progress, "message": "Updating firmware"}).encode(encoding="utf_8"))
|
||||||
|
elif re.search("/ajax/get_config", self.path) is not None:
|
||||||
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
# Get the JSON data.
|
||||||
|
data = self.rfile.read(int(self.headers["Content-Length"]))
|
||||||
|
elements = json.loads(data.decode("utf-8")).get("elements", None)
|
||||||
|
# Fill configuration data.
|
||||||
|
config_data = get_elements_configuration(elements)
|
||||||
|
# Send the answer.
|
||||||
|
if "error" in config_data:
|
||||||
|
self.wfile.write(json.dumps(config_data).encode(encoding="utf_8"))
|
||||||
|
else:
|
||||||
|
self.wfile.write(json.dumps(
|
||||||
|
{"data": json.dumps(config_data)}).encode(encoding="utf_8"))
|
||||||
|
elif re.search("/ajax/set_config", self.path) is not None:
|
||||||
|
# Set the response headers.
|
||||||
|
self._set_headers(200)
|
||||||
|
# Get the JSON data.
|
||||||
|
data = self.rfile.read(int(self.headers["Content-Length"]))
|
||||||
|
configuration = json.loads(data.decode("utf-8")).get("configuration", None)
|
||||||
|
# Apply configuration.
|
||||||
|
result = set_configuration(configuration)
|
||||||
|
# Send the answer.
|
||||||
|
if "error" in result:
|
||||||
|
self.wfile.write(json.dumps(result).encode(encoding="utf_8"))
|
||||||
|
else:
|
||||||
|
self.wfile.write(json.dumps({"data": json.dumps(result)}).encode(encoding="utf_8"))
|
||||||
else:
|
else:
|
||||||
# Forbidden.
|
# Forbidden.
|
||||||
self._set_headers(403)
|
self._set_headers(403)
|
||||||
|
|
@ -612,7 +646,7 @@ def filter_by_extension(name, filters):
|
||||||
if name.endswith(ext):
|
if name.endswith(ext):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False;
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_uptime():
|
def get_uptime():
|
||||||
|
|
@ -945,6 +979,257 @@ def set_audio_volume(value):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_elements_configuration(elements):
|
||||||
|
"""
|
||||||
|
Gets the configuration for the given elements.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
elements (List): Elements for which to get the configuration.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: The elements configuration data.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
for element in elements:
|
||||||
|
if element == ELEMENT_BLUETOOTH:
|
||||||
|
data[element] = get_bluetooth_element_configuration()
|
||||||
|
elif element in (ELEMENT_ETHERNET, ELEMENT_WIFI):
|
||||||
|
data[element] = get_network_element_configuration(element)
|
||||||
|
else:
|
||||||
|
data["error"] = f"Unknown element '{element}'"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_network_element_configuration(element):
|
||||||
|
"""
|
||||||
|
Gets the configuration for the given network element.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
element (String): Network element for which to get the configuration.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: The network element configuration data.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
prefix = PREFIX_ETHERNET
|
||||||
|
if element == ELEMENT_WIFI:
|
||||||
|
prefix = PREFIX_WIFI
|
||||||
|
try:
|
||||||
|
ifaces = NetworkInterface.list_interfaces() or []
|
||||||
|
for iface in ifaces:
|
||||||
|
if prefix in iface:
|
||||||
|
data[iface] = get_network_iface_configuration(iface)
|
||||||
|
except DigiAPIXException as exc:
|
||||||
|
data["error"] = f"Error listing network interfaces: '{str(exc)}'"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_network_iface_configuration(interface):
|
||||||
|
"""
|
||||||
|
Returns the network configuration of the given interface.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interface (String): Network interface to get its configuration.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: dictionary with the interface configuration.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
try:
|
||||||
|
net_iface = NetworkInterface.get(interface)
|
||||||
|
data["enable"] = 1 if net_iface.status == NetStatus.CONNECTED else 0
|
||||||
|
data["mac"] = mac_to_human_string(net_iface.mac)
|
||||||
|
data["type"] = 0 if net_iface.ip_mode == IPMode.STATIC else 1
|
||||||
|
data["ip"] = str(net_iface.ipv4)
|
||||||
|
data["netmask"] = str(net_iface.netmask)
|
||||||
|
data["dns1"] = str(net_iface.dns1)
|
||||||
|
data["dns2"] = str(net_iface.dns2)
|
||||||
|
data["gateway"] = str(net_iface.gateway)
|
||||||
|
if PREFIX_WIFI in interface:
|
||||||
|
try:
|
||||||
|
wifi_iface = WifiInterface.get(interface)
|
||||||
|
data["ssid"] = wifi_iface.ssid
|
||||||
|
data["frequency"] = wifi_iface.frequency
|
||||||
|
data["channel"] = wifi_iface.channel
|
||||||
|
data["sec_mode"] = 0 if wifi_iface.sec_mode == SecurityMode.UNKNOWN \
|
||||||
|
else wifi_iface.sec_mode.code
|
||||||
|
except WifiException as exc:
|
||||||
|
raise NetworkException({str(exc)}) from exc
|
||||||
|
except NetworkException as exc2:
|
||||||
|
data["error"] = f"Error reading interface data: {str(exc2)}"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def set_configuration(config_data):
|
||||||
|
"""
|
||||||
|
Applies the given configuration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config_data (Dictionary): Configuration to apply.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: The operation result.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
for element in config_data:
|
||||||
|
if element == ELEMENT_BLUETOOTH:
|
||||||
|
data[element] = set_bluetooth_element_configuration(config_data[element])
|
||||||
|
elif element in (ELEMENT_ETHERNET, ELEMENT_WIFI):
|
||||||
|
data[element] = set_network_element_configuration(config_data[element])
|
||||||
|
else:
|
||||||
|
data["error"] = f"Unknown element '{element}'"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def set_network_element_configuration(config_data):
|
||||||
|
"""
|
||||||
|
Applies the given network configuration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config_data (Dictionary): Network configuration to apply.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: The operation result.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
for iface in config_data:
|
||||||
|
data[iface] = set_network_iface_configuration(iface, config_data[iface])
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def set_network_iface_configuration(interface, config_data):
|
||||||
|
"""
|
||||||
|
Applies the given network configuration to the given interface.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interface (String): Network interface to apply configuration to.
|
||||||
|
config_data (Dictionary): Network configuration to apply.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: Operation result.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
profile = NetworkProfile()
|
||||||
|
if PREFIX_WIFI in interface:
|
||||||
|
profile = WifiProfile()
|
||||||
|
profile.connect = config_data.get("enable", None)
|
||||||
|
profile.mode = IPMode.get(config_data["type"]) if "type" in config_data else None
|
||||||
|
profile.ipv4 = config_data.get("ip", None)
|
||||||
|
profile.netmask = config_data.get("netmask", None)
|
||||||
|
profile.gateway = config_data.get("gateway", None)
|
||||||
|
profile.dns1 = config_data.get("dns1", None)
|
||||||
|
profile.dns2 = config_data.get("dns2", None)
|
||||||
|
if PREFIX_WIFI in interface:
|
||||||
|
profile.ssid = config_data.get("ssid", None)
|
||||||
|
profile.sec_mode = (SecurityMode.get(config_data["sec_mode"])
|
||||||
|
if "sec_mode" in config_data else None)
|
||||||
|
profile.psk = config_data.get("psk", None)
|
||||||
|
try:
|
||||||
|
if PREFIX_ETHERNET in interface:
|
||||||
|
net_iface = NetworkInterface.get(interface)
|
||||||
|
elif PREFIX_WIFI in interface:
|
||||||
|
net_iface = WifiInterface.get(interface)
|
||||||
|
else:
|
||||||
|
raise DigiAPIXException(f"Unknown interface '{interface}'")
|
||||||
|
net_iface.configure(profile)
|
||||||
|
data["status"] = 0
|
||||||
|
except DigiAPIXException as exc2:
|
||||||
|
data["status"] = 1
|
||||||
|
data["desc"] = f"Error configuring interface: {str(exc2)}"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_bluetooth_element_configuration():
|
||||||
|
"""
|
||||||
|
Gets the configuration for the bluetooth element.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: The bluetooth element configuration data.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
try:
|
||||||
|
bt_devices = BluetoothDevice.list_devices() or []
|
||||||
|
for bt_device in bt_devices:
|
||||||
|
data[bt_device] = get_bluetooth_device_configuration(bt_device)
|
||||||
|
except DigiAPIXException as exc:
|
||||||
|
data["error"] = f"Error listing bluetooth devices: '{str(exc)}'"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_bluetooth_device_configuration(device):
|
||||||
|
"""
|
||||||
|
Returns the configuration of the given bluetooth device.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
device (String): Bluetooth device to get its configuration.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: dictionary with the device configuration.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
try:
|
||||||
|
bt_device = BluetoothDevice.get(device)
|
||||||
|
data["device_id"] = bt_device.device_id
|
||||||
|
data["advert_name"] = str(bt_device.advert_name)
|
||||||
|
data["mac"] = mac_to_human_string(bt_device.mac)
|
||||||
|
data["enable"] = 1 if bt_device.is_enabled else 0
|
||||||
|
data["running"] = 1 if bt_device.is_running else 0
|
||||||
|
except BluetoothException as exc:
|
||||||
|
data["error"] = f"Error reading device data: {str(exc)}"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def set_bluetooth_element_configuration(config_data):
|
||||||
|
"""
|
||||||
|
Applies the given bluetooth configuration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config_data (Dictionary): Bluetooth configuration to apply.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: The operation result.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
for device in config_data:
|
||||||
|
data[device] = set_bluetooth_device_configuration(device, config_data[device])
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def set_bluetooth_device_configuration(device, config_data):
|
||||||
|
"""
|
||||||
|
Applies the given bluetooth configuration to the given device.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
device (String): Bluetooth device to apply configuration to.
|
||||||
|
config_data (Dictionary): Bluetooth configuration to apply.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary: Operation result.
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
try:
|
||||||
|
bt_device = BluetoothDevice.get(device)
|
||||||
|
profile = BluetoothProfile()
|
||||||
|
profile.enable = config_data.get("enable", None)
|
||||||
|
profile.advert_name = config_data.get("advert_name", None)
|
||||||
|
bt_device.configure(profile)
|
||||||
|
data["status"] = 0
|
||||||
|
except DigiAPIXException as exc2:
|
||||||
|
data["status"] = 1
|
||||||
|
data["desc"] = f"Error configuring interface: {str(exc2)}"
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def mac_to_human_string(mac, num_bytes=6):
|
def mac_to_human_string(mac, num_bytes=6):
|
||||||
"""
|
"""
|
||||||
Transforms the given MAC address into a human readable string.
|
Transforms the given MAC address into a human readable string.
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ Digi Demo - Dashboard
|
||||||
<p id="banner-text">ConnectCore Demo</p>
|
<p id="banner-text">ConnectCore Demo</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="nav-right-container">
|
<div class="nav-right-container">
|
||||||
<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">
|
||||||
|
|
@ -69,6 +68,14 @@ Digi Demo - Dashboard
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li id="section_network">
|
||||||
|
<a data-pjax href="network.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">
|
||||||
|
<span class="digi-menu-icon fas fa-network-wired fa-fw fa-lg mr-3"></span>
|
||||||
|
<span class="menu-collapsed">Network</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li id="section_management">
|
<li id="section_management">
|
||||||
<a data-pjax href="management.html" 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">
|
||||||
|
|
@ -754,6 +761,7 @@ Digi Demo - Dashboard
|
||||||
<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/network.js"></script>
|
||||||
<script type="text/javascript" src="./static/js/multimedia.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/file-system.js"></script>
|
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,12 @@ Digi Demo - Management
|
||||||
<p id="banner-text">ConnectCore Demo</p>
|
<p id="banner-text">ConnectCore Demo</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="nav-right-container">
|
||||||
<div class="nav-right-container">
|
<div>
|
||||||
|
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||||
<div>
|
</div>
|
||||||
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
<div id="device-name">DEY DEVICE</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="device-name">DEY DEVICE</div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
@ -69,6 +68,14 @@ Digi Demo - Management
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li id="section_network">
|
||||||
|
<a data-pjax href="network.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">
|
||||||
|
<span class="digi-menu-icon fas fa-network-wired fa-fw fa-lg mr-3"></span>
|
||||||
|
<span class="menu-collapsed">Network</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li id="section_management">
|
<li id="section_management">
|
||||||
<a data-pjax href="management.html" 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">
|
||||||
|
|
@ -293,6 +300,7 @@ 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/network.js"></script>
|
||||||
<script type="text/javascript" src="./static/js/multimedia.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/file-system.js"></script>
|
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,12 @@ Digi Demo - Multimedia
|
||||||
<p id="banner-text">ConnectCore Demo</p>
|
<p id="banner-text">ConnectCore Demo</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="nav-right-container">
|
||||||
<div class="nav-right-container">
|
<div>
|
||||||
|
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||||
<div>
|
</div>
|
||||||
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
<div id="device-name">DEY DEVICE</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="device-name">DEY DEVICE</div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
@ -69,6 +68,14 @@ Digi Demo - Multimedia
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li id="section_network">
|
||||||
|
<a data-pjax href="network.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">
|
||||||
|
<span class="digi-menu-icon fas fa-network-wired fa-fw fa-lg mr-3"></span>
|
||||||
|
<span class="menu-collapsed">Network</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li id="section_management">
|
<li id="section_management">
|
||||||
<a data-pjax href="management.html" 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">
|
||||||
|
|
@ -234,6 +241,7 @@ Digi Demo - Multimedia
|
||||||
<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/network.js"></script>
|
||||||
<script type="text/javascript" src="./static/js/multimedia.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/file-system.js"></script>
|
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,508 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>
|
||||||
|
Digi Demo - Network
|
||||||
|
</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="./static/css/stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||||
|
<link href="./static/css/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
||||||
|
<link href="./static/css/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/css/bootstrap-slider.min.css" rel="stylesheet">
|
||||||
|
<link href="./static/css/fontawesome5.15.4/all.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./static/css/general.css">
|
||||||
|
<link rel="stylesheet" href="./static/css/toastr.css">
|
||||||
|
|
||||||
|
<!-- JS, Popper.js, and jQuery -->
|
||||||
|
<script src="./static/js/code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||||
|
<script src="./static/js/cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||||
|
<script src="./static/js/stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||||
|
<script src="./static/js/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
|
||||||
|
<script src="./static/js/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/bootstrap-slider.min.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/common.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/devices.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/jquery.pjax.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/jquery.matchHeight-min.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/toastr.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav id="topBar" class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||||
|
<div class="nav-container">
|
||||||
|
<a id="banner-link" class="navbar-brand align-middle" href="/">
|
||||||
|
<div class="d-flex align-items-baseline">
|
||||||
|
<img id="banner-logo" class="banner-icon" src="./static/images/Digi_logo_banner.png">
|
||||||
|
<p id="banner-text">ConnectCore Demo</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="nav-right-container">
|
||||||
|
<div>
|
||||||
|
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||||
|
</div>
|
||||||
|
<div id="device-name">DEY DEVICE</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="bg-light" id="body-row">
|
||||||
|
|
||||||
|
<!-- Sidebar https://www.codeply.com/go/3e0RAjccRO/bootstrap-4-collapsing-sidebar-menu# -->
|
||||||
|
<div id="sidebar-container" class="sidebar-expanded d-none d-md-block">
|
||||||
|
<!-- d-* hides the Sidebar in smaller devices. Its items can be kept on the Navbar 'Menu' -->
|
||||||
|
<div id="sidebar-contents">
|
||||||
|
<!-- Bootstrap List Group -->
|
||||||
|
|
||||||
|
<ul id="sections" data-pjax class="list-group">
|
||||||
|
<li id="section_dashboard">
|
||||||
|
<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">
|
||||||
|
<span class="digi-menu-icon fas fa-tachometer-alt fa-fw fa-lg mr-3"></span>
|
||||||
|
<span class="menu-collapsed">Dashboard</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li id="section_multimedia">
|
||||||
|
<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">
|
||||||
|
<span class="digi-menu-icon fas fa-film fa-fw fa-lg mr-3"></span>
|
||||||
|
<span class="menu-collapsed">Multimedia</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li id="section_network">
|
||||||
|
<a data-pjax href="network.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">
|
||||||
|
<span class="digi-menu-icon fas fa-network-wired fa-fw fa-lg mr-3"></span>
|
||||||
|
<span class="menu-collapsed">Network</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li id="section_management">
|
||||||
|
<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">
|
||||||
|
<span class="digi-menu-icon fas fa-cog fa-fw fa-lg mr-3"></span>
|
||||||
|
<span class="menu-collapsed">Management</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul id="collapsator" class="list-group">
|
||||||
|
<a href="#top" data-toggle="sidebar-collapse" 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">
|
||||||
|
<span id="collapse-icon" class="digi-menu-icon fas fa-fw fa-lg mr-3"></span>
|
||||||
|
<span id="collapse-text" class="menu-collapsed">Collapse</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<div id="loading">
|
||||||
|
<img id="loading-image" src="./static/images/loading.gif" alt="Loading..." />
|
||||||
|
</div>
|
||||||
|
<div id="pjax-container">
|
||||||
|
<div class="row justify-content-lg-center">
|
||||||
|
<div class="col-lg-12 col-xl-12">
|
||||||
|
<div id="loading_popup" class="popup popup-loading shadow">
|
||||||
|
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||||
|
<div id="loading_popup_message" class="popup-text">Loading configuration...</div>
|
||||||
|
</div>
|
||||||
|
<div id="info_popup" class="popup popup-info shadow d-none">
|
||||||
|
<div id="info_popup_title" class="popup-title">Error</div>
|
||||||
|
<div id="info_popup_message" class="popup-text">-</div>
|
||||||
|
</div>
|
||||||
|
<div id="confirm_dialog" class="confirm-dialog d-none">
|
||||||
|
<div class="device-card-header">
|
||||||
|
<span class="fas fa-question-circle fa-lg mr-2"></span>
|
||||||
|
<span id="confirm_dialog_title"></span>
|
||||||
|
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="showPopup(ID_LOADING_WRAPPER, ID_CONFIRM_DIALOG, false)"></div>
|
||||||
|
</div>
|
||||||
|
<div id="confirm_dialog_message" class="confirm-dialog-message"></div>
|
||||||
|
<div class="confirm-dialog-buttons-container">
|
||||||
|
<div id="confirm_dialog_no_button" class="device-card-button confirm-dialog-button">No</div>
|
||||||
|
<div id="confirm_dialog_yes_button" class="device-card-button confirm-dialog-button">Yes</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="loading_wrapper" class="loading-wrapper">
|
||||||
|
<div class="card shadow-sm" style="padding: 0px">
|
||||||
|
<div id="eth0_panel_header" class="interface-header" style="cursor: pointer;" onclick="togglePanelVisibility('eth0')">
|
||||||
|
<span class="fas fa-ethernet fa-lg mr-2"></span>
|
||||||
|
<span id="eth0_title" class="card-title interface-title">Ethernet 0</span>
|
||||||
|
<div id="eth0_toggle_button" class="fas fa-caret-up fa-lg device-card-header-button"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth0_panel_container" class="interface-panel-container">
|
||||||
|
<div>Configure ethernet parameters.</div>
|
||||||
|
<div class="param-container">
|
||||||
|
<span class="param-label">MAC Address:</span>
|
||||||
|
<span id="eth0_mac" class="param-value"></span>
|
||||||
|
</div>
|
||||||
|
<div class="param-container">
|
||||||
|
<span class="param-label">Connected:</span>
|
||||||
|
<label class="switch-control">
|
||||||
|
<input id="eth0_enable" type="checkbox">
|
||||||
|
<span class="slider-control round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="eth0_ip_mode_param" class="param-container">
|
||||||
|
<span class="param-label">IP mode:</span>
|
||||||
|
<select name="eth0_ip_mode" id="eth0_ip_mode" class="select-control">
|
||||||
|
<option value="static">Static</option>
|
||||||
|
<option value="dhcp" selected="selected">DHCP</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="eth0_ip_addr_param" class="param-container">
|
||||||
|
<span class="param-label">IP address:</span>
|
||||||
|
<input id="eth0_ip_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth0_ip_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth0_subnet_mask_param" class="param-container">
|
||||||
|
<span class="param-label">Subnet mask:</span>
|
||||||
|
<input id="eth0_subnet_mask" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth0_subnet_mask_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth0_default_gateway_param" class="param-container">
|
||||||
|
<span class="param-label">Default gateway:</span>
|
||||||
|
<input id="eth0_default_gateway" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth0_default_gateway_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth0_dns1_addr_param" class="param-container">
|
||||||
|
<span class="param-label">DNS1 address:</span>
|
||||||
|
<input id="eth0_dns1_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth0_dns1_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth0_dns2_addr_param" class="param-container">
|
||||||
|
<span class="param-label">DNS2 address:</span>
|
||||||
|
<input id="eth0_dns2_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth0_dns2_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons-container">
|
||||||
|
<div id="eth0_refresh_button" class="device-card-button config-button" onclick="readConfiguration(['ethernet'], 'eth0')">Refresh</div>
|
||||||
|
<div id="eth0_save_button" class="device-card-button config-button config-button-disabled" onclick="saveInterface('ethernet', 'eth0')">Save</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="eth1" class="card shadow-sm" style="padding: 0px">
|
||||||
|
<div id="eth1_panel_header" class="interface-header" style="cursor: pointer;" onclick="togglePanelVisibility('eth1')">
|
||||||
|
<span class="fas fa-ethernet fa-lg mr-2"></span>
|
||||||
|
<span id="eth1_title" class="card-title interface-title">Ethernet 1</span>
|
||||||
|
<div id="eth1_toggle_button" class="fas fa-caret-down fa-lg device-card-header-button"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth1_panel_container" class="interface-panel-container" style="display: none;">
|
||||||
|
<div>Configure ethernet 1 parameters.</div>
|
||||||
|
<div class="param-container">
|
||||||
|
<span class="param-label">MAC Address:</span>
|
||||||
|
<span id="eth1_mac" class="param-value"></span>
|
||||||
|
</div>
|
||||||
|
<div class="param-container">
|
||||||
|
<span class="param-label">Connected:</span>
|
||||||
|
<label class="switch-control">
|
||||||
|
<input id="eth1_enable" type="checkbox">
|
||||||
|
<span class="slider-control round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="eth1_ip_mode_param" class="param-container">
|
||||||
|
<span class="param-label">IP mode:</span>
|
||||||
|
<select name="eth1_ip_mode" id="eth1_ip_mode" class="select-control">
|
||||||
|
<option value="static">Static</option>
|
||||||
|
<option value="dhcp" selected="selected">DHCP</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="eth1_ip_addr_param" class="param-container">
|
||||||
|
<span class="param-label">IP address:</span>
|
||||||
|
<input id="eth1_ip_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth1_ip_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth1_subnet_mask_param" class="param-container">
|
||||||
|
<span class="param-label">Subnet mask:</span>
|
||||||
|
<input id="eth1_subnet_mask" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth1_subnet_mask_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth1_default_gateway_param" class="param-container">
|
||||||
|
<span class="param-label">Default gateway:</span>
|
||||||
|
<input id="eth1_default_gateway" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth1_default_gateway_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth1_dns1_addr_param" class="param-container">
|
||||||
|
<span class="param-label">DNS1 address:</span>
|
||||||
|
<input id="eth1_dns1_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth1_dns1_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="eth1_dns2_addr_param" class="param-container">
|
||||||
|
<span class="param-label">DNS2 address:</span>
|
||||||
|
<input id="eth1_dns2_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="eth1_dns2_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons-container">
|
||||||
|
<div id="eth1_refresh_button" class="device-card-button config-button" onclick="readConfiguration(['ethernet'], 'eth1')">Refresh</div>
|
||||||
|
<div id="eth1_save_button" class="device-card-button config-button config-button-disabled" onclick="saveInterface('ethernet', 'eth1')">Save</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0" class="card shadow-sm" style="padding: 0px;">
|
||||||
|
<div id="wlan0_panel_header" class="interface-header" style="cursor: pointer;" onclick="togglePanelVisibility('wlan0')">
|
||||||
|
<span class="fas fa-wifi fa-lg mr-2"></span>
|
||||||
|
<span id="wlan0_title" class="card-title interface-title">Wi-Fi</span>
|
||||||
|
<div id="wlan0_toggle_button" class="fas fa-caret-down fa-lg device-card-header-button"></div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_panel_container" class="interface-panel-container" style="display: none;">
|
||||||
|
<div>Configure wifi parameters.</div>
|
||||||
|
<div class="param-container">
|
||||||
|
<span class="param-label">MAC Address:</span>
|
||||||
|
<span id="wlan0_mac" class="param-value"></span>
|
||||||
|
</div>
|
||||||
|
<div class="param-container">
|
||||||
|
<span class="param-label">Connected:</span>
|
||||||
|
<label class="switch-control">
|
||||||
|
<input id="wlan0_enable" type="checkbox">
|
||||||
|
<span class="slider-control round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_ssid_param" class="param-container">
|
||||||
|
<span class="param-label">SSID:</span>
|
||||||
|
<input id="wlan0_ssid" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="wlan0_ssid_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_enc_type_param" class="param-container">
|
||||||
|
<span class="param-label">Encryption type:</span>
|
||||||
|
<select name="wlan0_enc_type" id="wlan0_enc_type" class="select-control">
|
||||||
|
<option value="0">Open</option>
|
||||||
|
<option value="1">WPA</option>
|
||||||
|
<option value="2">WPA2</option>
|
||||||
|
<option value="3">WPA3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_password_param" class="param-container">
|
||||||
|
<span class="param-label">Password:</span>
|
||||||
|
<input id="wlan0_password" class="input-control input-control-wide" type="password"/>
|
||||||
|
<div id="wlan0_password_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_ip_mode_param" class="param-container">
|
||||||
|
<span class="param-label">IP mode:</span>
|
||||||
|
<select name="wlan0_ip_mode" id="wlan0_ip_mode" class="select-control">
|
||||||
|
<option value="static">Static</option>
|
||||||
|
<option value="dhcp" selected="selected">DHCP</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_ip_addr_param" class="param-container">
|
||||||
|
<span class="param-label">IP address:</span>
|
||||||
|
<input id="wlan0_ip_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="wlan0_ip_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_subnet_mask_param" class="param-container">
|
||||||
|
<span class="param-label">Subnet mask:</span>
|
||||||
|
<input id="wlan0_subnet_mask" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="wlan0_subnet_mask_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_default_gateway_param" class="param-container">
|
||||||
|
<span class="param-label">Default gateway:</span>
|
||||||
|
<input id="wlan0_default_gateway" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="wlan0_default_gateway_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_dns1_addr_param" class="param-container">
|
||||||
|
<span class="param-label">DNS1 address:</span>
|
||||||
|
<input id="wlan0_dns1_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="wlan0_dns1_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div id="wlan0_dns2_addr_param" class="param-container">
|
||||||
|
<span class="param-label">DNS2 address:</span>
|
||||||
|
<input id="wlan0_dns2_addr" class="input-control input-control-wide" type="text"/>
|
||||||
|
<div id="wlan0_dns2_addr_error" class="error-label"></div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons-container">
|
||||||
|
<div id="wlan0_refresh_button" class="device-card-button config-button" onclick="readConfiguration(['wifi'], 'wlan0')">Refresh</div>
|
||||||
|
<div id="wlan0_save_button" class="device-card-button config-button config-button-disabled" onclick="saveInterface('wifi', 'wlan0')">Save</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
// Reset variables.
|
||||||
|
readingNetworkInfo = false;
|
||||||
|
// Register input changed events.
|
||||||
|
$('#eth0_enable').click(function(){
|
||||||
|
updateInterfaceControls("eth0");
|
||||||
|
});
|
||||||
|
$("#eth0_ip_mode").on("change", function(event) {
|
||||||
|
updateInterfaceControls("eth0");
|
||||||
|
});
|
||||||
|
$("#eth0_ip_addr").on("input", function(event) {
|
||||||
|
validateInterface("eth0");
|
||||||
|
});
|
||||||
|
$("#eth0_subnet_mask").on("input", function(event) {
|
||||||
|
validateInterface("eth0");
|
||||||
|
});
|
||||||
|
$("#eth0_default_gateway").on("input", function(event) {
|
||||||
|
validateInterface("eth0");
|
||||||
|
});
|
||||||
|
$("#eth0_dns1_addr").on("input", function(event) {
|
||||||
|
validateInterface("eth0");
|
||||||
|
});
|
||||||
|
$("#eth0_dns2_addr").on("input", function(event) {
|
||||||
|
validateInterface("eth0");
|
||||||
|
});
|
||||||
|
$('#eth1_enable').click(function(){
|
||||||
|
updateInterfaceControls("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_ip_mode").on("change", function(event) {
|
||||||
|
updateInterfaceControls("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_ip_addr").on("input", function(event) {
|
||||||
|
validateInterface("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_subnet_mask").on("input", function(event) {
|
||||||
|
validateInterface("eth1");
|
||||||
|
});
|
||||||
|
$('#eth1_enable').click(function(){
|
||||||
|
updateInterfaceControls("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_ip_mode").on("change", function(event) {
|
||||||
|
updateInterfaceControls("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_ip_addr").on("input", function(event) {
|
||||||
|
validateInterface("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_subnet_mask").on("input", function(event) {
|
||||||
|
validateInterface("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_default_gateway").on("input", function(event) {
|
||||||
|
validateInterface("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_dns1_addr").on("input", function(event) {
|
||||||
|
validateInterface("eth1");
|
||||||
|
});
|
||||||
|
$("#eth1_dns2_addr").on("input", function(event) {
|
||||||
|
validateInterface("eth1");
|
||||||
|
});
|
||||||
|
$('#wlan0_enable').click(function(){
|
||||||
|
updateInterfaceControls("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_ssid").on("input", function(event) {
|
||||||
|
validateInterface("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_enc_type").on("change", function(event) {
|
||||||
|
document.getElementById("wlan0_password").value = "";
|
||||||
|
passwordChanged = true;
|
||||||
|
updateInterfaceControls("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_password").on("input", function(event) {
|
||||||
|
passwordChanged = true;
|
||||||
|
validateInterface("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_ip_mode").on("change", function(event) {
|
||||||
|
updateInterfaceControls("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_ip_addr").on("input", function(event) {
|
||||||
|
validateInterface("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_subnet_mask").on("input", function(event) {
|
||||||
|
validateInterface("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_default_gateway").on("input", function(event) {
|
||||||
|
validateInterface("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_dns1_addr").on("input", function(event) {
|
||||||
|
validateInterface("wlan0");
|
||||||
|
});
|
||||||
|
$("#wlan0_dns2_addr").on("input", function(event) {
|
||||||
|
validateInterface("wlan0");
|
||||||
|
});
|
||||||
|
// Gray out page.
|
||||||
|
document.getElementById("loading_wrapper").classList.add("element-grayed");
|
||||||
|
// Update all controls.
|
||||||
|
updateAllControls();
|
||||||
|
// Initialize page.
|
||||||
|
initializeNetworkPage();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</div> <!-- pjax-container -->
|
||||||
|
|
||||||
|
</div> <!-- container fluid -->
|
||||||
|
</div> <!--bg light -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#banner-link").on({
|
||||||
|
"mouseover" : function() {
|
||||||
|
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner_gray.png");
|
||||||
|
},
|
||||||
|
"mouseout" : function() {
|
||||||
|
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner.png");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enable the tooltip library.
|
||||||
|
$(function() {
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Local JS files and functions -->
|
||||||
|
<script type="text/javascript" src="./static/js/sidebar.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/ccmp157-dvk.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/ccimx6ulsbc.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/ccimx8mm-dvk.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/dashboard.js"></script>
|
||||||
|
<script type="text/javascript" src="./static/js/network.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/file-system.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
// Don't show the loading spinner at the beginning. Initial page
|
||||||
|
// load is full, so not relying on AJAX.
|
||||||
|
$("#loading").hide();
|
||||||
|
|
||||||
|
// Set up PJAX.
|
||||||
|
if ($.support.pjax) {
|
||||||
|
$.pjax.defaults.timeout = 20000;
|
||||||
|
$.pjax.defaults.fragment = "#pjax-container";
|
||||||
|
$(document).pjax("a[data-pjax]", "#pjax-container");
|
||||||
|
|
||||||
|
$(document).on("pjax:beforeSend", function() {
|
||||||
|
// Do not load new content if there are unsaved changes.
|
||||||
|
if ($("#save-schedule").length && !$("#save-schedule").attr("disabled") && !confirm("There are unsaved changes. Do you want to exit?"))
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("pjax:send", function(e) {
|
||||||
|
setSelectedSection(e.currentTarget.activeElement);
|
||||||
|
$("#pjax-container").hide();
|
||||||
|
$("#loading").show();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("pjax:complete", function() {
|
||||||
|
$("#loading").hide();
|
||||||
|
$("#pjax-container").show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the URL parameters to the section links.
|
||||||
|
var params = new URLSearchParams(window.location.search).toString();
|
||||||
|
if (params) {
|
||||||
|
$("#sections li").each(function(i, n) {
|
||||||
|
n.children[0].href += "?" + params;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update available sections.
|
||||||
|
updateAvailableSections();
|
||||||
|
|
||||||
|
// Set the selected section.
|
||||||
|
setSelectedSection();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -373,7 +373,7 @@ body {
|
||||||
/* POPUP */
|
/* POPUP */
|
||||||
.popup {
|
.popup {
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
position: absolute;
|
position: fixed;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
background-color: white;
|
background-color: white;
|
||||||
padding: 20px 10px;
|
padding: 20px 10px;
|
||||||
|
|
@ -1895,6 +1895,11 @@ body {
|
||||||
width: 170px;
|
width: 170px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.param-value {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.input-control {
|
.input-control {
|
||||||
position: relative;
|
position: relative;
|
||||||
-webkit-transition: none !important;
|
-webkit-transition: none !important;
|
||||||
|
|
@ -1905,12 +1910,99 @@ body {
|
||||||
width: 80px !important;
|
width: 80px !important;
|
||||||
padding: 0px !important;
|
padding: 0px !important;
|
||||||
margin: 0px !important;
|
margin: 0px !important;
|
||||||
|
text-align: left !important;
|
||||||
|
padding-left: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-control-wide {
|
||||||
|
width: 180px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-control-error {
|
.input-control-error {
|
||||||
background-color: #f3b1b1 !important;
|
background-color: #f3b1b1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-control-disabled {
|
||||||
|
background-color: transparent !important;
|
||||||
|
border: none !important;
|
||||||
|
pointer-events: none !important;
|
||||||
|
color: #939393 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-control {
|
||||||
|
position: relative;
|
||||||
|
-webkit-transition: none !important;
|
||||||
|
-moz-transition: none !important;
|
||||||
|
-ms-transition: none !important;
|
||||||
|
-o-transition: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
width: 80px !important;
|
||||||
|
padding: 0px !important;
|
||||||
|
margin: 0px !important;
|
||||||
|
text-align-last: left !important;
|
||||||
|
padding-left: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-control {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 48px;
|
||||||
|
height: 22px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-control input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-control {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #ccc;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-control:before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
left: 3px;
|
||||||
|
bottom: 3px;
|
||||||
|
background-color: white;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider-control {
|
||||||
|
background-color: #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus + .slider-control {
|
||||||
|
box-shadow: 0 0 1px #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider-control:before {
|
||||||
|
-webkit-transform: translateX(26px);
|
||||||
|
-ms-transform: translateX(26px);
|
||||||
|
transform: translateX(26px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-control.round {
|
||||||
|
border-radius: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-control.round:before {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
.error-label {
|
.error-label {
|
||||||
color: red;
|
color: red;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
@ -1919,6 +2011,11 @@ body {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.buttons-container {
|
||||||
|
with: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.config-button {
|
.config-button {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
@ -1935,6 +2032,43 @@ body {
|
||||||
background-color: #c3c3c3;
|
background-color: #c3c3c3;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type=text], input[type=password], select {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
border: none;
|
||||||
|
color: #0d0d0d;
|
||||||
|
padding: 12px 30px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0px 0px 25px 0px;
|
||||||
|
width: 85%;
|
||||||
|
border: 2px solid #f6f6f6;
|
||||||
|
-webkit-transition: all 0.5s ease-in-out;
|
||||||
|
-moz-transition: all 0.5s ease-in-out;
|
||||||
|
-ms-transition: all 0.5s ease-in-out;
|
||||||
|
-o-transition: all 0.5s ease-in-out;
|
||||||
|
transition: all 0.5s ease-in-out;
|
||||||
|
-webkit-border-radius: 5px 5px 5px 5px;
|
||||||
|
border-radius: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text]:focus, input[type=password]:focus, select:focus {
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 2px solid var(--digi-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
-moz-appearance:none; /* Firefox */
|
||||||
|
-webkit-appearance:none; /* Safari and Chrome */
|
||||||
|
appearance:none;
|
||||||
|
text-align-last: center;
|
||||||
|
background-image: url("../images/combo_arrow_gray.png");
|
||||||
|
background-repeat: no-repeat, repeat;
|
||||||
|
background-position: right .7em top 50%;
|
||||||
|
background-size: .65em auto;
|
||||||
|
}
|
||||||
/* END CONFIG CONTROLS */
|
/* END CONFIG CONTROLS */
|
||||||
|
|
||||||
/* MANAGEMENT */
|
/* MANAGEMENT */
|
||||||
|
|
@ -2206,3 +2340,20 @@ body {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
/* END MANAGEMENT */
|
/* END MANAGEMENT */
|
||||||
|
|
||||||
|
/* NETWORK */
|
||||||
|
.interface-header {
|
||||||
|
padding: 15px 20px 10px 20px;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interface-panel-container {
|
||||||
|
padding: 0px 20px 15px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.interface-title {
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
/* END NETWORK */
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ const ID_CPU_TEMPERATURE = "cpu_temperature";
|
||||||
const ID_CPU_UPTIME = "cpu_uptime";
|
const ID_CPU_UPTIME = "cpu_uptime";
|
||||||
const ID_CURRENT_DIR = "current_dir";
|
const ID_CURRENT_DIR = "current_dir";
|
||||||
const ID_DATA = "data";
|
const ID_DATA = "data";
|
||||||
|
const ID_DESC = "desc";
|
||||||
const ID_DEVICE_NAME = "device-name";
|
const ID_DEVICE_NAME = "device-name";
|
||||||
const ID_DEVICE_TYPE = "device_type";
|
const ID_DEVICE_TYPE = "device_type";
|
||||||
const ID_DEVICES = "devices";
|
const ID_DEVICES = "devices";
|
||||||
|
|
@ -133,9 +134,12 @@ const VALUE_SUCCESSFUL = "successful";
|
||||||
const VALUE_TOP = "top";
|
const VALUE_TOP = "top";
|
||||||
const VALUE_UNKNOWN = "unknown";
|
const VALUE_UNKNOWN = "unknown";
|
||||||
|
|
||||||
|
const CLASS_ARROW_DOWN = "fa-caret-down";
|
||||||
|
const CLASS_ARROW_UP = "fa-caret-up";
|
||||||
const CLASS_D_NONE = "d-none";
|
const CLASS_D_NONE = "d-none";
|
||||||
const CLASS_DISABLED_DIV = "disabled-div";
|
const CLASS_DISABLED_DIV = "disabled-div";
|
||||||
const CLASS_ELEMENT_GRAYED = "element-grayed";
|
const CLASS_ELEMENT_GRAYED = "element-grayed";
|
||||||
|
const CLASS_INPUT_DISABLED = "input-control-disabled";
|
||||||
const CLASS_INPUT_ERROR = "input-control-error";
|
const CLASS_INPUT_ERROR = "input-control-error";
|
||||||
const CLASS_CONFIG_BUTTON_DISABLED = "config-button-disabled";
|
const CLASS_CONFIG_BUTTON_DISABLED = "config-button-disabled";
|
||||||
const CLASS_SELECTED = "selected";
|
const CLASS_SELECTED = "selected";
|
||||||
|
|
@ -487,6 +491,11 @@ function isDashboardShowing() {
|
||||||
return window.location.pathname.indexOf("index") > -1;
|
return window.location.pathname.indexOf("index") > -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether the network page is showing or not.
|
||||||
|
function isNetworkShowing() {
|
||||||
|
return window.location.pathname.indexOf("network") > -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns whether the management page is showing or not.
|
// Returns whether the management page is showing or not.
|
||||||
function isManagementShowing() {
|
function isManagementShowing() {
|
||||||
return window.location.pathname.indexOf("management") > -1;
|
return window.location.pathname.indexOf("management") > -1;
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,6 @@ const STREAM_BT_STATE = PREFIX_STREAM + IFACE_BT + "/state";
|
||||||
const PANEL_ARROW_WIDTH_100 = 20;
|
const PANEL_ARROW_WIDTH_100 = 20;
|
||||||
const PANEL_BOARD_WIDTH_100 = 1200;
|
const PANEL_BOARD_WIDTH_100 = 1200;
|
||||||
|
|
||||||
const CLASS_ARROW_DOWN = "fa-caret-down";
|
|
||||||
const CLASS_ARROW_UP = "fa-caret-up";
|
|
||||||
const CLASS_LED_PANEL_AREA_ON = "led-panel-area-on";
|
const CLASS_LED_PANEL_AREA_ON = "led-panel-area-on";
|
||||||
const CLASS_PANEL_AREA_SELECTED = "panel-area-selected";
|
const CLASS_PANEL_AREA_SELECTED = "panel-area-selected";
|
||||||
const CLASS_PANEL_AREA_ICON_SELECTED = "panel-area-icon-selected";
|
const CLASS_PANEL_AREA_ICON_SELECTED = "panel-area-icon-selected";
|
||||||
|
|
|
||||||
|
|
@ -325,6 +325,11 @@ class ConnectCoreDevice {
|
||||||
return this.#ethernetIP[index];
|
return this.#ethernetIP[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether the device supports Wifi or not.
|
||||||
|
hasWifi() {
|
||||||
|
return this.#wifiMAC != null && this.#wifiMAC != "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the device WiFi MAC address.
|
// Returns the device WiFi MAC address.
|
||||||
getWifiMAC() {
|
getWifiMAC() {
|
||||||
return this.#wifiMAC;
|
return this.#wifiMAC;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,459 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022, Digi International Inc.
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Constants.
|
||||||
|
const ELEMENT_ETHERNET = "ethernet";
|
||||||
|
const ELEMENT_WIFI = "wifi";
|
||||||
|
|
||||||
|
const FIELD_DEFAULT_GATEWAY = "_default_gateway";
|
||||||
|
const FIELD_DNS1_ADDRESS = "_dns1_addr";
|
||||||
|
const FIELD_DNS2_ADDRESS = "_dns2_addr";
|
||||||
|
const FIELD_ENABLE = "_enable";
|
||||||
|
const FIELD_ENCRYPTION_TYPE = "_enc_type";
|
||||||
|
const FIELD_ERROR = "_error";
|
||||||
|
const FIELD_MAC_ADDRESS = "_mac";
|
||||||
|
const FIELD_IP_ADDRESS = "_ip_addr";
|
||||||
|
const FIELD_IP_MODE = "_ip_mode";
|
||||||
|
const FIELD_PARAM = "_param";
|
||||||
|
const FIELD_PASSWORD = "_password";
|
||||||
|
const FIELD_SAVE_BUTTON = "_save_button";
|
||||||
|
const FIELD_SSID = "_ssid";
|
||||||
|
const FIELD_SUBNET_MASK = "_subnet_mask";
|
||||||
|
|
||||||
|
const ID_DNS1 = "dns1";
|
||||||
|
const ID_DNS2 = "dns2";
|
||||||
|
const ID_ENABLE = "enable";
|
||||||
|
const ID_ETH0_TITLE = "eth0_title";
|
||||||
|
const ID_GATEWAY = "gateway";
|
||||||
|
const ID_IP = "ip";
|
||||||
|
const ID_IP_MODE = "type";
|
||||||
|
const ID_INTERFACE = "interface";
|
||||||
|
const ID_MAC = "mac";
|
||||||
|
const ID_NETMASK = "netmask";
|
||||||
|
const ID_PANEL_CONTAINER = "_panel_container";
|
||||||
|
const ID_PASSWORD = "psk";
|
||||||
|
const ID_SECURITY_MODE = "sec_mode";
|
||||||
|
const ID_SSID = "ssid";
|
||||||
|
const ID_TOGGLE_BUTTON = "_toggle_button";
|
||||||
|
|
||||||
|
const IP_MODE_DHCP = "dhcp";
|
||||||
|
const IP_MODE_STATIC = "static";
|
||||||
|
|
||||||
|
const ERROR_IP_VALUE_FORMAT = "Value must follow this format: XXX.XXX.XXX.XXX";
|
||||||
|
const ERROR_PASSWORD_INVALID = "Password must be between 8 and 63 characters long";
|
||||||
|
const ERROR_SSID_INVALID = "SSID value is not valid";
|
||||||
|
const ERROR_UNKNOWN = "Unknown error saving configuration.";
|
||||||
|
|
||||||
|
const MESSAGE_LOADING_CONFIGURATION = "Loading configuration...";
|
||||||
|
const MESSAGE_SAVING_CONFIGURATION = "Saving configuration...";
|
||||||
|
const MESSAGE_CONFIGURATION_SAVED = "Configuration saved successfully!";
|
||||||
|
|
||||||
|
const PREFIX_ETHERNET = "eth";
|
||||||
|
const PREFIX_WIFI = "wlan";
|
||||||
|
|
||||||
|
const REGEX_IP = '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$';
|
||||||
|
const REGEX_SSID = '^[^!#;+\\]/"\t][^+\\]/"\t]{0,31}$';
|
||||||
|
const REGEX_PASSWORD = '^[\u0020-\u007e]{8,63}$';
|
||||||
|
|
||||||
|
const ALL_ELEMENTS = "all";
|
||||||
|
|
||||||
|
// Variables.
|
||||||
|
var readingNetworkInfo = false;
|
||||||
|
var passwordChanged = false;
|
||||||
|
|
||||||
|
// Initializes the network page.
|
||||||
|
function initializeNetworkPage() {
|
||||||
|
// Sanity checks.
|
||||||
|
if (!isNetworkShowing())
|
||||||
|
return;
|
||||||
|
// Read network configuration.
|
||||||
|
readElements = [ELEMENT_ETHERNET, ELEMENT_WIFI];
|
||||||
|
readConfiguration(readElements, ALL_ELEMENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the device configuration the given elements.
|
||||||
|
function readConfiguration(readElements, parseElement) {
|
||||||
|
// Execute only in the network page.
|
||||||
|
if (!isNetworkShowing() || readingNetworkInfo)
|
||||||
|
return;
|
||||||
|
// Flag reading variable.
|
||||||
|
readingNetworkInfo = true;
|
||||||
|
// Hide the info popup.
|
||||||
|
showInfoPopup(false);
|
||||||
|
// Show the loading popup.
|
||||||
|
showLoadingPopup(true, MESSAGE_LOADING_CONFIGURATION);
|
||||||
|
// Send request to retrieve configuration.
|
||||||
|
$.post(
|
||||||
|
"http://" + getServerAddress() + "/ajax/get_config",
|
||||||
|
JSON.stringify({
|
||||||
|
"elements": readElements
|
||||||
|
}),
|
||||||
|
function(data) {
|
||||||
|
// Process only in the network page.
|
||||||
|
if (!isNetworkShowing())
|
||||||
|
return;
|
||||||
|
// Process answer.
|
||||||
|
processReadConfigurationResponse(data, parseElement);
|
||||||
|
}
|
||||||
|
).fail(function(response) {
|
||||||
|
// Flag reading variable.
|
||||||
|
readingNetworkInfo = false;
|
||||||
|
// Clear the element being read.
|
||||||
|
elementReading = "";
|
||||||
|
// Process only in the network page.
|
||||||
|
if (!isNetworkShowing())
|
||||||
|
return;
|
||||||
|
// Hide the loading panel.
|
||||||
|
showLoadingPopup(false);
|
||||||
|
// Process error.
|
||||||
|
processAjaxErrorResponse(response);
|
||||||
|
// Update controls.
|
||||||
|
updateAllControls();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processes the response of the read configuration request.
|
||||||
|
function processReadConfigurationResponse(response, parseElement) {
|
||||||
|
// Check if there was any error in the request.
|
||||||
|
if (!checkErrorResponse(response, false)) {
|
||||||
|
// Fill network info.
|
||||||
|
fillNetworkInfo(JSON.parse(response[ID_DATA]), parseElement);
|
||||||
|
} else {
|
||||||
|
// Flag reading variable.
|
||||||
|
readingNetworkInfo = false;
|
||||||
|
// Hide the loading panel.
|
||||||
|
showLoadingPopup(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fills network information.
|
||||||
|
function fillNetworkInfo(response, parseElement) {
|
||||||
|
var numEthernetIfaces = 0;
|
||||||
|
var numWifiIfaces = 0;
|
||||||
|
for (const [element, elementData] of Object.entries(response)) {
|
||||||
|
if (element != ELEMENT_ETHERNET && element != ELEMENT_WIFI)
|
||||||
|
continue;
|
||||||
|
for (const [iface, ifaceData] of Object.entries(elementData)) {
|
||||||
|
if (!iface.startsWith(PREFIX_WIFI) && !iface.startsWith(PREFIX_ETHERNET))
|
||||||
|
continue;
|
||||||
|
if (parseElement != ALL_ELEMENTS && iface != parseElement)
|
||||||
|
continue;
|
||||||
|
var enabled = ifaceData[ID_ENABLE];
|
||||||
|
var ipMode = ifaceData[ID_IP_MODE];
|
||||||
|
if (iface.startsWith(PREFIX_ETHERNET))
|
||||||
|
numEthernetIfaces += 1;
|
||||||
|
else if (iface.startsWith(PREFIX_WIFI))
|
||||||
|
numWifiIfaces += 1;
|
||||||
|
// Fill MAC.
|
||||||
|
document.getElementById(iface + FIELD_MAC_ADDRESS).innerText = ifaceData[ID_MAC];
|
||||||
|
// Set enable state.
|
||||||
|
document.getElementById(iface + FIELD_ENABLE).checked = enabled;
|
||||||
|
// Set IP mode.
|
||||||
|
if (ipMode == 0)
|
||||||
|
document.getElementById(iface + FIELD_IP_MODE).value = IP_MODE_STATIC;
|
||||||
|
else
|
||||||
|
document.getElementById(iface + FIELD_IP_MODE).value = IP_MODE_DHCP;
|
||||||
|
// Fill the rest of the fields.
|
||||||
|
document.getElementById(iface + FIELD_IP_ADDRESS).value = ifaceData[ID_IP];
|
||||||
|
document.getElementById(iface + FIELD_SUBNET_MASK).value = ifaceData[ID_NETMASK];
|
||||||
|
document.getElementById(iface + FIELD_DEFAULT_GATEWAY).value = ifaceData[ID_GATEWAY];
|
||||||
|
document.getElementById(iface + FIELD_DNS1_ADDRESS).value = ifaceData[ID_DNS1];
|
||||||
|
document.getElementById(iface + FIELD_DNS2_ADDRESS).value = ifaceData[ID_DNS2];
|
||||||
|
// Specific Wifi fields.
|
||||||
|
if (iface.startsWith(PREFIX_WIFI)) {
|
||||||
|
document.getElementById(iface + FIELD_SSID).value = ifaceData[ID_SSID];
|
||||||
|
document.getElementById(iface + FIELD_ENCRYPTION_TYPE).selectedIndex = ifaceData[ID_SECURITY_MODE];
|
||||||
|
if (ifaceData[ID_SECURITY_MODE] != 0)
|
||||||
|
document.getElementById(iface + FIELD_PASSWORD).value = "dummy_password";
|
||||||
|
passwordChanged = false;
|
||||||
|
}
|
||||||
|
// Update controls.
|
||||||
|
updateInterfaceControls(iface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update interfaces visibility.
|
||||||
|
if (parseElement == ALL_ELEMENTS) {
|
||||||
|
if (numEthernetIfaces == 1) {
|
||||||
|
document.getElementById(IFACE_ETH1).style.display = "none";
|
||||||
|
document.getElementById(ID_ETH0_TITLE).innerHTML = "Ethernet";
|
||||||
|
}
|
||||||
|
if (numWifiIfaces == 0)
|
||||||
|
document.getElementById(IFACE_WIFI).style.display = "none";
|
||||||
|
}
|
||||||
|
// Flag reading variable.
|
||||||
|
readingNetworkInfo = false;
|
||||||
|
// Hide the loading panel.
|
||||||
|
showLoadingPopup(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates all controls of the page.
|
||||||
|
function updateAllControls() {
|
||||||
|
updateInterfaceControls(IFACE_ETH0);
|
||||||
|
updateInterfaceControls(IFACE_ETH1);
|
||||||
|
updateInterfaceControls(IFACE_WIFI);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the given interface controls based on its configuration.
|
||||||
|
function updateInterfaceControls(iface) {
|
||||||
|
// Initialize variables.
|
||||||
|
var ipGroup = document.getElementById(iface + FIELD_IP_ADDRESS + FIELD_PARAM);
|
||||||
|
var ipField = document.getElementById(iface + FIELD_IP_ADDRESS);
|
||||||
|
var subnetGroup = document.getElementById(iface + FIELD_SUBNET_MASK + FIELD_PARAM);
|
||||||
|
var subnetField = document.getElementById(iface + FIELD_SUBNET_MASK);
|
||||||
|
var gatewayGroup = document.getElementById(iface + FIELD_DEFAULT_GATEWAY + FIELD_PARAM);
|
||||||
|
var gatewayField = document.getElementById(iface + FIELD_DEFAULT_GATEWAY);
|
||||||
|
var dns1Group = document.getElementById(iface + FIELD_DNS1_ADDRESS + FIELD_PARAM);
|
||||||
|
var dns1Field = document.getElementById(iface + FIELD_DNS1_ADDRESS);
|
||||||
|
var dns2Group = document.getElementById(iface + FIELD_DNS2_ADDRESS + FIELD_PARAM);
|
||||||
|
var dns2Field = document.getElementById(iface + FIELD_DNS2_ADDRESS);
|
||||||
|
var ipModeGroup = document.getElementById(iface + FIELD_IP_MODE + FIELD_PARAM);
|
||||||
|
var ipModeField = document.getElementById(iface + FIELD_IP_MODE);
|
||||||
|
var enableField = document.getElementById(iface + FIELD_ENABLE);
|
||||||
|
var enabled = enableField.checked;
|
||||||
|
var ipMode = ipModeField.value;
|
||||||
|
var ssidGroup, encryptionTypeGroup, encryptionTypeField, passwordGroup, usePassword;
|
||||||
|
if (iface.startsWith(PREFIX_WIFI)) {
|
||||||
|
ssidGroup = document.getElementById(iface + FIELD_SSID + FIELD_PARAM);
|
||||||
|
encryptionTypeGroup = document.getElementById(iface + FIELD_ENCRYPTION_TYPE + FIELD_PARAM);
|
||||||
|
encryptionTypeField = document.getElementById(iface + FIELD_ENCRYPTION_TYPE);
|
||||||
|
passwordGroup = document.getElementById(iface + FIELD_PASSWORD + FIELD_PARAM);
|
||||||
|
usePassword = encryptionTypeField.value != 0;
|
||||||
|
if (usePassword)
|
||||||
|
passwordGroup.style.display = "block";
|
||||||
|
else
|
||||||
|
passwordGroup.style.display = "none";
|
||||||
|
}
|
||||||
|
// Determine if IP fields can be edited.
|
||||||
|
if (ipMode == IP_MODE_DHCP) {
|
||||||
|
if (!ipField.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
ipField.classList.add(CLASS_INPUT_DISABLED);
|
||||||
|
if (!subnetField.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
subnetField.classList.add(CLASS_INPUT_DISABLED);
|
||||||
|
if (!gatewayField.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
gatewayField.classList.add(CLASS_INPUT_DISABLED);
|
||||||
|
if (!dns1Field.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
dns1Field.classList.add(CLASS_INPUT_DISABLED);
|
||||||
|
if (!dns2Field.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
dns2Field.classList.add(CLASS_INPUT_DISABLED);
|
||||||
|
} else if (ipMode == IP_MODE_STATIC) {
|
||||||
|
if (ipField.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
ipField.classList.remove(CLASS_INPUT_DISABLED);
|
||||||
|
if (subnetField.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
subnetField.classList.remove(CLASS_INPUT_DISABLED);
|
||||||
|
if (gatewayField.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
gatewayField.classList.remove(CLASS_INPUT_DISABLED);
|
||||||
|
if (dns1Field.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
dns1Field.classList.remove(CLASS_INPUT_DISABLED);
|
||||||
|
if (dns2Field.classList.contains(CLASS_INPUT_DISABLED))
|
||||||
|
dns2Field.classList.remove(CLASS_INPUT_DISABLED);
|
||||||
|
}
|
||||||
|
// Validate the network interface.
|
||||||
|
validateInterface(iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates the given network interface.
|
||||||
|
function validateInterface(iface) {
|
||||||
|
// Initialize vars.
|
||||||
|
var valid = true;
|
||||||
|
var saveButton = document.getElementById(iface + FIELD_SAVE_BUTTON);
|
||||||
|
var enableField = document.getElementById(iface + FIELD_ENABLE);
|
||||||
|
var ipModeField = document.getElementById(iface + FIELD_IP_MODE);
|
||||||
|
var ipField = document.getElementById(iface + FIELD_IP_ADDRESS);
|
||||||
|
var subnetField = document.getElementById(iface + FIELD_SUBNET_MASK);
|
||||||
|
var gatewayField = document.getElementById(iface + FIELD_DEFAULT_GATEWAY);
|
||||||
|
var dns1Field = document.getElementById(iface + FIELD_DNS1_ADDRESS);
|
||||||
|
var dns2Field = document.getElementById(iface + FIELD_DNS2_ADDRESS);
|
||||||
|
var ipMode = ipModeField.value;
|
||||||
|
var forceValid = false;
|
||||||
|
// Validate fields.
|
||||||
|
if (ipMode == IP_MODE_DHCP)
|
||||||
|
forceValid = true;
|
||||||
|
valid &= validateIPField(iface + FIELD_IP_ADDRESS, iface + FIELD_IP_ADDRESS + FIELD_ERROR, forceValid);
|
||||||
|
valid &= validateIPField(iface + FIELD_SUBNET_MASK, iface + FIELD_SUBNET_MASK + FIELD_ERROR, forceValid);
|
||||||
|
valid &= validateIPField(iface + FIELD_DEFAULT_GATEWAY, iface + FIELD_DEFAULT_GATEWAY + FIELD_ERROR, forceValid);
|
||||||
|
valid &= validateIPField(iface + FIELD_DNS1_ADDRESS, iface + FIELD_DNS1_ADDRESS + FIELD_ERROR, forceValid);
|
||||||
|
valid &= validateIPField(iface + FIELD_DNS2_ADDRESS, iface + FIELD_DNS2_ADDRESS + FIELD_ERROR, forceValid);
|
||||||
|
if (iface.startsWith(PREFIX_WIFI)) {
|
||||||
|
valid &= validateField(iface + FIELD_SSID, iface + FIELD_SSID + FIELD_ERROR, REGEX_SSID, ERROR_SSID_INVALID, false);
|
||||||
|
if (parseInt(document.getElementById(iface + FIELD_ENCRYPTION_TYPE).value) != 0)
|
||||||
|
valid &= validateField(iface + FIELD_PASSWORD, iface + FIELD_PASSWORD + FIELD_ERROR, REGEX_PASSWORD, ERROR_PASSWORD_INVALID, false);
|
||||||
|
}
|
||||||
|
// Check errors.
|
||||||
|
if (!valid) {
|
||||||
|
if (!saveButton.classList.contains(CLASS_CONFIG_BUTTON_DISABLED))
|
||||||
|
saveButton.classList.add(CLASS_CONFIG_BUTTON_DISABLED);
|
||||||
|
} else {
|
||||||
|
if (saveButton.classList.contains(CLASS_CONFIG_BUTTON_DISABLED))
|
||||||
|
saveButton.classList.remove(CLASS_CONFIG_BUTTON_DISABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates the given IP field.
|
||||||
|
function validateIPField(fieldID, errorID, forceValid) {
|
||||||
|
return validateField(fieldID, errorID, REGEX_IP, ERROR_IP_VALUE_FORMAT, forceValid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates the given field.
|
||||||
|
function validateField(fieldID, errorID, regexPattern, errorMessage, forceValid) {
|
||||||
|
// Initialize vars.
|
||||||
|
var field = document.getElementById(fieldID);
|
||||||
|
var fieldError = document.getElementById(errorID);
|
||||||
|
var isValid = true;
|
||||||
|
var error = "";
|
||||||
|
// Sanity checks.
|
||||||
|
if (field == null || fieldError == null)
|
||||||
|
return false;
|
||||||
|
// Check if value is valid.
|
||||||
|
if (!forceValid) {
|
||||||
|
var value = field.value;
|
||||||
|
if (value.length == 0) {
|
||||||
|
isValid = false;
|
||||||
|
error = ERROR_FIELD_EMPTY;
|
||||||
|
} else if (!value.match(regexPattern)) {
|
||||||
|
isValid = false;
|
||||||
|
error = errorMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update controls.
|
||||||
|
if (isValid) {
|
||||||
|
if (field.classList.contains(CLASS_INPUT_ERROR))
|
||||||
|
field.classList.remove(CLASS_INPUT_ERROR);
|
||||||
|
fieldError.innerHTML = " ";
|
||||||
|
fieldError.style.display = "none";
|
||||||
|
} else {
|
||||||
|
if (!field.classList.contains(CLASS_INPUT_ERROR))
|
||||||
|
field.classList.add(CLASS_INPUT_ERROR);
|
||||||
|
fieldError.innerHTML = error;
|
||||||
|
fieldError.style.display = "block";
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the given network interface form data.
|
||||||
|
function getInterfaceData(element, iface) {
|
||||||
|
// Initialize variables.
|
||||||
|
var data = {};
|
||||||
|
var ifaceData = {};
|
||||||
|
var networkData = {};
|
||||||
|
var enable = document.getElementById(iface + FIELD_ENABLE).checked;
|
||||||
|
var ipMode = document.getElementById(iface + FIELD_IP_MODE).value;
|
||||||
|
// Fill network data.
|
||||||
|
networkData[ID_ENABLE] = enable;
|
||||||
|
if (ipMode == IP_MODE_STATIC) {
|
||||||
|
networkData[ID_IP_MODE] = 0;
|
||||||
|
networkData[ID_IP] = document.getElementById(iface + FIELD_IP_ADDRESS).value;
|
||||||
|
networkData[ID_NETMASK] = document.getElementById(iface + FIELD_SUBNET_MASK).value;
|
||||||
|
networkData[ID_GATEWAY] = document.getElementById(iface + FIELD_DEFAULT_GATEWAY).value;
|
||||||
|
networkData[ID_DNS1] = document.getElementById(iface + FIELD_DNS1_ADDRESS).value;
|
||||||
|
networkData[ID_DNS2] = document.getElementById(iface + FIELD_DNS2_ADDRESS).value;
|
||||||
|
} else {
|
||||||
|
networkData[ID_IP_MODE] = 1;
|
||||||
|
}
|
||||||
|
if (iface.startsWith(PREFIX_WIFI)) {
|
||||||
|
networkData[ID_SSID] = document.getElementById(iface + FIELD_SSID).value;
|
||||||
|
networkData[ID_SECURITY_MODE] = parseInt(document.getElementById(iface + FIELD_ENCRYPTION_TYPE).value);
|
||||||
|
if (networkData[ID_SECURITY_MODE] != 0 && passwordChanged)
|
||||||
|
networkData[ID_PASSWORD] = document.getElementById(iface + FIELD_PASSWORD).value;
|
||||||
|
}
|
||||||
|
ifaceData[iface] = networkData;
|
||||||
|
data[element] = ifaceData;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saves the network settings for the given interface.
|
||||||
|
function saveInterface(element, iface) {
|
||||||
|
// Execute only in the network page.
|
||||||
|
if (!isNetworkShowing())
|
||||||
|
return;
|
||||||
|
// Hide the info popup.
|
||||||
|
showInfoPopup(false);
|
||||||
|
// Show the loading popup.
|
||||||
|
showLoadingPopup(true, MESSAGE_SAVING_CONFIGURATION);
|
||||||
|
// Send request to set new configuration.
|
||||||
|
$.post(
|
||||||
|
"http://" + getServerAddress() + "/ajax/set_config",
|
||||||
|
JSON.stringify({
|
||||||
|
"configuration": getInterfaceData(element, iface)
|
||||||
|
}),
|
||||||
|
function(data) {
|
||||||
|
// Process only in the network page.
|
||||||
|
if (!isNetworkShowing())
|
||||||
|
return;
|
||||||
|
// Process answer.
|
||||||
|
processSaveInterfaceResponse(data, element, iface);
|
||||||
|
}
|
||||||
|
).fail(function(response) {
|
||||||
|
// Process only in the network page.
|
||||||
|
if (!isNetworkShowing())
|
||||||
|
return;
|
||||||
|
// Hide the loading panel.
|
||||||
|
showLoadingPopup(false);
|
||||||
|
// Process error.
|
||||||
|
processAjaxErrorResponse(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processes the save network request response.
|
||||||
|
function processSaveInterfaceResponse(response, element, iface) {
|
||||||
|
// Check for error in the response.
|
||||||
|
if (!checkErrorResponse(response, false)) {
|
||||||
|
var statusFound = false;
|
||||||
|
// Check status in the response.
|
||||||
|
if (response[ID_DATA] != null) {
|
||||||
|
data = JSON.parse(response[ID_DATA]);
|
||||||
|
for (const [elementEntry, elementData] of Object.entries(data)) {
|
||||||
|
if (elementEntry != element)
|
||||||
|
continue;
|
||||||
|
for (const [ifaceEntry, ifaceData] of Object.entries(elementData)) {
|
||||||
|
if (ifaceEntry != iface)
|
||||||
|
continue;
|
||||||
|
if (ifaceData[ID_STATUS] != null) {
|
||||||
|
statusFound = true;
|
||||||
|
if (ifaceData[ID_STATUS] != 0)
|
||||||
|
toastr.error(ifaceData[ID_DESC]);
|
||||||
|
else
|
||||||
|
toastr.success(MESSAGE_CONFIGURATION_SAVED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!statusFound)
|
||||||
|
toastr.error(ERROR_UNKNOWN);
|
||||||
|
}
|
||||||
|
// Hide the loading panel.
|
||||||
|
showLoadingPopup(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggles the visibility of the given interface panel.
|
||||||
|
function togglePanelVisibility(interface) {
|
||||||
|
// Initialize variables.
|
||||||
|
var panelButton = document.getElementById(interface + ID_TOGGLE_BUTTON);
|
||||||
|
// Sanity checks.
|
||||||
|
if (panelButton == null)
|
||||||
|
return;
|
||||||
|
// Check visibility.
|
||||||
|
if (panelButton.classList.contains(CLASS_ARROW_UP)) {
|
||||||
|
$("#" + interface + ID_PANEL_CONTAINER).slideUp("fast", function() {
|
||||||
|
panelButton.classList.remove(CLASS_ARROW_UP);
|
||||||
|
panelButton.classList.add(CLASS_ARROW_DOWN);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$("#" + interface + ID_PANEL_CONTAINER).slideDown("fast", function() {
|
||||||
|
panelButton.classList.remove(CLASS_ARROW_DOWN);
|
||||||
|
panelButton.classList.add(CLASS_ARROW_UP);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue