1003 lines
35 KiB
HTML
1003 lines
35 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" data-bs-theme="light">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>模块管理</title>
|
|
<!-- <link
|
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
|
rel="stylesheet"
|
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
|
crossorigin="anonymous"
|
|
/> -->
|
|
<!-- Import all the bootstrap css files from css folder -->
|
|
<link rel="stylesheet" href="css/styles.css" />
|
|
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
|
|
|
<!-- Logo -->
|
|
<link rel="simpleadmin-logo" href="favicon.ico" />
|
|
|
|
<!-- Import BootStrap Javascript -->
|
|
<script src="js/bootstrap.bundle.min.js"></script>
|
|
<script src="js/alpinejs.min.js" defer></script>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<div class="container my-4" x-data="cellLocking()">
|
|
<nav class="navbar navbar-expand-lg mt-2">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="/"
|
|
><span class="mb-0 h4 fw-bold">模块管理</span></a>
|
|
<button
|
|
class="navbar-toggler"
|
|
type="button"
|
|
data-bs-toggle="collapse"
|
|
data-bs-target="#navbarText"
|
|
aria-controls="navbarText"
|
|
aria-expanded="false"
|
|
aria-label="Toggle navigation"
|
|
>
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="collapse navbar-collapse" id="navbarText">
|
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/">首页</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a
|
|
class="nav-link active"
|
|
href="network.html"
|
|
aria-current="page"
|
|
>网络</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/scanner.html">扫描</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/settings.html">设置</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/sms.html">短信</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/console">控制台</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="deviceinfo.html"
|
|
>设备信息</a
|
|
>
|
|
</li>
|
|
</ul>
|
|
<span class="navbar-text">
|
|
<button class="btn btn-link text-reset" id="darkModeToggle">
|
|
Dark Mode
|
|
</button>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="row mt-5 gap-3">
|
|
<div class="col">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="row align-items-center">
|
|
<div class="col">频段锁定</div>
|
|
<div class="col-md-3">
|
|
<select
|
|
class="form-select"
|
|
id="networkModeBand"
|
|
aria-label="LTE"
|
|
>
|
|
<option selected value="LTE">LTE</option>
|
|
<option value="NSA">NR5G-NSA</option>
|
|
<option value="SA">NR5G-SA</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<h5 class="card-subtitle" x-show="isGettingBands === true">
|
|
获取支持的频段...
|
|
</h5>
|
|
<form id="checkboxForm" x-show="isGettingBands === false">
|
|
<!-- Checkboxes will be populated here -->
|
|
</form>
|
|
</div>
|
|
<div class="card-footer">
|
|
<div class="d-flex align-items-center">
|
|
<div class="col">
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary m-2"
|
|
@click="lockSelectedBands()"
|
|
>
|
|
锁频段
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-info m-2"
|
|
id="uncheckAll"
|
|
>
|
|
取消勾选
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-danger m-2"
|
|
@click="resetBandLocking()"
|
|
>
|
|
复位
|
|
</button>
|
|
</div>
|
|
<div class="form-check">
|
|
<input
|
|
class="form-check-input"
|
|
type="checkbox"
|
|
value=""
|
|
id="providerBands"
|
|
onchange="saveCheckboxState()"
|
|
/>
|
|
<label class="form-check-label" for="providerBands">
|
|
显示支持的频段
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer">
|
|
<p x-text="'激活的频段: ' + bands"></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row gap-3 mt-4">
|
|
<div class="col">
|
|
<form>
|
|
<div class="card">
|
|
<div class="card-header">网络工具</div>
|
|
<div class="card-body row">
|
|
<div class="col">
|
|
<div class="mb-4">
|
|
<label for="APN" class="form-label">APN</label>
|
|
<input
|
|
type="text"
|
|
class="form-control"
|
|
id="APN"
|
|
x-model="newApn"
|
|
aria-describedby="APN"
|
|
x-bind:placeholder="apn === '-' ? 'Fetching...' : apn"
|
|
/>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label for="ipForAPN" class="form-label"
|
|
>选择APN类型</label
|
|
>
|
|
<select
|
|
class="form-select"
|
|
id="ipAPN"
|
|
x-model="newApnIP"
|
|
aria-label="ipForAPN"
|
|
>
|
|
<option
|
|
selected
|
|
x-text="apnIP === '-' ? 'Fetching...' : 'Current: ' + apnIP"
|
|
></option>
|
|
<option value="1">IP</option>
|
|
<option value="2">IPv6</option>
|
|
<option value="3">IPv4v6</option>
|
|
<option value="4">PPP</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="mb-4 input-group grid gap-3">
|
|
<label for="SIM1" class="form-label"> 更改SIM卡</label>
|
|
<div class="form-check form-check-inline">
|
|
<style> .form-check-inline {
|
|
display: inline-flex; /* 确保选项在同一行 */
|
|
align-items: center; /* 垂直居中对齐 */
|
|
margin-right: 15px; /* 添加间距 */ }
|
|
</style>
|
|
<input
|
|
class="form-check-input"
|
|
type="radio"
|
|
name="inlineRadioOptions"
|
|
aria-describedby="SIM1"
|
|
id="SIM1"
|
|
value="option1"
|
|
x-bind:checked="sim === '1'"
|
|
x-on:click="newSim = '1'"
|
|
/>
|
|
<label class="form-check-label" for="inlineRadio1"
|
|
>1</label
|
|
>
|
|
</div>
|
|
<div class="form-check form-check-inline">
|
|
<input
|
|
class="form-check-input"
|
|
type="radio"
|
|
name="inlineRadioOptions"
|
|
aria-describedby="SIM2"
|
|
id="SIM2"
|
|
value="option2"
|
|
x-bind:checked="sim === '2'"
|
|
x-on:click="newSim = '2'"
|
|
/>
|
|
<label class="form-check-label" for="inlineRadio2"
|
|
>2</label
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col">
|
|
<div class="mb-4">
|
|
<label for="nrModeControl" class="form-label"
|
|
>选择网络模式</label
|
|
>
|
|
<select
|
|
class="form-select"
|
|
id="prefNetworkMode"
|
|
x-model="prefNetworkMode"
|
|
aria-label="prefNetworkMode"
|
|
>
|
|
<option
|
|
selected
|
|
x-text="prefNetwork === '-' ? 'Fetching...' : 'Current: ' + prefNetwork"
|
|
></option>
|
|
<option value="AUTO">AUTO</option>
|
|
<option value="LTE">LTE Only</option>
|
|
<option value="LTE:NR5G">NR5G-NSA</option>
|
|
<option value="NR5G">NR5G-SA</option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-4">
|
|
<label for="prefNetwork" class="form-label"
|
|
>5G模式控制</label
|
|
>
|
|
<select
|
|
class="form-select"
|
|
id="nrModeControl"
|
|
x-model="nrModeControl"
|
|
aria-label="nrModeControl"
|
|
>
|
|
<option
|
|
selected
|
|
x-text="nrModeControl === '-' ? 'Fetching...' : 'Current: ' + nrModeControl"
|
|
></option>
|
|
<option value="0">Enable All</option>
|
|
<option value="2">Disable NR5G-NSA</option>
|
|
<option value="1">Disable NR5G-SA</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer">
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary"
|
|
@click="saveChanges()"
|
|
>
|
|
保存
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header">频段锁定</div>
|
|
<div class="card-body">
|
|
<select
|
|
class="form-select"
|
|
id="networkModeCell"
|
|
x-model="networkModeCell"
|
|
aria-label="LTE"
|
|
>
|
|
<option
|
|
selected
|
|
x-text="'Cell Lock: ' + cellLockStatus"
|
|
></option>
|
|
<option>LTE</option>
|
|
<option>NR5G-SA</option>
|
|
<option>Unlock LTE</option>
|
|
<option>Unlock NR5G-SA</option>
|
|
</select>
|
|
|
|
<div class="my-4">
|
|
<!-- For LTE -->
|
|
<div id="lteElementsCell" x-show="networkModeCell == 'LTE'">
|
|
<div class="input-group mb-3">
|
|
<span class="input-group-text" id="basic-addon1"
|
|
>Num Cells</span
|
|
>
|
|
<input
|
|
type="number"
|
|
class="form-control"
|
|
placeholder="1-10"
|
|
min="1"
|
|
max="10"
|
|
aria-label="NumCells"
|
|
aria-describedby="basic-addon1"
|
|
x-model="cellNum"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="freqNumbersContainer">
|
|
<!-- Generate EARFCN and PCI here -->
|
|
</div>
|
|
|
|
<!-- For SA -->
|
|
<div
|
|
id="saElementsCell"
|
|
x-show="networkModeCell == 'NR5G-SA'"
|
|
>
|
|
<div
|
|
class="input-group mb-3"
|
|
x-show="networkModeCell == 'NR5G-SA'"
|
|
>
|
|
<input
|
|
type="text"
|
|
aria-label="EARFCN"
|
|
placeholder="EARFCN"
|
|
class="form-control"
|
|
x-model="earfcn1"
|
|
/>
|
|
<input
|
|
type="text"
|
|
aria-label="PCI"
|
|
placeholder="PCI"
|
|
class="form-control"
|
|
x-model="pci1"
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
class="input-group mb-3"
|
|
x-show="networkModeCell == 'NR5G-SA'"
|
|
>
|
|
<select
|
|
class="form-select"
|
|
x-model="scs"
|
|
aria-label="SCS"
|
|
>
|
|
<option selected>SCS</option>
|
|
<option>15</option>
|
|
<option>30</option>
|
|
<option>60</option>
|
|
<option>120</option>
|
|
<option>240</option>
|
|
</select>
|
|
<input
|
|
type="text"
|
|
aria-label="band"
|
|
placeholder="Band"
|
|
class="form-control"
|
|
x-model="band"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary"
|
|
x-show="networkModeCell == 'LTE'"
|
|
@click="cellLockEnableLTE()"
|
|
>
|
|
Lock LTE Cells
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary"
|
|
x-show="networkModeCell == 'NR5G-SA'"
|
|
@click="cellLockEnableNR()"
|
|
>
|
|
Lock NR5G-SA Cells
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn btn-danger"
|
|
x-show="networkModeCell == 'Unlock LTE'"
|
|
@click="cellLockDisableLTE()"
|
|
>
|
|
Unlock LTE Cells
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn btn-danger"
|
|
x-show="networkModeCell == 'Unlock NR5G-SA'"
|
|
@click="cellLockDisableNR()"
|
|
>
|
|
Unlock NR5G-SA Cells
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer">
|
|
信道锁定仅适用于主信道,并且在重启后不会持久保存
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Loading Modal for Locking Band -->
|
|
<div class="modal-overlay" x-show="showModal">
|
|
<div class="loading-modal">
|
|
<div class="loader"></div>
|
|
<div
|
|
class="loading-text"
|
|
style="display: flex; flex-direction: column"
|
|
>
|
|
<h3>Initializing Network...</h3>
|
|
<p style="margin-top: 0.5rem">
|
|
Please wait for
|
|
<span x-text="countdown" style="font-weight: 500"></span>
|
|
seconds.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Import Band Locking GUI JS -->
|
|
<!-- <script src="js/band-locking.js"></script> -->
|
|
<script src="js/generate-freq-box.js"></script>
|
|
<script src="js/populate-checkbox.js"></script>
|
|
<script src="js/parse-settings.js"></script>
|
|
<script>
|
|
function cellLocking() {
|
|
return {
|
|
isLoading: false,
|
|
showModal: false,
|
|
countdown: 0,
|
|
networkModeCell: "-",
|
|
earfcn1: null,
|
|
pci1: null,
|
|
earfcn2: null,
|
|
pci2: null,
|
|
earfcn3: null,
|
|
pci3: null,
|
|
earfcn4: null,
|
|
pci4: null,
|
|
earfcn5: null,
|
|
pci5: null,
|
|
earfcn6: null,
|
|
pci6: null,
|
|
earfcn7: null,
|
|
pci7: null,
|
|
earfcn8: null,
|
|
pci8: null,
|
|
earfcn9: null,
|
|
pci9: null,
|
|
earfcn10: null,
|
|
pci10: null,
|
|
scs: null,
|
|
band: null,
|
|
apn: "-",
|
|
apnIP: "-",
|
|
newApnIP: null,
|
|
newApn: null,
|
|
prefNetwork: "-",
|
|
prefNetworkMode: null,
|
|
nrModeControl: "-",
|
|
cellNum: null,
|
|
lte_bands: null,
|
|
nsa_bands: null,
|
|
sa_bands: null,
|
|
locked_lte_bands: null,
|
|
locked_nsa_bands: null,
|
|
locked_sa_bands: null,
|
|
currentNetworkMode: "-",
|
|
updatedLockedBands: null,
|
|
sim: "-",
|
|
newSim: null,
|
|
cellLockStatus: "Unknown",
|
|
bands: "Fetching Bands...",
|
|
isGettingBands: false,
|
|
rawdata: null,
|
|
|
|
getSupportedBands() {
|
|
// Load the checkbox state from localStorage
|
|
const isChecked =
|
|
localStorage.getItem("providerBandsChecked") === "true";
|
|
const providerBands = document.getElementById("providerBands");
|
|
providerBands.checked = isChecked;
|
|
|
|
// If the checkbox is checked, then show only the provider bands
|
|
if (providerBands.checked) {
|
|
const atcmd = 'AT+QNWPREFCFG="ue_capability_band"';
|
|
this.sendATcommand(atcmd)
|
|
.then((rawdata) => {
|
|
this.rawdata = rawdata;
|
|
this.parseSupportedBands(rawdata);
|
|
})
|
|
.then(() => {
|
|
this.getLockedBands();
|
|
});
|
|
} else {
|
|
const atcmd = 'AT+QNWPREFCFG="policy_band"';
|
|
this.sendATcommand(atcmd)
|
|
.then((rawdata) => {
|
|
this.rawdata = rawdata;
|
|
this.parseSupportedBands(rawdata);
|
|
})
|
|
.then(() => {
|
|
this.getLockedBands();
|
|
});
|
|
}
|
|
},
|
|
|
|
parseSupportedBands(rawdata) {
|
|
const data = rawdata;
|
|
const regex = /"([^"]+)",([0-9:]+)/g;
|
|
|
|
// Object to store the results
|
|
const bands = {};
|
|
|
|
let match;
|
|
while ((match = regex.exec(data)) !== null) {
|
|
const bandType = match[1];
|
|
const numbers = match[2].split(":").map(Number);
|
|
bands[bandType] = numbers;
|
|
}
|
|
|
|
// Seperate the bands for each network mode
|
|
this.lte_bands = bands.lte_band.join(":");
|
|
this.nsa_bands = bands.nsa_nr5g_band.join(":");
|
|
this.sa_bands = bands.nr5g_band.join(":");
|
|
},
|
|
|
|
getLockedBands() {
|
|
const atcmd =
|
|
'AT+QNWPREFCFG="lte_band";+QNWPREFCFG= "nsa_nr5g_band";+QNWPREFCFG= "nr5g_band"';
|
|
|
|
this.sendATcommand(atcmd)
|
|
.then((rawdata) => {
|
|
this.rawdata = rawdata;
|
|
this.parseLockedBands(rawdata);
|
|
})
|
|
.then(() => {
|
|
// Call current settings
|
|
this.getCurrentSettings();
|
|
});
|
|
},
|
|
|
|
parseLockedBands(rawdata) {
|
|
const data = rawdata;
|
|
const regex = /"([^"]+)",([0-9:]+)/g;
|
|
|
|
// Object to store the results
|
|
const bands = {};
|
|
|
|
let match;
|
|
while ((match = regex.exec(data)) !== null) {
|
|
const bandType = match[1];
|
|
const numbers = match[2].split(":").map(Number);
|
|
bands[bandType] = numbers;
|
|
}
|
|
|
|
// Seperate the bands for each network mode
|
|
this.locked_lte_bands = bands.lte_band.join(":");
|
|
this.locked_nsa_bands = bands.nsa_nr5g_band.join(":");
|
|
this.locked_sa_bands = bands.nr5g_band.join(":");
|
|
|
|
populateCheckboxes(
|
|
this.lte_bands,
|
|
this.nsa_bands,
|
|
this.sa_bands,
|
|
this.locked_lte_bands,
|
|
this.locked_nsa_bands,
|
|
this.locked_sa_bands,
|
|
this
|
|
);
|
|
},
|
|
|
|
init() {
|
|
// Function to populate checkboxes
|
|
const showPopulateCheckboxes = () => {
|
|
this.isGettingBands = true;
|
|
this.getSupportedBands();
|
|
this.isGettingBands = false;
|
|
|
|
// Add event listeners to checkboxes after populating them
|
|
addCheckboxListeners(this);
|
|
};
|
|
|
|
// Function to track checkbox changes
|
|
this.trackCheckboxChanges = () => {
|
|
var selectedMode =
|
|
document.getElementById("networkModeBand").value;
|
|
var checkboxes = document.querySelectorAll(
|
|
'input[type="checkbox"]'
|
|
);
|
|
var newCheckedValues = [];
|
|
|
|
checkboxes.forEach(function (checkbox) {
|
|
if (checkbox.checked) {
|
|
newCheckedValues.push(checkbox.value);
|
|
}
|
|
});
|
|
|
|
// Update currentNetworkMode and updatedLockedBands
|
|
this.currentNetworkMode = selectedMode;
|
|
this.updatedLockedBands = newCheckedValues;
|
|
};
|
|
|
|
// Function to add event listener to network mode dropdown
|
|
const addNetworkModeListener = () => {
|
|
document
|
|
.getElementById("networkModeBand")
|
|
.addEventListener("change", function () {
|
|
showPopulateCheckboxes(); // Update checkboxes when network mode changes
|
|
});
|
|
};
|
|
|
|
// Execute necessary functions on initialization
|
|
showPopulateCheckboxes();
|
|
addNetworkModeListener();
|
|
},
|
|
getCurrentSettings() {
|
|
const atcmd =
|
|
'AT+QUIMSLOT?;+CGCONTRDP=1;+QNWLOCK="common/4g";+QNWLOCK="common/5g";+QNWPREFCFG="mode_pref";+QNWPREFCFG="nr5g_disable_mode";+QCAINFO;+CGDCONT?';
|
|
|
|
this.sendATcommand(atcmd).then((rawdata) => {
|
|
const settings = parseCurrentSettings(rawdata);
|
|
this.sim = settings.sim;
|
|
this.apn = settings.apn;
|
|
this.apnIP = settings.apnIP;
|
|
this.cellLockStatus = settings.cellLockStatus;
|
|
this.prefNetwork = settings.prefNetwork;
|
|
this.nrModeControl = settings.nrModeControl;
|
|
this.bands = settings.bands;
|
|
});
|
|
},
|
|
lockSelectedBands() {
|
|
// Get the updated this.currentNetworkMode = selectedMode; and this.updatedLockedBands = newCheckedValues;
|
|
const selectedMode = this.currentNetworkMode;
|
|
const newCheckedValues = this.updatedLockedBands;
|
|
let atcmd;
|
|
|
|
// Check if both values are null then show the error message
|
|
if (selectedMode === null || newCheckedValues === null) {
|
|
} else {
|
|
if (selectedMode === "LTE") {
|
|
atcmd = `AT+QNWPREFCFG="lte_band",${newCheckedValues.join(
|
|
":"
|
|
)}`;
|
|
this.sendATcommand(atcmd);
|
|
} else if (selectedMode === "NSA") {
|
|
atcmd = `AT+QNWPREFCFG="nsa_nr5g_band",${newCheckedValues.join(
|
|
":"
|
|
)}`;
|
|
this.sendATcommand(atcmd);
|
|
} else if (selectedMode === "SA") {
|
|
atcmd = `AT+QNWPREFCFG="nr5g_band",${newCheckedValues.join(
|
|
":"
|
|
)}`;
|
|
this.sendATcommand(atcmd);
|
|
} else {
|
|
alert("Invalid network mode selected");
|
|
}
|
|
|
|
// Do a 2 second countdown
|
|
this.showModal = true;
|
|
this.countdown = 2;
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
|
|
// Refresh the page to show the updated bands
|
|
this.init();
|
|
}
|
|
}, 1000);
|
|
}
|
|
},
|
|
resetBandLocking() {
|
|
// Send the atcmd command to reset the locked bands
|
|
const atcmd = 'AT+QNWPREFCFG="restore_band"';
|
|
|
|
this.showModal = true;
|
|
|
|
this.sendATcommand(atcmd);
|
|
|
|
this.countdown = 5;
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
|
|
// Refresh the page to show the updated bands
|
|
this.init();
|
|
}
|
|
}, 1000);
|
|
|
|
// Run init function to repopulate the checkboxes
|
|
this.init();
|
|
},
|
|
saveChanges() {
|
|
const newApn = this.newApn;
|
|
const newSim = this.newSim;
|
|
const prefNetworkMode = this.prefNetworkMode;
|
|
const nrModeControl = this.nrModeControl;
|
|
|
|
let atAPN, atSIM, ATNetwork, ATNRMode, atcmd;
|
|
atAPN = "";
|
|
atSIM = "";
|
|
ATNetwork = "";
|
|
ATNRMode = "";
|
|
|
|
if (newApn !== null) {
|
|
if (this.newApnIP === "1") {
|
|
atAPN = `+CGDCONT=1,"IP","${newApn}";`;
|
|
} else if (this.newApnIP === "2") {
|
|
atAPN = `+CGDCONT=1,"IPV6","${newApn}";`;
|
|
} else if (this.newApnIP === "3") {
|
|
atAPN = `+CGDCONT=1,"IPV4V6","${newApn}";`;
|
|
} else if (this.newApnIP === "4") {
|
|
atAPN = `+CGDCONT=1,"PPP","${newApn}";`;
|
|
} else {
|
|
console.log("No changes made");
|
|
atAPN = `+CGDCONT=1,"IPV4V6","${newApn}";`;
|
|
}
|
|
}
|
|
|
|
if (newSim !== null) {
|
|
atSIM = `+QUIMSLOT=${newSim};`;
|
|
}
|
|
|
|
if (prefNetworkMode !== null) {
|
|
ATNetwork = `+QNWPREFCFG="mode_pref",${prefNetworkMode};`;
|
|
}
|
|
|
|
if (nrModeControl !== this.nrModeControl) {
|
|
ATNRMode = `+QNWPREFCFG="nr5g_disable_mode",${nrModeControl}`;
|
|
}
|
|
|
|
atcmd = `AT+${atAPN}${atSIM}${ATNetwork}${ATNRMode}`;
|
|
// If there is double + (++), remove 1 + from the command
|
|
atcmd = atcmd.replace("++", "+");
|
|
if (atcmd !== "AT+") {
|
|
this.showModal = true;
|
|
console.log(atcmd);
|
|
|
|
// If atcmd has QUIMSLOT, do a reboot instead
|
|
if (atcmd.includes("QUIMSLOT")) {
|
|
atcmd = atcmd + "+CFUN=1,1";
|
|
this.sendATcommand(atcmd);
|
|
this.countdown = 45;
|
|
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
this.init();
|
|
}
|
|
}, 1000);
|
|
|
|
return;
|
|
}
|
|
|
|
this.sendATcommand(atcmd);
|
|
// Do a 15 second countdown
|
|
this.countdown = 15;
|
|
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
this.init();
|
|
}
|
|
}, 1000);
|
|
} else {
|
|
alert("No changes made");
|
|
}
|
|
},
|
|
cellLockEnableLTE() {
|
|
const cellNum = this.cellNum;
|
|
|
|
if (cellNum === null) {
|
|
alert("Please enter the number of cells to lock");
|
|
return; // Exit the function early if cellNum is null
|
|
}
|
|
|
|
// Create an array to hold earfcn and pci pairs
|
|
const earfcnPciPairs = [
|
|
{ earfcn: this.earfcn1, pci: this.pci1 },
|
|
{ earfcn: this.earfcn2, pci: this.pci2 },
|
|
{ earfcn: this.earfcn3, pci: this.pci3 },
|
|
{ earfcn: this.earfcn4, pci: this.pci4 },
|
|
{ earfcn: this.earfcn5, pci: this.pci5 },
|
|
{ earfcn: this.earfcn6, pci: this.pci6 },
|
|
{ earfcn: this.earfcn7, pci: this.pci7 },
|
|
{ earfcn: this.earfcn8, pci: this.pci8 },
|
|
{ earfcn: this.earfcn9, pci: this.pci9 },
|
|
{ earfcn: this.earfcn10, pci: this.pci10 },
|
|
];
|
|
|
|
// Filter out pairs where either earfcn or pci is null
|
|
const validPairs = earfcnPciPairs.filter(
|
|
(pair) => pair.earfcn !== null && pair.pci !== null
|
|
);
|
|
|
|
if (validPairs.length === 0) {
|
|
alert("Please enter at least one valid earfcn and pci pair");
|
|
return; // Exit the function early if no valid pairs are found
|
|
}
|
|
|
|
// Construct the AT command using the valid pairs
|
|
let atcmd = `AT+QNWLOCK="common/4g",${cellNum},${validPairs
|
|
.map((pair) => `${pair.earfcn},${pair.pci}`)
|
|
.join(",")}`;
|
|
|
|
// Mock data
|
|
this.showModal = true;
|
|
|
|
this.sendATcommand(atcmd);
|
|
|
|
// Do a 15 second countdown
|
|
this.countdown = 15;
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
}
|
|
}, 1000);
|
|
},
|
|
cellLockEnableNR() {
|
|
const earfcn = this.earfcn1;
|
|
const pci = this.pci1;
|
|
const scs = this.scs;
|
|
const band = this.band;
|
|
|
|
if (
|
|
earfcn === null ||
|
|
pci === null ||
|
|
scs === null ||
|
|
band === null
|
|
) {
|
|
alert("Please enter all the required fields");
|
|
return; // Exit the function early if any of the fields are null
|
|
}
|
|
|
|
// Construct the AT command using the valid pairs
|
|
let atcmd = `AT+QNWLOCK="common/5g",${pci},${earfcn},${scs},${band}`;
|
|
|
|
// Mock data
|
|
this.showModal = true;
|
|
|
|
this.sendATcommand(atcmd);
|
|
|
|
// Do a 15 second countdown
|
|
this.countdown = 15;
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
}
|
|
}, 1000);
|
|
},
|
|
cellLockDisableLTE() {
|
|
// Send the atcmd command to reset the locked bands
|
|
const atcmd = 'AT+QNWLOCK="common/4g",0';
|
|
this.showModal = true;
|
|
|
|
this.sendATcommand(atcmd);
|
|
|
|
this.countdown = 15;
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
}
|
|
}, 1000);
|
|
},
|
|
cellLockDisableNR() {
|
|
// Send the atcmd command to reset the locked bands
|
|
const atcmd = 'AT+QNWLOCK="common/5g",0';
|
|
|
|
this.showModal = true;
|
|
|
|
this.sendATcommand(atcmd);
|
|
|
|
this.countdown = 15;
|
|
const interval = setInterval(() => {
|
|
this.countdown--;
|
|
if (this.countdown === 0) {
|
|
clearInterval(interval);
|
|
this.showModal = false;
|
|
}
|
|
}, 1000);
|
|
},
|
|
sendATcommand(atcmd) {
|
|
return fetch(
|
|
"/cgi-bin/get_atcommand?" +
|
|
new URLSearchParams({
|
|
atcmd: atcmd,
|
|
})
|
|
)
|
|
.then((response) => response.text())
|
|
.then((data) => {
|
|
return data;
|
|
})
|
|
.catch((error) => {
|
|
console.error("Error:", error);
|
|
// Throw the error again to ensure it's propagated
|
|
throw error;
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
function addCheckboxListeners(cellLock) {
|
|
// Remove existing event listeners
|
|
document
|
|
.querySelectorAll('input[type="checkbox"]')
|
|
.forEach(function (checkbox) {
|
|
checkbox.removeEventListener(
|
|
"change",
|
|
cellLock.trackCheckboxChanges
|
|
);
|
|
});
|
|
|
|
// Add new event listeners
|
|
document
|
|
.querySelectorAll('input[type="checkbox"]')
|
|
.forEach(function (checkbox) {
|
|
checkbox.addEventListener("change", cellLock.trackCheckboxChanges);
|
|
});
|
|
}
|
|
|
|
// Function for unchecking all checkboxes
|
|
document
|
|
.getElementById("uncheckAll")
|
|
.addEventListener("click", function () {
|
|
document
|
|
.querySelectorAll('input[type="checkbox"]')
|
|
.forEach(function (checkbox) {
|
|
checkbox.checked = false;
|
|
});
|
|
});
|
|
|
|
// Function for setting the provider bands checkbox and fetching the bands
|
|
document
|
|
.getElementById("providerBands")
|
|
.addEventListener("change", function () {
|
|
cellLocking().getSupportedBands();
|
|
});
|
|
|
|
document.addEventListener("DOMContentLoaded", (event) => {
|
|
loadCheckboxState();
|
|
});
|
|
|
|
function saveCheckboxState() {
|
|
const providerBandsCheckbox = document.getElementById("providerBands");
|
|
localStorage.setItem(
|
|
"providerBandsChecked",
|
|
providerBandsCheckbox.checked
|
|
);
|
|
}
|
|
|
|
function loadCheckboxState() {
|
|
const providerBandsCheckbox = document.getElementById("providerBands");
|
|
const isChecked =
|
|
localStorage.getItem("providerBandsChecked") === "true";
|
|
providerBandsCheckbox.checked = isChecked;
|
|
}
|
|
</script>
|
|
<script src="js/dark-mode.js"></script>
|
|
</body>
|
|
</html>
|