fixed apn and improved javascripts
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
<script src="/js/utils/reboot.js"></script>
|
<script src="/js/utils/reboot.js"></script>
|
||||||
<script src="/js/utils/restart-connection.js"></script>
|
<script src="/js/utils/restart-connection.js"></script>
|
||||||
<script defer src="/js/auth/auth.js"></script>
|
<script defer src="/js/auth/auth.js"></script>
|
||||||
|
<script src="/js/band-locking/fetch-bands.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
@@ -140,7 +141,7 @@
|
|||||||
<div class="column-margin">
|
<div class="column-margin">
|
||||||
<div class="fixed-grid has-2-cols has-1-cols-mobile">
|
<div class="fixed-grid has-2-cols has-1-cols-mobile">
|
||||||
<div class="grid is-gap-5">
|
<div class="grid is-gap-5">
|
||||||
<div class="cell">
|
<div class="cell is-col-span-2 is-col-span-1-mobile">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-header-title">4G LTE Band Locking</div>
|
<div class="card-header-title">4G LTE Band Locking</div>
|
||||||
@@ -175,7 +176,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell">
|
<!-- <div class="cell">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-header-title">5G-NR SA Band Locking</div>
|
<div class="card-header-title">5G-NR SA Band Locking</div>
|
||||||
@@ -183,7 +184,6 @@
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="fixed-grid has-5-cols has-3-cols-mobile">
|
<div class="fixed-grid has-5-cols has-3-cols-mobile">
|
||||||
<div class="grid" id="sa_bands">
|
<div class="grid" id="sa_bands">
|
||||||
<!-- SA bands will be populated here -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -208,7 +208,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@@ -335,7 +335,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<!-- <script>
|
||||||
// Function to fetch current active bands and display them in the footer
|
// Function to fetch current active bands and display them in the footer
|
||||||
async function fetchCurrentBands() {
|
async function fetchCurrentBands() {
|
||||||
try {
|
try {
|
||||||
@@ -385,13 +385,13 @@
|
|||||||
|
|
||||||
const lteBandsMatch = data.output.match(/"lte_band",([0-9:]+)/);
|
const lteBandsMatch = data.output.match(/"lte_band",([0-9:]+)/);
|
||||||
const nsaBandsMatch = data.output.match(/"nsa_nr5g_band",([0-9:]+)/);
|
const nsaBandsMatch = data.output.match(/"nsa_nr5g_band",([0-9:]+)/);
|
||||||
const saBandsMatch = data.output.match(/"nr5g_band",([0-9:]+)/);
|
// const saBandsMatch = data.output.match(/"nr5g_band",([0-9:]+)/);
|
||||||
const saDcBandsMatch = data.output.match(
|
const saDcBandsMatch = data.output.match(
|
||||||
/"nrdc_nr5g_band",([0-9:]+)/
|
/"nrdc_nr5g_band",([0-9:]+)/
|
||||||
);
|
);
|
||||||
|
|
||||||
if (lteBandsMatch) populateBands(lteBandsMatch[1], "#lte_bands");
|
if (lteBandsMatch) populateBands(lteBandsMatch[1], "#lte_bands");
|
||||||
if (saBandsMatch) populateBands(saBandsMatch[1], "#sa_bands");
|
// if (saBandsMatch) populateBands(saBandsMatch[1], "#sa_bands");
|
||||||
if (nsaBandsMatch) populateBands(nsaBandsMatch[1], "#nsa_bands");
|
if (nsaBandsMatch) populateBands(nsaBandsMatch[1], "#nsa_bands");
|
||||||
if (saDcBandsMatch) populateBands(saDcBandsMatch[1], "#sanrdc_bands");
|
if (saDcBandsMatch) populateBands(saDcBandsMatch[1], "#sanrdc_bands");
|
||||||
|
|
||||||
@@ -429,9 +429,9 @@
|
|||||||
const activeNsaBands = data.output
|
const activeNsaBands = data.output
|
||||||
.match(/"nsa_nr5g_band",([0-9:]+)/)[1]
|
.match(/"nsa_nr5g_band",([0-9:]+)/)[1]
|
||||||
.split(":");
|
.split(":");
|
||||||
const activeSaBands = data.output
|
// const activeSaBands = data.output
|
||||||
.match(/"nr5g_band",([0-9:]+)/)[1]
|
// .match(/"nr5g_band",([0-9:]+)/)[1]
|
||||||
.split(":");
|
// .split(":");
|
||||||
// get the the second to the last line of the output and use it for active sa-dc bands
|
// get the the second to the last line of the output and use it for active sa-dc bands
|
||||||
const activeSaDcBandsLine = data.output
|
const activeSaDcBandsLine = data.output
|
||||||
.split("\n")[6]
|
.split("\n")[6]
|
||||||
@@ -441,7 +441,7 @@
|
|||||||
// // Mark checkboxes as checked for active bands
|
// // Mark checkboxes as checked for active bands
|
||||||
markActiveBands(activeLteBands, "#lte_bands");
|
markActiveBands(activeLteBands, "#lte_bands");
|
||||||
markActiveBands(activeNsaBands, "#nsa_bands");
|
markActiveBands(activeNsaBands, "#nsa_bands");
|
||||||
markActiveBands(activeSaBands, "#sa_bands");
|
// markActiveBands(activeSaBands, "#sa_bands");
|
||||||
markActiveBands(activeSaDcBandsLine, "#sanrdc_bands");
|
markActiveBands(activeSaDcBandsLine, "#sanrdc_bands");
|
||||||
|
|
||||||
// Fetch current active bands and display them in the footer
|
// Fetch current active bands and display them in the footer
|
||||||
@@ -505,12 +505,12 @@
|
|||||||
uncheckAll("#nsa_bands");
|
uncheckAll("#nsa_bands");
|
||||||
});
|
});
|
||||||
|
|
||||||
document
|
// document
|
||||||
.getElementById("uncheckSa")
|
// .getElementById("uncheckSa")
|
||||||
.addEventListener("click", function (event) {
|
// .addEventListener("click", function (event) {
|
||||||
event.preventDefault();
|
// event.preventDefault();
|
||||||
uncheckAll("#sa_bands");
|
// uncheckAll("#sa_bands");
|
||||||
});
|
// });
|
||||||
|
|
||||||
document
|
document
|
||||||
.getElementById("uncheckSaDc")
|
.getElementById("uncheckSaDc")
|
||||||
@@ -675,6 +675,6 @@
|
|||||||
|
|
||||||
// Initial call to fetch supported bands on page load
|
// Initial call to fetch supported bands on page load
|
||||||
window.onload = fetchSupportedBands;
|
window.onload = fetchSupportedBands;
|
||||||
</script>
|
</script> -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ escape_json() {
|
|||||||
JSON_RESPONSE="["
|
JSON_RESPONSE="["
|
||||||
|
|
||||||
# List of AT commands to run, one by one
|
# List of AT commands to run, one by one
|
||||||
for COMMAND in "AT+QUIMSLOT?" "AT+CNUM" "AT+COPS?" "AT+CIMI" "AT+ICCID" "AT+CGSN" "AT+CPIN?" "AT+CGCONTRDP" "AT+CREG?" "AT+CFUN?" "AT+QENG=\"servingcell\"" "AT+QTEMP" "AT+CGCONTRDP" "AT+QCAINFO" "AT+QRSRP" 'AT+QMAP="WWAN"'; do
|
for COMMAND in "AT+QUIMSLOT?" "AT+CNUM" "AT+COPS?" "AT+CIMI" "AT+ICCID" "AT+CGSN" "AT+CPIN?" "AT+CGCONTRDP=1" "AT+CREG?" "AT+CFUN?" "AT+QENG=\"servingcell\"" "AT+QTEMP" "AT+CGCONTRDP" "AT+QCAINFO" "AT+QRSRP" 'AT+QMAP="WWAN"'; do
|
||||||
# Write the command to the input file
|
# Write the command to the input file
|
||||||
echo "$COMMAND" > "$INPUT_FILE"
|
echo "$COMMAND" > "$INPUT_FILE"
|
||||||
|
|
||||||
|
|||||||
@@ -1,461 +1,299 @@
|
|||||||
async function fetchCurrentSettings() {
|
// api.js - API related functions
|
||||||
try {
|
const api = {
|
||||||
const response = await fetch("/cgi-bin/advanced_settings.sh");
|
async fetch(endpoint, options = {}) {
|
||||||
if (!response.ok) {
|
try {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
const response = await fetch(endpoint, options);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`API Error (${endpoint}):`, error);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
const data = await response.json();
|
},
|
||||||
|
|
||||||
|
async fetchCurrentSettings() {
|
||||||
|
const data = await this.fetch("/cgi-bin/advanced_settings.sh");
|
||||||
console.log("Current settings:", data);
|
console.log("Current settings:", data);
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
},
|
||||||
console.error("Error fetching current settings:", error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchConnectedDevices() {
|
async fetchConnectedDevices() {
|
||||||
try {
|
const data = await this.fetch("/cgi-bin/fetch_macs.sh");
|
||||||
const response = await fetch("/cgi-bin/fetch_macs.sh");
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log("Connected devices:", data);
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
},
|
||||||
console.error("Error fetching connected devices:", error);
|
|
||||||
return null;
|
async sendATCommand(command) {
|
||||||
|
return await this.fetch("/cgi-bin/atinout_handler.sh", {
|
||||||
|
method: "POST",
|
||||||
|
body: "command=" + encodeURIComponent(command)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function populateConnectedDevices(devices) {
|
// uiManager.js - UI related functions
|
||||||
const selectElement = document.getElementById("connected-devices");
|
const uiManager = {
|
||||||
if (!selectElement) {
|
elements: {
|
||||||
console.error("Connected devices select element not found");
|
ipPassthrough: () => document.getElementById("ip-passthrough-mode"),
|
||||||
return;
|
dnsProxy: () => document.getElementById("dns-proxy-mode"),
|
||||||
}
|
usbModem: () => document.getElementById("usb-modem-protocol"),
|
||||||
|
connectedDevices: () => document.getElementById("connected-devices"),
|
||||||
|
loadingContent: () => document.getElementById("loading-content"),
|
||||||
|
modalButtons: () => document.getElementById("modal-buttons"),
|
||||||
|
countdown: () => document.getElementById("countdown"),
|
||||||
|
rebootModal: () => document.getElementById("reboot-modal"),
|
||||||
|
advancedSettingsIcons: () => document.querySelectorAll(".advanced-settings i")
|
||||||
|
},
|
||||||
|
|
||||||
// Clear existing options except the first one
|
showLoadingSpinners() {
|
||||||
while (selectElement.options.length > 1) {
|
this.elements.advancedSettingsIcons().forEach(icon => {
|
||||||
selectElement.remove(1);
|
icon.classList.add("fa-spinner", "fa-spin");
|
||||||
}
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// Add new options
|
hideLoadingSpinners() {
|
||||||
devices.forEach((device) => {
|
this.elements.advancedSettingsIcons().forEach(icon => {
|
||||||
const option = document.createElement("option");
|
icon.classList.remove("fa-spinner", "fa-spin");
|
||||||
option.value = device.mac;
|
});
|
||||||
option.textContent = `${device.hostname} - ${device.mac}`;
|
},
|
||||||
selectElement.appendChild(option);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePassthroughModeState(isEnabled) {
|
updatePassthroughModeState(isEnabled) {
|
||||||
const ipPassthroughSelect = document.getElementById("ip-passthrough-mode");
|
const select = this.elements.ipPassthrough();
|
||||||
if (!ipPassthroughSelect) return;
|
if (!select) return;
|
||||||
|
|
||||||
if (isEnabled) {
|
const helpText = select.parentElement.querySelector(".help");
|
||||||
ipPassthroughSelect.removeAttribute("disabled");
|
|
||||||
ipPassthroughSelect.classList.remove("is-warning");
|
if (isEnabled) {
|
||||||
const helpText = ipPassthroughSelect.parentElement.querySelector(".help");
|
select.removeAttribute("disabled");
|
||||||
if (helpText) {
|
select.classList.remove("is-warning");
|
||||||
helpText.textContent = "Select a passthrough mode to apply.";
|
if (helpText) {
|
||||||
helpText.classList.remove("is-warning");
|
helpText.textContent = "Select a passthrough mode to apply.";
|
||||||
helpText.classList.add("is-info");
|
helpText.classList.remove("is-warning");
|
||||||
}
|
helpText.classList.add("is-info");
|
||||||
} else {
|
}
|
||||||
ipPassthroughSelect.setAttribute("disabled", "disabled");
|
} else {
|
||||||
ipPassthroughSelect.classList.add("is-warning");
|
select.setAttribute("disabled", "disabled");
|
||||||
ipPassthroughSelect.value = "Select IP Passthrough Mode";
|
select.classList.add("is-warning");
|
||||||
const helpText = ipPassthroughSelect.parentElement.querySelector(".help");
|
select.value = "Select IP Passthrough Mode";
|
||||||
if (helpText) {
|
if (helpText) {
|
||||||
helpText.textContent = "Please select a device first.";
|
helpText.textContent = "Please select a device first.";
|
||||||
helpText.classList.remove("is-info");
|
helpText.classList.remove("is-info");
|
||||||
helpText.classList.add("is-warning");
|
helpText.classList.add("is-warning");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateUIElements(data) {
|
|
||||||
// Get all required DOM elements
|
|
||||||
const elements = {
|
|
||||||
ipPassthrough: document.getElementById("ip-passthrough-mode"),
|
|
||||||
dnsProxy: document.getElementById("dns-proxy-mode"),
|
|
||||||
usbModem: document.getElementById("usb-modem-protocol"),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if all elements exist
|
|
||||||
const missingElements = Object.entries(elements)
|
|
||||||
.filter(([key, element]) => !element)
|
|
||||||
.map(([key]) => key);
|
|
||||||
|
|
||||||
if (missingElements.length > 0) {
|
|
||||||
console.error("Missing DOM elements:", missingElements);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Initially disable IP Passthrough mode
|
|
||||||
updatePassthroughModeState(false);
|
|
||||||
|
|
||||||
// Passthrough Mode (will be disabled until device is selected)
|
|
||||||
const mpdnRuleLine = data[0].response.split("\n")[1];
|
|
||||||
if (mpdnRuleLine) {
|
|
||||||
const mpdnRule = mpdnRuleLine.split(":")[1].trim();
|
|
||||||
switch (mpdnRule) {
|
|
||||||
case '"MPDN_rule",0,0,0,0,0':
|
|
||||||
elements.ipPassthrough.value = "Disabled";
|
|
||||||
break;
|
|
||||||
case '"MPDN_rule",0,1,0,1,1':
|
|
||||||
elements.ipPassthrough.value = "ETH Only";
|
|
||||||
break;
|
|
||||||
case '"MPDN_rule",0,1,0,3,1':
|
|
||||||
elements.ipPassthrough.value = "USB Only";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elements.ipPassthrough.value = "Select IP Passthrough Mode";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// DNS Proxy
|
populateConnectedDevices(devices) {
|
||||||
const dnsProxyLine = data[1].response
|
const select = this.elements.connectedDevices();
|
||||||
.split("\n")[1]
|
if (!select) {
|
||||||
.split(":")[1]
|
console.error("Connected devices select element not found");
|
||||||
.split(",")[1]
|
return;
|
||||||
.trim();
|
|
||||||
if (dnsProxyLine) {
|
|
||||||
elements.dnsProxy.value =
|
|
||||||
dnsProxyLine === '"disable"' ? "Disabled" : "Enabled";
|
|
||||||
} else {
|
|
||||||
elements.dnsProxy.value = "Select Onboard DNS Proxy";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// USB Modem Protocol
|
// Clear existing options except the first one
|
||||||
const usbModemProtocolLine = data[2].response
|
while (select.options.length > 1) {
|
||||||
.split("\n")[1]
|
select.remove(1);
|
||||||
.split(":")[1]
|
|
||||||
.split(",")[1]
|
|
||||||
.trim();
|
|
||||||
switch (usbModemProtocolLine) {
|
|
||||||
case "0":
|
|
||||||
elements.usbModem.value = "RMNET";
|
|
||||||
break;
|
|
||||||
case "1":
|
|
||||||
elements.usbModem.value = "ECM (Recommended)";
|
|
||||||
break;
|
|
||||||
case "2":
|
|
||||||
elements.usbModem.value = "MBIM";
|
|
||||||
break;
|
|
||||||
case "3":
|
|
||||||
elements.usbModem.value = "RNDIS";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elements.usbModem.value = "Select USB Modem Protocol";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// Add new options
|
||||||
} catch (error) {
|
devices.forEach(device => {
|
||||||
console.error("Error updating UI elements:", error);
|
const option = document.createElement("option");
|
||||||
return false;
|
option.value = device.mac;
|
||||||
}
|
option.textContent = `${device.hostname} - ${device.mac}`;
|
||||||
}
|
select.appendChild(option);
|
||||||
|
|
||||||
// Function to send an AT command based on the DNS proxy mode
|
|
||||||
async function sendDnsProxyCommand(command) {
|
|
||||||
try {
|
|
||||||
const response = await fetch("/cgi-bin/atinout_handler.sh", {
|
|
||||||
method: "POST",
|
|
||||||
body: "command=" + encodeURIComponent(command),
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
const data = await response.json();
|
showModal() {
|
||||||
console.log("DNS Proxy AT command executed:", data.output);
|
const modal = this.elements.rebootModal();
|
||||||
} catch (error) {
|
if (modal) {
|
||||||
console.error("Error sending DNS Proxy AT command:", error);
|
modal.classList.add("is-active");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
showLoadingContent() {
|
||||||
|
this.elements.loadingContent().style.display = "flex";
|
||||||
|
this.elements.modalButtons().style.display = "none";
|
||||||
|
this.showModal();
|
||||||
|
},
|
||||||
|
|
||||||
|
startCountdown(duration) {
|
||||||
|
const countdownElement = this.elements.countdown();
|
||||||
|
let countdown = duration;
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
countdown--;
|
||||||
|
countdownElement.textContent = countdown;
|
||||||
|
|
||||||
|
if (countdown <= 0) {
|
||||||
|
clearInterval(interval);
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Function to handle DNS Proxy changes
|
// settingsManager.js - Settings management
|
||||||
function handleDnsProxyChange() {
|
const settingsManager = {
|
||||||
const dnsProxySelect = document.getElementById("dns-proxy-mode");
|
async updateSettings(data) {
|
||||||
const currentDnsProxyMode = dnsProxySelect.getAttribute("data-current-mode"); // Store current mode as a data attribute
|
const elements = {
|
||||||
|
ipPassthrough: uiManager.elements.ipPassthrough(),
|
||||||
|
dnsProxy: uiManager.elements.dnsProxy(),
|
||||||
|
usbModem: uiManager.elements.usbModem()
|
||||||
|
};
|
||||||
|
|
||||||
dnsProxySelect.addEventListener("change", function (e) {
|
// Validate required elements
|
||||||
|
const missingElements = Object.entries(elements)
|
||||||
|
.filter(([, element]) => !element)
|
||||||
|
.map(([key]) => key);
|
||||||
|
|
||||||
|
if (missingElements.length > 0) {
|
||||||
|
console.error("Missing DOM elements:", missingElements);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
uiManager.updatePassthroughModeState(false);
|
||||||
|
|
||||||
|
// Update IP Passthrough Mode
|
||||||
|
const mpdnRuleLine = data[0].response.split("\n")[1];
|
||||||
|
if (mpdnRuleLine) {
|
||||||
|
const mpdnRule = mpdnRuleLine.split(":")[1].trim();
|
||||||
|
elements.ipPassthrough.value = this.getPassthroughModeValue(mpdnRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update DNS Proxy
|
||||||
|
const dnsProxyLine = data[1].response.split("\n")[1].split(":")[1].split(",")[1].trim();
|
||||||
|
elements.dnsProxy.value = dnsProxyLine === '"disable"' ? "Disabled" : "Enabled";
|
||||||
|
|
||||||
|
// Update USB Modem Protocol
|
||||||
|
const usbModemProtocolLine = data[2].response.split("\n")[1].split(":")[1].split(",")[1].trim();
|
||||||
|
elements.usbModem.value = this.getUsbModemProtocolValue(usbModemProtocolLine);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating settings:", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getPassthroughModeValue(mpdnRule) {
|
||||||
|
const modes = {
|
||||||
|
'"MPDN_rule",0,0,0,0,0': "Disabled",
|
||||||
|
'"MPDN_rule",0,1,0,1,1': "ETH Only",
|
||||||
|
'"MPDN_rule",0,1,0,3,1': "USB Only"
|
||||||
|
};
|
||||||
|
return modes[mpdnRule] || "Select IP Passthrough Mode";
|
||||||
|
},
|
||||||
|
|
||||||
|
getUsbModemProtocolValue(protocol) {
|
||||||
|
const protocols = {
|
||||||
|
"0": "RMNET",
|
||||||
|
"1": "ECM (Recommended)",
|
||||||
|
"2": "MBIM",
|
||||||
|
"3": "RNDIS"
|
||||||
|
};
|
||||||
|
return protocols[protocol] || "Select USB Modem Protocol";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// eventHandlers.js - Event handling
|
||||||
|
const eventHandlers = {
|
||||||
|
async handleDnsProxyChange(e) {
|
||||||
const selectedMode = e.target.value;
|
const selectedMode = e.target.value;
|
||||||
|
const currentMode = e.target.getAttribute("data-current-mode");
|
||||||
|
|
||||||
// Send AT command only if the selected mode differs from the current one
|
if (selectedMode !== currentMode) {
|
||||||
if (selectedMode !== currentDnsProxyMode) {
|
const command = selectedMode === "Enabled"
|
||||||
if (selectedMode === "Enabled") {
|
? 'AT+QMAP="DHCPV4DNS","enable"'
|
||||||
sendDnsProxyCommand('AT+QMAP="DHCPV4DNS","enable"');
|
: 'AT+QMAP="DHCPV4DNS","disable"';
|
||||||
} else if (selectedMode === "Disabled") {
|
await api.sendATCommand(command);
|
||||||
sendDnsProxyCommand('AT+QMAP="DHCPV4DNS","disable"');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("No changes made to DNS Proxy mode");
|
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
}
|
|
||||||
|
|
||||||
// Function to send an AT command based on the IP Passthrough mode
|
async handleIpPassthroughChange(e) {
|
||||||
async function sendIpPassthroughCommand(command) {
|
|
||||||
if (command) {
|
|
||||||
showLoadingContent(); // Show loading content and hide the buttons
|
|
||||||
startCountdown(80); // Start the countdown for 5 seconds
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const response = await fetch("/cgi-bin/atinout_handler.sh", {
|
|
||||||
method: "POST",
|
|
||||||
body: "command=" + encodeURIComponent(command),
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log("IP Passthrough AT command executed:", data.output);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error sending IP Passthrough AT command:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to handle IP Passthrough mode changes
|
|
||||||
function handleIpPassthroughChange() {
|
|
||||||
// track if the device is selected by listening to the connected devices dropdown change event
|
|
||||||
const connectedDevicesSelect = document.getElementById("connected-devices");
|
|
||||||
if (connectedDevicesSelect) {
|
|
||||||
connectedDevicesSelect.addEventListener("change", function (e) {
|
|
||||||
const selectedMAC = e.target.value;
|
|
||||||
const selectedHostname = e.target.options[e.target.selectedIndex].text;
|
|
||||||
console.log("Selected device:", {
|
|
||||||
mac: selectedMAC,
|
|
||||||
hostname: selectedHostname,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Enable/disable IP Passthrough mode based on selection
|
|
||||||
const isDeviceSelected = selectedMAC !== "Select Device MAC";
|
|
||||||
if (isDeviceSelected) {
|
|
||||||
updatePassthroughModeState(true);
|
|
||||||
} else {
|
|
||||||
updatePassthroughModeState(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const ipPassthroughSelect = document.getElementById("ip-passthrough-mode");
|
|
||||||
const currentIpPassthroughMode =
|
|
||||||
ipPassthroughSelect.getAttribute("data-current-mode"); // Store current mode as a data attribute
|
|
||||||
|
|
||||||
ipPassthroughSelect.addEventListener("change", function (e) {
|
|
||||||
const selectedMode = e.target.value;
|
const selectedMode = e.target.value;
|
||||||
const selectedDeviceMAC =
|
const currentMode = e.target.getAttribute("data-current-mode");
|
||||||
document.getElementById("connected-devices").value;
|
const selectedDeviceMAC = uiManager.elements.connectedDevices().value;
|
||||||
|
|
||||||
// Send AT command only if the selected mode differs from the current one
|
if (selectedMode !== currentMode) {
|
||||||
if (selectedMode !== currentIpPassthroughMode) {
|
const commands = {
|
||||||
let command;
|
"Disabled": 'AT+QMPDN="MPDN_rule",0;+CFUN=1,1',
|
||||||
switch (selectedMode) {
|
"ETH Only": `AT+QMPDN="MPDN_rule",0,1,0,1,1,"${selectedDeviceMAC}"`,
|
||||||
case "Disabled":
|
"USB Only": `AT+QMPDN="MPDN_rule",0,1,0,3,1,"${selectedDeviceMAC}"`
|
||||||
command = 'AT+QMPDN="MPDN_rule",0;+CFUN=1,1';
|
};
|
||||||
break;
|
|
||||||
case "ETH Only":
|
const command = commands[selectedMode];
|
||||||
command = `AT+QMPDN="MPDN_rule",0,1,0,1,1,"${selectedDeviceMAC}"`;
|
if (command) {
|
||||||
break;
|
uiManager.showLoadingContent();
|
||||||
case "USB Only":
|
uiManager.startCountdown(80);
|
||||||
command = `AT+QMPDN="MPDN_rule",0,1,0,3,1,"${selectedDeviceMAC}"`;
|
await api.sendATCommand(command);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.error("Invalid IP Passthrough mode:", selectedMode);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendIpPassthroughCommand(command);
|
|
||||||
} else {
|
|
||||||
console.log("No changes made to IP Passthrough mode");
|
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
}
|
|
||||||
|
|
||||||
// Function to send an AT command based on the USB Modem Protocol
|
async handleUsbModemProtocolChange(e) {
|
||||||
async function sendUsbModemProtocolCommand(command) {
|
|
||||||
try {
|
|
||||||
if (command) {
|
|
||||||
showLoadingContent(); // Show loading content and hide the buttons
|
|
||||||
startCountdown(80); // Start the countdown for 5 seconds
|
|
||||||
}
|
|
||||||
const response = await fetch("/cgi-bin/atinout_handler.sh", {
|
|
||||||
method: "POST",
|
|
||||||
body: "command=" + encodeURIComponent(command),
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log("USB Modem Protocol AT command executed:", data.output);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error sending USB Modem Protocol AT command:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to handle USB Modem Protocol changes
|
|
||||||
function handleUsbModemProtocolChange() {
|
|
||||||
const usbModemSelect = document.getElementById("usb-modem-protocol");
|
|
||||||
const currentUsbModemProtocol = usbModemSelect.getAttribute(
|
|
||||||
"data-current-protocol"
|
|
||||||
); // Store current protocol as a data attribute
|
|
||||||
|
|
||||||
usbModemSelect.addEventListener("change", function (e) {
|
|
||||||
const selectedProtocol = e.target.value;
|
const selectedProtocol = e.target.value;
|
||||||
|
const currentProtocol = e.target.getAttribute("data-current-protocol");
|
||||||
|
|
||||||
// Send AT command only if the selected protocol differs from the current one
|
if (selectedProtocol !== currentProtocol) {
|
||||||
if (selectedProtocol !== currentUsbModemProtocol) {
|
const commands = {
|
||||||
let command;
|
"RMNET": 'AT+QCFG="usbnet",0;+CFUN=1,1',
|
||||||
switch (selectedProtocol) {
|
"ECM (Recommended)": 'AT+QCFG="usbnet",1;+CFUN=1,1',
|
||||||
case "RMNET":
|
"MBIM": 'AT+QCFG="usbnet",2;+CFUN=1,1',
|
||||||
command = 'AT+QCFG="usbnet",0;+CFUN=1,1';
|
"RNDIS": 'AT+QCFG="usbnet",3;+CFUN=1,1'
|
||||||
break;
|
};
|
||||||
case "ECM (Recommended)":
|
|
||||||
command = 'AT+QCFG="usbnet",1;+CFUN=1,1';
|
const command = commands[selectedProtocol];
|
||||||
break;
|
if (command) {
|
||||||
case "MBIM":
|
uiManager.showLoadingContent();
|
||||||
command = 'AT+QCFG="usbnet",2;+CFUN=1,1';
|
uiManager.startCountdown(80);
|
||||||
break;
|
await api.sendATCommand(command);
|
||||||
case "RNDIS":
|
|
||||||
command = 'AT+QCFG="usbnet",3;+CFUN=1,1';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.error("Invalid USB Modem Protocol:", selectedProtocol);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendUsbModemProtocolCommand(command);
|
|
||||||
} else {
|
|
||||||
console.log("No changes made to USB Modem Protocol");
|
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
}
|
|
||||||
|
|
||||||
// Function to show the modal
|
handleDeviceSelection(e) {
|
||||||
function showModal() {
|
const selectedMAC = e.target.value;
|
||||||
const modal = document.getElementById("reboot-modal");
|
const selectedHostname = e.target.options[e.target.selectedIndex].text;
|
||||||
if (modal) {
|
console.log("Selected device:", { mac: selectedMAC, hostname: selectedHostname });
|
||||||
modal.classList.add("is-active"); // Bulma modals require "is-active" to be shown
|
|
||||||
|
const isDeviceSelected = selectedMAC !== "Select Device MAC";
|
||||||
|
uiManager.updatePassthroughModeState(isDeviceSelected);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// main.js - Application initialization
|
||||||
|
async function init() {
|
||||||
|
uiManager.showLoadingSpinners();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [settings, devices] = await Promise.all([
|
||||||
|
api.fetchCurrentSettings(),
|
||||||
|
api.fetchConnectedDevices()
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (settings) {
|
||||||
|
const updateSuccess = await settingsManager.updateSettings(settings);
|
||||||
|
if (updateSuccess) {
|
||||||
|
uiManager.hideLoadingSpinners();
|
||||||
|
|
||||||
|
// Set up event listeners
|
||||||
|
uiManager.elements.dnsProxy().addEventListener("change", eventHandlers.handleDnsProxyChange);
|
||||||
|
uiManager.elements.ipPassthrough().addEventListener("change", eventHandlers.handleIpPassthroughChange);
|
||||||
|
uiManager.elements.usbModem().addEventListener("change", eventHandlers.handleUsbModemProtocolChange);
|
||||||
|
uiManager.elements.connectedDevices().addEventListener("change", eventHandlers.handleDeviceSelection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devices) {
|
||||||
|
uiManager.populateConnectedDevices(devices);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Initialization error:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to show loading content and show the modal
|
// Initialize when DOM is ready
|
||||||
function showLoadingContent() {
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
document.getElementById("loading-content").style.display = "flex"; // Show the loading section
|
|
||||||
document.getElementById("modal-buttons").style.display = "none"; // Hide the buttons
|
|
||||||
|
|
||||||
// Activate the modal
|
|
||||||
showModal();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to start the countdown
|
|
||||||
function startCountdown(duration) {
|
|
||||||
let countdownElement = document.getElementById("countdown");
|
|
||||||
let countdown = duration;
|
|
||||||
let interval = setInterval(function () {
|
|
||||||
countdown--;
|
|
||||||
countdownElement.textContent = countdown;
|
|
||||||
|
|
||||||
if (countdown <= 0) {
|
|
||||||
clearInterval(interval);
|
|
||||||
// Add any additional logic after countdown reaches 0 (like reloading or closing the modal)
|
|
||||||
location.reload(); // Reload the page
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function for initializing the page
|
|
||||||
function init() {
|
|
||||||
// Replace all i elements under the class advanced-settings with a spinner icon initially
|
|
||||||
const advancedSettingsIcons = document.querySelectorAll(
|
|
||||||
".advanced-settings i"
|
|
||||||
);
|
|
||||||
advancedSettingsIcons.forEach((icon) => {
|
|
||||||
icon.classList.add("fa-spinner", "fa-spin");
|
|
||||||
});
|
|
||||||
|
|
||||||
Promise.all([fetchCurrentSettings(), fetchConnectedDevices()])
|
|
||||||
.then(([settings, devices]) => {
|
|
||||||
if (settings) {
|
|
||||||
const updateSuccess = updateUIElements(settings);
|
|
||||||
if (!updateSuccess) {
|
|
||||||
console.error("Failed to update UI elements");
|
|
||||||
} else {
|
|
||||||
// Revert the spinner icons back to their original state
|
|
||||||
advancedSettingsIcons.forEach((icon) => {
|
|
||||||
icon.classList.remove("fa-spinner", "fa-spin");
|
|
||||||
});
|
|
||||||
|
|
||||||
handleDnsProxyChange(); // Add event listener for DNS Proxy changes
|
|
||||||
handleUsbModemProtocolChange(); // Add event listener for USB Modem Protocol changes
|
|
||||||
handleIpPassthroughChange(); // Add event listener for IP Passthrough changes
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error("Failed to fetch current settings");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (devices) {
|
|
||||||
populateConnectedDevices(devices);
|
|
||||||
} else {
|
|
||||||
console.error("Failed to fetch connected devices");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Error during initialization:", error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize event listeners when DOM is ready
|
|
||||||
// document.addEventListener("DOMContentLoaded", () => {
|
|
||||||
// // Initialize the page
|
|
||||||
// init();
|
|
||||||
|
|
||||||
// // Add event listener for usb modem protocol changes
|
|
||||||
// handleUsbModemProtocolChange();
|
|
||||||
|
|
||||||
// // Add event listener for connected devices dropdown
|
|
||||||
// const connectedDevicesSelect = document.getElementById("connected-devices");
|
|
||||||
// if (connectedDevicesSelect) {
|
|
||||||
// connectedDevicesSelect.addEventListener("change", function (e) {
|
|
||||||
// const selectedMAC = e.target.value;
|
|
||||||
// const selectedHostname = e.target.options[e.target.selectedIndex].text;
|
|
||||||
// console.log("Selected device:", {
|
|
||||||
// mac: selectedMAC,
|
|
||||||
// hostname: selectedHostname,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // Enable/disable IP Passthrough mode based on selection
|
|
||||||
// const isDeviceSelected = selectedMAC !== "Select Device MAC";
|
|
||||||
// updatePassthroughModeState(isDeviceSelected);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Add event listener for IP Passthrough mode changes
|
|
||||||
// const ipPassthroughSelect = document.getElementById("ip-passthrough-mode");
|
|
||||||
// if (ipPassthroughSelect) {
|
|
||||||
// ipPassthroughSelect.addEventListener("change", function (e) {
|
|
||||||
// const selectedMode = e.target.value;
|
|
||||||
// const connectedDevicesSelect =
|
|
||||||
// document.getElementById("connected-devices");
|
|
||||||
// const selectedMAC = connectedDevicesSelect
|
|
||||||
// ? connectedDevicesSelect.value
|
|
||||||
// : null;
|
|
||||||
|
|
||||||
// if (selectedMAC && selectedMAC !== "Select Device MAC") {
|
|
||||||
// console.log("Applying IP Passthrough mode:", {
|
|
||||||
// mode: selectedMode,
|
|
||||||
// deviceMAC: selectedMAC,
|
|
||||||
// });
|
|
||||||
// // Here you can add the API call to apply the passthrough mode
|
|
||||||
// } else {
|
|
||||||
// console.error("No device selected for IP Passthrough mode");
|
|
||||||
// e.target.value = "Select IP Passthrough Mode";
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// Initialize event listeners when DOM is ready
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
|
||||||
// Initialize the page
|
|
||||||
init();
|
|
||||||
});
|
|
||||||
214
www/js/band-locking/fetch-bands.js
Normal file
214
www/js/band-locking/fetch-bands.js
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
// api.js - API related functions
|
||||||
|
const api = {
|
||||||
|
async sendCommand(command) {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/cgi-bin/atinout_handler.sh", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
body: `command=${encodeURIComponent(command)}`,
|
||||||
|
});
|
||||||
|
return await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("API Error:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// bandManager.js - Band management functionality
|
||||||
|
const bandManager = {
|
||||||
|
async fetchCurrentBands() {
|
||||||
|
try {
|
||||||
|
const data = await api.sendCommand("AT+QCAINFO");
|
||||||
|
const lteBands = data.output.match(/LTE BAND ([0-9]+)/g) || [];
|
||||||
|
const nrBands = data.output.match(/NR5G BAND ([0-9]+)/g) || [];
|
||||||
|
|
||||||
|
const currentBandsElement = document.getElementById("currentBands");
|
||||||
|
if (!currentBandsElement) return;
|
||||||
|
|
||||||
|
if (lteBands.length === 0 && nrBands.length === 0) {
|
||||||
|
currentBandsElement.textContent = "No active bands found";
|
||||||
|
} else if (lteBands.length === 0) {
|
||||||
|
currentBandsElement.textContent = nrBands.join(", ");
|
||||||
|
} else if (nrBands.length === 0) {
|
||||||
|
currentBandsElement.textContent = lteBands.join(", ");
|
||||||
|
} else {
|
||||||
|
currentBandsElement.textContent = [...lteBands, ...nrBands].join(", ");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching current bands:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchSupportedBands() {
|
||||||
|
try {
|
||||||
|
const data = await api.sendCommand('AT+QNWPREFCFG="policy_band"');
|
||||||
|
|
||||||
|
const matches = {
|
||||||
|
lte: data.output.match(/"lte_band",([0-9:]+)/),
|
||||||
|
nsa: data.output.match(/"nsa_nr5g_band",([0-9:]+)/),
|
||||||
|
saDc: data.output.match(/"nrdc_nr5g_band",([0-9:]+)/)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (matches.lte) this.populateBands(matches.lte[1], "#lte_bands");
|
||||||
|
if (matches.nsa) this.populateBands(matches.nsa[1], "#nsa_bands");
|
||||||
|
if (matches.saDc) this.populateBands(matches.saDc[1], "#sanrdc_bands");
|
||||||
|
|
||||||
|
await this.fetchActiveBands();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching supported bands:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchActiveBands() {
|
||||||
|
try {
|
||||||
|
const command = 'AT+QNWPREFCFG="lte_band";+QNWPREFCFG="nsa_nr5g_band";+QNWPREFCFG="nr5g_band";+QNWPREFCFG="nrdc_nr5g_band"';
|
||||||
|
const data = await api.sendCommand(command);
|
||||||
|
|
||||||
|
const output = data.output.split("\n").slice(1).join("\n").replace("OK", "");
|
||||||
|
|
||||||
|
const matches = {
|
||||||
|
lte: output.match(/"lte_band",([0-9:]+)/),
|
||||||
|
nsa: output.match(/"nsa_nr5g_band",([0-9:]+)/),
|
||||||
|
saDc: output.split("\n")[6]?.match(/"nr5g_band",([0-9:]+)/)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (matches.lte) this.markActiveBands(matches.lte[1].split(":"), "#lte_bands");
|
||||||
|
if (matches.nsa) this.markActiveBands(matches.nsa[1].split(":"), "#nsa_bands");
|
||||||
|
if (matches.saDc) this.markActiveBands(matches.saDc[1].split(":"), "#sanrdc_bands");
|
||||||
|
|
||||||
|
await this.fetchCurrentBands();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching active bands:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
populateBands(bandsString, targetId) {
|
||||||
|
const container = document.querySelector(targetId);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const html = bandsString.split(":").map(band => `
|
||||||
|
<div class="cell">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" value="${band}" /> B${band}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
`).join("");
|
||||||
|
|
||||||
|
container.innerHTML = html;
|
||||||
|
},
|
||||||
|
|
||||||
|
markActiveBands(activeBands, targetId) {
|
||||||
|
document.querySelectorAll(`${targetId} input[type="checkbox"]`).forEach(checkbox => {
|
||||||
|
if (activeBands.includes(checkbox.value)) {
|
||||||
|
checkbox.setAttribute("checked", "checked");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
uncheckAll(targetId) {
|
||||||
|
document.querySelectorAll(`${targetId} input[type="checkbox"]`).forEach(checkbox => {
|
||||||
|
checkbox.removeAttribute("checked");
|
||||||
|
checkbox.checked = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async lockBands(targetId, commandType) {
|
||||||
|
const checkboxes = document.querySelectorAll(`${targetId} input[type="checkbox"]:checked`);
|
||||||
|
const checkedBands = Array.from(checkboxes)
|
||||||
|
.map(cb => cb.value)
|
||||||
|
.sort((a, b) => a - b);
|
||||||
|
|
||||||
|
if (checkedBands.length === 0) {
|
||||||
|
alert("Please select at least one band to lock.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const command = `AT+QNWPREFCFG="${commandType}",${checkedBands.join(":")}`;
|
||||||
|
await api.sendCommand(command);
|
||||||
|
alert(`Successfully locked ${commandType.split("_")[0].toUpperCase()} bands`);
|
||||||
|
await this.fetchActiveBands();
|
||||||
|
} catch (error) {
|
||||||
|
alert(`Failed to lock bands: ${error.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async resetBands(targetId, bandType) {
|
||||||
|
const checkboxes = document.querySelectorAll(`${targetId} input[type="checkbox"]`);
|
||||||
|
const selectedBands = [];
|
||||||
|
|
||||||
|
checkboxes.forEach(checkbox => {
|
||||||
|
checkbox.setAttribute("checked", "checked");
|
||||||
|
checkbox.checked = true;
|
||||||
|
selectedBands.push(checkbox.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const command = `AT+QNWPREFCFG="${bandType}",${selectedBands.join(":")}`;
|
||||||
|
await api.sendCommand(command);
|
||||||
|
await this.fetchActiveBands();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error resetting ${bandType}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// eventHandlers.js - Event handling setup
|
||||||
|
function setupEventListeners() {
|
||||||
|
const handlers = {
|
||||||
|
uncheck: {
|
||||||
|
"uncheckLte": "#lte_bands",
|
||||||
|
"uncheckNsa": "#nsa_bands",
|
||||||
|
"uncheckSaDc": "#sanrdc_bands"
|
||||||
|
},
|
||||||
|
lock: {
|
||||||
|
"lockLte": ["#lte_bands", "lte_band"],
|
||||||
|
"lockNsa": ["#nsa_bands", "nsa_nr5g_band"],
|
||||||
|
"lockSaDc": ["#sanrdc_bands", "nrdc_nr5g_band"]
|
||||||
|
},
|
||||||
|
reset: {
|
||||||
|
"resetLte": ["#lte_bands", "lte_band"],
|
||||||
|
"resetNsa": ["#nsa_bands", "nsa_nr5g_band"],
|
||||||
|
"resetSaDc": ["#sanrdc_bands", "nrdc_nr5g_band"]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup uncheck handlers
|
||||||
|
Object.entries(handlers.uncheck).forEach(([id, targetId]) => {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
element.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
bandManager.uncheckAll(targetId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup lock handlers
|
||||||
|
Object.entries(handlers.lock).forEach(([id, [targetId, commandType]]) => {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
element.addEventListener("click", () => bandManager.lockBands(targetId, commandType));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup reset handlers
|
||||||
|
Object.entries(handlers.reset).forEach(([id, [targetId, bandType]]) => {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
element.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
bandManager.resetBands(targetId, bandType);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// main.js - Application initialization
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
setupEventListeners();
|
||||||
|
bandManager.fetchSupportedBands();
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user