Major Toolkit Update

New: simple settings for band locking, cell locking, and other settable settings.

New: Tailscale and ttyd now get the binaries directly from their sources

Updated: tailscale and ttyd versions

Updated: simpleadmin is now installed by downloading each file individually and directly to the spot it needs to be in

Removed: TTL Only and No at commands versions of simpleadmin. If anyone needs this please open an issue.
This commit is contained in:
Cameron Thompson
2024-03-31 01:50:44 -04:00
parent de74eecd77
commit 20e2aca705
10 changed files with 1064 additions and 213 deletions

View File

@@ -11,12 +11,6 @@ SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
SIMPLE_FIREWALL_SERVICE="/lib/systemd/system/simplefirewall.service"
GITHUB_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/$GITTREE.zip"
GITHUB_SIMPADMIN_FULL_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadminfull.zip"
GITHUB_SIMPADMIN_NOCMD_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadminnoatcmds.zip"
GITHUB_SIMPADMIN_TTL_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadminttlonly.zip"
GITHUB_SIMPADMIN_TEST_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadmintest.zip"
TAILSCALE_DIR="/usrdata/tailscale/"
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
# AT Command Script Variables and Functions
@@ -310,97 +304,134 @@ configure_simple_firewall() {
install_simple_admin() {
while true; do
echo -e "\e[1;32mWhat version of Simple Admin do you want to install? This will start a webserver on port 8080\e[0m"
echo -e "\e[1;32m1) Full Install\e[0m"
echo -e "\e[1;34m2) No AT Commands, List only\e[0m"
echo -e "\e[1;33m3) TTL Only\e[0m"
echo -e "\e[1;31m4) Install Test Build (work in progress/not ready yet)\e[0m"
echo -e "\e[0;33m5) Return to Main Menu\e[0m"
echo -e "\e[1;32m1) Stable current version, (Main Branch)\e[0m"
echo -e "\e[1;31m2) Install Test Build (Development Branch)\e[0m"
echo -e "\e[0;33m3) Return to Main Menu\e[0m"
echo -e "\e[1;32mSelect your choice: \e[0m"
read choice
case $choice in
1)
install_update_at_socat
echo -e "\e[1;32mInstalling simpleadmin from the main stable branch\e[0m"
install_update_at_socat
sleep 1
install_simple_firewall
sleep 1
remount_rw
cd $TMP_DIR
wget $GITHUB_SIMPADMIN_FULL_URL -O simpleadminfull.zip
unzip -o simpleadminfull.zip
cp -Rf quectel-rgmii-toolkit-simpleadminfull/simpleadmin/ $USRDATA_DIR
sleep 1
mkdir $SIMPLE_ADMIN_DIR
mkdir $SIMPLE_ADMIN_DIR/systemd
mkdir $SIMPLE_ADMIN_DIR/scripts
mkdir $SIMPLE_ADMIN_DIR/www
mkdir $SIMPLE_ADMIN_DIR/www/cgi-bin
mkdir $SIMPLE_ADMIN_DIR/www/css
mkdir $SIMPLE_ADMIN_DIR/www/js
cd $SIMPLE_ADMIN_DIR/systemd
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/systemd/simpleadmin_generate_status.service
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/systemd/simpleadmin_httpd.service
sleep 1
cd $SIMPLE_ADMIN_DIR/scripts
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/scripts/build_modem_status
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/scripts/modemstatus_parse.sh
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/scripts/tojson.sh
sleep 1
cd $SIMPLE_ADMIN_DIR/www
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/atcommander.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/index.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/speedtest.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/styles.css
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/ttl.html
sleep 1
cd $SIMPLE_ADMIN_DIR/www/js
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/js/alpinejs.min.js
sleep 1
cd $SIMPLE_ADMIN_DIR/www/css
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/css/admin.css
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/css/bulma.css
sleep 1
cd $SIMPLE_ADMIN_DIR/www/cgi-bin
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/cgi-bin/get_atcommand
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/cgi-bin/get_csq
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/cgi-bin/get_ttl_status
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/simpleadmin/www/cgi-bin/set_ttl
sleep 1
cd /
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
systemctl daemon-reload
sleep 1
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
ln -sf /lib/systemd/system/simpleadmin_generate_status.service /lib/systemd/system/multi-user.target.wants/
systemctl start simpleadmin_generate_status
sleep 1
systemctl start simpleadmin_httpd
remount_ro
echo "Cleaning up..."
rm /tmp/simpleadminfull.zip
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminfull/
echo -e "\e[1;32msimpleadmin has been installed and is now ready for use!\e[0m"
break
;;
2)
install_update_at_socat
echo -e "\e[1;31m2) Installing simpleadmin from the development test branch\e[0m"
install_update_at_socat
sleep 1
install_simple_firewall
sleep 1
remount_rw
cd $TMP_DIR
wget $GITHUB_SIMPADMIN_NOCMD_URL -O simpleadminnoatcmds.zip
unzip -o simpleadminnoatcmds.zip
cp -Rf quectel-rgmii-toolkit-simpleadminnoatcmds/simpleadmin/ $USRDATA_DIR
sleep 1
mkdir $SIMPLE_ADMIN_DIR
mkdir $SIMPLE_ADMIN_DIR/systemd
mkdir $SIMPLE_ADMIN_DIR/scripts
mkdir $SIMPLE_ADMIN_DIR/www
mkdir $SIMPLE_ADMIN_DIR/www/cgi-bin
mkdir $SIMPLE_ADMIN_DIR/www/css
mkdir $SIMPLE_ADMIN_DIR/www/js
cd $SIMPLE_ADMIN_DIR/systemd
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/systemd/simpleadmin_generate_status.service
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/systemd/simpleadmin_httpd.service
sleep 1
cd $SIMPLE_ADMIN_DIR/scripts
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/scripts/build_modem_status
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/scripts/modemstatus_parse.sh
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/scripts/tojson.sh
sleep 1
cd $SIMPLE_ADMIN_DIR/www
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/atcommander.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/index.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/speedtest.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/styles.css
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/ttl.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/sms.html
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/bandlock.html
sleep 1
cd $SIMPLE_ADMIN_DIR/www/js
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/js/alpinejs.min.js
sleep 1
cd $SIMPLE_ADMIN_DIR/www/css
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/css/admin.css
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/css/bulma.css
sleep 1
cd $SIMPLE_ADMIN_DIR/www/cgi-bin
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/cgi-bin/get_atcommand
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/cgi-bin/get_csq
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/cgi-bin/get_ttl_status
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/development/simpleadmin/www/cgi-bin/set_ttl
sleep 1
cd /
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
systemctl daemon-reload
sleep 1
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
ln -sf /lib/systemd/system/simpleadmin_generate_status.service /lib/systemd/system/multi-user.target.wants/
systemctl start simpleadmin_generate_status
sleep 1
systemctl start simpleadmin_httpd
remount_ro
echo "Cleaning up..."
rm /tmp/simpleadminnoatcmds.zip
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminnoatcmds/
echo -e "\e[1;32msimpleadmin has been installed and is now ready for use!\e[0m"
break
;;
3)
install_simple_firewall
remount_rw
cd $TMP_DIR
wget $GITHUB_SIMPADMIN_TTL_URL -O simpleadminttlonly.zip
unzip -o simpleadminttlonly.zip
cp -Rf quectel-rgmii-toolkit-simpleadminttlonly/simpleadmin/ $USRDATA_DIR
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
systemctl daemon-reload
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
systemctl start simpleadmin_httpd
remount_ro
echo "Cleaning up..."
rm /tmp/simpleadminttlonly.zip
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminttlonly/
break
;;
4)
install_update_at_socat
install_simple_firewall
remount_rw
cd $TMP_DIR
wget $GITHUB_SIMPADMIN_TEST_URL -O simpleadmintest.zip
unzip -o simpleadmintest.zip
cp -Rf quectel-rgmii-toolkit-simpleadmintest/simpleadmin/ $USRDATA_DIR
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
systemctl daemon-reload
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
ln -sf /lib/systemd/system/simpleadmin_generate_status.service /lib/systemd/system/multi-user.target.wants/
systemctl start simpleadmin_generate_status
systemctl start simpleadmin_httpd
remount_ro
break
;;
5)
3)
echo "Returning to main menu..."
break
;;
@@ -542,11 +573,15 @@ install_update_remove_tailscale() {
echo "Creating /usrdata/tailscale/"
mkdir $TAILSCALE_DIR
mkdir $TAILSCALE_SYSD_DIR
echo "Downloading binary files..."
cd /usrdata
wget https://pkgs.tailscale.com/stable/tailscale_1.62.1_arm.tgz
tar -xzf tailscale_1.62.1_arm.tgz
cd /usrdata/tailscale_1.62.1_arm
mv tailscale $TAILSCALE_DIR/tailscale
mv tailscaled $TAILSCALE_DIR/tailscaled
cd $TAILSCALE_DIR
echo "Downloading binary: /usrdata/tailscale/tailscaled"
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/tailscaled
echo "Downloading binary: /usrdata/tailscale/tailscale"
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/tailscale
rm -rf /usrdata/tailscale_1.62.1_arm
echo "Downloading systemd files..."
cd $TAILSCALE_SYSD_DIR
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.service
@@ -996,7 +1031,20 @@ echo " :+##+. "
install_ttyd
;;
9)
echo -e "\e[1;32mInstalling Speedtest.net CLI (speedtest command)\e[0m"
echo -e "\e[1;32mInstalling Speedtest.net CLI (speedtest command)\e[0m"
# Check for existing Entware/opkg installation, install if not installed
if [ ! -f "/opt/bin/opkg" ]; then
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
cd /tmp && wget -O installentware.sh "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/installentware.sh" && chmod +x installentware.sh && ./installentware.sh
if [ "$?" -ne 0 ]; then
echo -e "\e[1;31mEntware/OPKG installation failed. Please check your internet connection or the repository URL.\e[0m"
exit 1
fi
cd /
else
echo -e "\e[1;32mEntware/OPKG is already installed.\e[0m"
fi
echo -e "\e[1;32mInstalling Speedtest.net CLI (speedtest command)\e[0m"
remount_rw
mkdir /usrdata/root
mkdir /usrdata/root/bin
@@ -1010,6 +1058,9 @@ echo " :+##+. "
remount_ro
echo -e "\e[1;32mSpeedtest CLI (speedtest command) installed!!\e[0m"
echo -e "\e[1;32mTry running the command 'speedtest'\e[0m"
echo -e "\e[1;32mNote that it will not work unless you login to the root account first\e[0m"
echo -e "\e[1;32mNormaly only an issue in adb, ttyd and ssh you are forced to login\e[0m"
echo -e "\e[1;32mIf in adb just type login and then try to run the speedtest command\e[0m"
;;
10)
echo -e "\e[1;32mInstalling fast.com CLI (fast command)\e[0m"

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AT Commands</title>
<title>Simple Settings</title>
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css" />
@@ -35,7 +35,10 @@
>
<div class="navbar-start">
<a class="navbar-item" href="/"> Connection Info </a>
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
<a class="navbar-item" href="/atcommander.html">
Simple Settings
</a>
<a class="navbar-item" href="/bandlock.html"> Simple Network </a>
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
<a class="navbar-item" href="/speedtest.html"> Speedtest </a>
</div>
@@ -93,13 +96,13 @@
<div class="column is-8">
<div class="card">
<header class="card-header">
<p class="card-header-title">ATI Response</p>
<p class="card-header-title">AT Command Response</p>
</header>
<div class="card-content">
<div class="content">
<textarea
class="textarea"
placeholder="Please send only 1 AT command at a time"
placeholder="Multiple commands should be separated by a semicolon. Example: AT+CGMR;+GSN"
rows="10"
x-text="isLoading ? 'Fetching response, please wait...' : atCommandResponse"
></textarea>
@@ -113,156 +116,63 @@
</div>
<!-- START Useful Commands Section -->
<div class="container">
<div class="container" x-data="atCommands()">
<div class="columns">
<div class="column is-12">
<div class="card">
<header class="card-header">
<p class="card-header-title">Useful Commands</p>
<p class="card-header-title">Useful One Click Commands</p>
</header>
<div class="card-content">
<div class="content">
<div
class="field"
style="margin-bottom: 1rem"
x-data="atCommands()"
>
<p class="control">
<button
class="button is-danger"
@click="sendRebootCommand()"
:disabled="isRebooting"
>
Reboot
</button>
</p>
<!-- Loading modal -->
<div x-show="isRebooting" class="modal-overlay">
<div class="loading-modal">
<div class="spinner"></div>
<div class="loading-text" style="display: flex; flex-direction: column;">
<h3>Rebooting...</h3>
<p style="margin-top: 0.5rem;">Please wait for
<span x-text="countdown" style="font-weight: 500;"></span> seconds before
refreshing the page.</p>
</div>
<div style="display: flex; flex-direction: row; flex-wrap: wrap; margin-top: 1rem; justify-content: space-between;">
<div class="field">
<div class="control">
<button
class="button is-danger"
@click="sendRebootCommand()"
:disabled="isRebooting"
>
Reboot
</button>
</div>
</div>
<!-- <div class="field">
<div class="control">
<button
class="button is-danger"
@click="sendRebootCommand()"
:disabled="isRebooting"
>
Reboot
</button>
</div>
</div> -->
</div>
<!-- Add your useful commands content here -->
<p>Here are some useful commands:</p>
<ul>
<li>
<!-- Open to another tab -->
See <a href="https://github.com/iamromulan/RM520N-GL#at-commands" target="_blank" style="cursor: pointer;">https://github.com/iamromulan/RM520N-GL#at-commands</a> for
more
</li>
<li>AT+CFUN=1,1 (reboot)</li>
<li>
AT+QMAPWAC? (get current status of auto connect, 0=disabled
1=enabled)
</li>
<li>
AT+QMAPWAC=1 (enable auto connect internet for ethernet)
</li>
<li>
AT+QMAPWAC=0 (disable auto connect for ethernet; use when
you want internet over usb to work; IPPT must be disabled)
</li>
<li>
AT+QUIMSLOT? (get active sim slot; 1=Slot 1; 2=Slot 2)
</li>
<li>AT+QUIMSLOT=1 (switch to sim slot 1)</li>
<li>AT+QUIMSLOT=2 (switch to sim slot 2)</li>
<li>AT+CGDCONT? (Get active APN profle list 1 through 8)</li>
<li>
AT+CGDCONT=1,"IPV4V6","APNHERE" (Sets APN profle 1 to
APNHERE using both IPV4 and IPV6)
</li>
<li>AT+GSN (Show current IMEI)</li>
<li>AT+EGMR=1,7,"IMEIGOESHERE" (sets/repairs IMEI)</li>
<li>AT+QCAINFO (Show all connected bands/CA info)</li>
<li>
AT+QNWPREFCFG="mode_pref" (Check what the current network
search mode is set to)
</li>
<li>
AT+QNWPREFCFG="mode_pref",AUTO (Set network search mode to
automatic)
</li>
<li>
AT+QNWPREFCFG="mode_pref",NR5G:LTE (Set network search mode
to 5G/NR and 4G/LTE only)
</li>
<li>
AT+QNWPREFCFG="mode_pref",NR5G (Set network search mode to
5G/NR only)
</li>
<li>
AT+QNWPREFCFG="mode_pref",LTE (Set network search mode to
4G/LTE only)
</li>
<li>
AT+QNWPREFCFG="nr5g_disable_mode" (Check to see if SA or NSA
NR5G is disabled)
</li>
<li>
AT+QNWPREFCFG="nr5g_disable_mode",0 (Enable Both SA and NSA
5G/NR)
</li>
<li>
AT+QNWPREFCFG="nr5g_disable_mode",1 (Disable SA 5G/NR only)
</li>
<li>
AT+QNWPREFCFG="nr5g_disable_mode",2 (Disable NSA 5G/NR only)
</li>
<li>
AT+QNWPREFCFG="nr5g_band" (Get current 5G/NR bandlock
settings)
</li>
<li>
AT+QNWPREFCFG="nr5g_band",1:2:3:4:5:6 (Example: Lock to
5G/NR bands n1,n2,n3,n4,n5, and n6)
</li>
<li>
AT+QNWPREFCFG="lte_band" (Get current 4G/LTE bandlock
settings)
</li>
<li>
AT+QNWPREFCFG="lte_band",1:2:3:4:5:6 (Example: Lock to
4G/LTE bands 1,2,3,4,5, and 6)
</li>
<li>
AT+QMAP="WWAN" (Show currently assigned IPv4 and IPv6 from
the provider)
</li>
<li>
AT+QMAP="LANIP" (Show current DHCP range and Gateway address
for VLAN0)
</li>
<li>
AT+QMAP="LANIP",IP_start_range,IP_end_range,Gateway_IP (Set
IPv4 Start/End range and Gateway IP of DHCP for VLAN0)
</li>
<li>
AT+QMAP="DHCPV4DNS","disable" (disable the onboard DNS
proxy; recommended for IPPT)
</li>
<li>
AT+QMAP="MPDN_rule",0,1,0,1,1,"FF:FF:FF:FF:FF:FF" (Turn on
IP Passthrough for Ethernet)
</li>
<li>
AT+QMAP="MPDN_rule",0 (turn off IPPT/clear MPDN rule 0;
Remember to run AT+QMAPWAC=1 and reboot after)
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Loading modal -->
<div x-show="isRebooting" class="modal-overlay">
<div class="loading-modal">
<div class="spinner"></div>
<div
class="loading-text"
style="display: flex; flex-direction: column"
>
<h3>Rebooting...</h3>
<p style="margin-top: 0.5rem">
Please wait for
<span x-text="countdown" style="font-weight: 500"></span> seconds
before refreshing the page.
</p>
</div>
</div>
</div>
</div>
<script>

View File

@@ -0,0 +1,877 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Simple Network</title>
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css" />
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
<link rel="stylesheet" href="styles.css" />
<style>
.container {
display: flex;
justify-content: center;
}
.card-column {
margin-bottom: 20px;
}
</style>
</head>
<body>
<!-- START NAV -->
<nav class="navbar is-black" x-data="{ isOpen: false }">
<div class="container">
<div class="navbar-brand">
<a class="navbar-item brand-text" href="/"> Simple Admin </a>
<a
role="button"
class="navbar-burger burger"
@click="isOpen = !isOpen"
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div
id="navMenu"
class="navbar-menu"
:class="isOpen ? 'is-active' : ''"
>
<div class="navbar-start">
<a class="navbar-item" href="/"> Connection Info </a>
<a class="navbar-item" href="/atcommander.html">
Simple Settings
</a>
<a class="navbar-item" href="/bandlock.html"> Simple Network </a>
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
<a class="navbar-item" href="/speedtest.html"> Speedtest </a>
</div>
</div>
</div>
</nav>
<!-- END NAV -->
<div
class="container"
style="margin: auto"
x-data="atCommands()"
x-init="atCommands()"
>
<div class="columns is-multiline">
<!-- First Box -->
<div class="column is-8-tablet is-6-desktop card-column">
<div class="card">
<header class="card-header">
<p class="card-header-title">Band Locking</p>
</header>
<div class="card-content">
<!-- Create a drop down -->
<div class="select is-primary">
<select id="networkMode" x-model="networkMode">
<option>Select Network Mode</option>
<option>LTE</option>
<option>NR5G-NSA</option>
<option>NR5G-SA</option>
</select>
</div>
<input
class="input is-primary"
type="text"
placeholder="Example: 1,3,41"
style="margin-top: 1rem"
x-model="bandNumbers"
/>
<div style="margin-top: 1rem; display: flex; flex-direction: row">
<button
class="button is-primary"
@click="lockBands()"
:disabled="isLocking"
>
Lock Bands
</button>
<button
class="button is-warning"
style="margin-left: 1rem"
@click="restoreBands()"
:disabled="isLocking"
>
Restore Bands
</button>
</div>
</div>
<div class="card-footer" style="padding: 0.25rem">
<p class="card-footer-item">
Please first select your desired network band from the dropdown
menu. To lock onto specific bands, please type the band numbers
separated by commas (,) and then click the lock button.
</p>
</div>
</div>
</div>
<!-- Second Box -->
<div class="column is-8-tablet is-6-desktop card-column">
<div class="card">
<header class="card-header">
<p class="card-header-title">LTE and NR5G Cell Locking</p>
</header>
<div class="card-content">
<div style="display: flex; flex-direction: row">
<div class="select is-info">
<select id="networkModeSelect" x-model="networkMode2">
<option>Select Network Mode</option>
<option>LTE</option>
<option>NR5G-SA</option>
</select>
</div>
<div
id="numFreqContainer"
style="margin-left: 1rem"
x-show="networkMode2 == 'LTE'"
>
<input
class="input is-info"
type="number"
id="numFreqInput"
min="1"
max="10"
placeholder="1-10"
x-model="cellNum"
/>
</div>
</div>
<div id="freqNumbersContainer"></div>
<!-- For NR5G-SA -->
<div style="margin-top: 1rem" x-show="networkMode2 == 'NR5G-SA'">
<div style="display: flex; flex-direction: row">
<input
class="input is-info"
type="text"
placeholder="EARFCN"
x-model="earfcn1"
/>
<input
class="input is-info"
type="text"
placeholder="PCI"
x-model="pci1"
style="margin-left: 1rem"
/>
<input
class="input is-info"
type="text"
placeholder="SCS"
x-model="scs"
style="margin-left: 1rem"
/>
<input
class="input is-info"
type="text"
placeholder="BAND"
x-model="band"
style="margin-left: 1rem"
/>
</div>
</div>
<div style="margin-top: 1rem; display: flex; flex-direction: row">
<button
class="button is-info"
@click="cellLock()"
:disabled="isLocking"
>
Lock Cell
</button>
<button
class="button is-warning"
style="margin-left: 1rem"
@click="restoreCell()"
:disabled="isLocking"
>
Restore Cell
</button>
</div>
</div>
<div class="card-footer" style="padding: 0.25rem">
<p class="card-footer-item">
To utilize cell locking, first, select the network mode, then
specify the number of cells you wish to lock onto (max 10) if
you are using LTE. Next, input the EARFCN and PCI values for
each cell number. If you are locking through NR5G-SA instead,
simply fill up all the required parameters.
</p>
</div>
</div>
</div>
<!-- Third Box -->
<div class="column is-8-tablet is-6-desktop card-column">
<div class="card">
<header class="card-header">
<p class="card-header-title">Network Utilities</p>
</header>
<div class="card-content">
<div style="display: flex; flex-direction: column">
<div>
<p>Set Network APN</p>
<div
style="
display: flex;
flex-direction: row;
margin-top: 0.5rem;
"
>
<input
class="input is-link"
type="text"
placeholder="APN"
x-model="apnInput"
/>
<button
class="button is-link"
style="margin-left: 1rem"
@click="setAPN()"
:disabled="isLoading"
>
Set APN
</button>
</div>
</div>
</div>
<div style="margin-top: 1rem">
<p>Set Preferred Network Mode</p>
<div
style="display: flex; flex-direction: row; margin-top: 0.5rem"
>
<div class="select is-info">
<select id="prefNetworkMode" x-model="prefNetworkMode">
<option>Select Network</option>
<option>AUTO</option>
<option>WCDMA</option>
<option>LTE ONLY</option>
<option>NR5G-NSA</option>
<option>NR5G-SA</option>
</select>
</div>
<button
class="button is-link"
style="margin-left: 1rem"
@click="setPrefNetwork()"
:disabled="isLoading"
>
Set Network
</button>
</div>
</div>
<div style="margin-top: 1rem">
<p>Set Sim Slot</p>
<div
style="display: flex; flex-direction: row; margin-top: 0.5rem"
>
<div class="select is-info">
<select id="simSlot" x-model="simSlot">
<option>Select Sim</option>
<option>1</option>
<option>2</option>
</select>
</div>
<button
class="button is-link"
style="margin-left: 1rem"
@click="setSimSlot()"
:disabled="isLoading"
>
Set Sim
</button>
</div>
</div>
<div style="margin-top: 1rem">
<p>NR5G Mode Control</p>
<div
style="display: flex; flex-direction: row; margin-top: 0.5rem"
>
<div class="select is-info">
<select id="nrMode" x-model="nrMode">
<option>Select NR5G Mode</option>
<option>Enable All</option>
<option>Disable NSA</option>
<option>Disable SA</option>
</select>
</div>
<button
class="button is-link"
style="margin-left: 1rem"
@click="nr5GMode()"
:disabled="isLoading"
>
Set Mode
</button>
</div>
</div>
</div>
<div class="card-footer" style="padding: 0.25rem">
<p class="card-footer-item">
This section allows you to set the APN, preferred network mode,
and sim slot. Simply input the desired values and click the
respective buttons to apply the changes. (Sim slot is only
applicable for dual sim devices.)
</p>
</div>
</div>
</div>
<!-- Fourth Box -->
<div class="column is-8-tablet is-6-desktop card-column">
<div class="card">
<header class="card-header">
<p class="card-header-title">Query Network Parameters</p>
</header>
<div class="card-content">
<textarea
class="textarea"
rows="5"
placeholder="Query Response"
x-text=" isLoading ? 'Getting Response...' : queryCommandResponse"
></textarea>
<div style="margin-top: 1.5rem">
<p>Check Locked Bands</p>
<div class="select is-info" style="margin-top: 0.5rem">
<select id="lockedBands" x-model="lockedBands">
<option>Locked Bands</option>
<option>LTE</option>
<option>NSA</option>
<option>SA</option>
</select>
</div>
<button
class="button is-link"
style="margin-left: 1rem; margin-top: 0.5rem"
@click="showLockedBands()"
:disabled="isLoading"
>
Check Bands
</button>
</div>
<div style="margin-top: 1rem">
<p>Check Cell Lock</p>
<div class="select is-info" style="margin-top: 0.5rem">
<select id="cellState" x-model="cellState">
<option>Cell Lock</option>
<option>LTE</option>
<option>NR5G-SA</option>
</select>
</div>
<button
class="button is-link"
style="margin-left: 1rem; margin-top: 0.5rem"
@click="showCellState()"
:disabled="isLoading"
>
Check Cell
</button>
</div>
<div style="margin-top: 2rem">
<p>Other Network Query</p>
</div>
<div class="buttons" style="margin-top: 0.5rem">
<button
class="button is-link mr-2"
@click="showSupportedBands()"
:disabled="isLoading"
>
Show Supported Bands
</button>
<button
class="button is-link mr-2"
@click="showCurrentSim()"
:disabled="isLoading"
>
Show Current Sim
</button>
<button
class="button is-link"
@click="showPrefNetwork()"
:disabled="isLoading"
>
Show Pref Network
</button>
<button
class="button is-link"
@click="showCaInfo()"
:disabled="isLoading"
>
Carrier Aggregation Info
</button>
<button
class="button is-link"
@click="servingCellInfo()"
:disabled="isLoading"
>
Serving Cell Info
</button>
<button
class="button is-link"
@click="scanNeighbourCells()"
:disabled="isLoading"
>
Scan Neighbour Cells
</button>
<button
class="button is-link"
@click="scanNsaCells()"
:disabled="isLoading"
>
Scan NSA Cells
</button>
<button
class="button is-link"
@click="fullNetworkScan()"
:disabled="isLoading"
>
Full Network Scan
</button>
</div>
</div>
<div class="card-footer" style="padding: 0.25rem">
<p class="card-footer-item">
This section allows you to query the network parameters. Simply
click the respective buttons to view the network parameters.
</p>
</div>
</div>
</div>
</div>
<!-- Loading Modal for Locking Band -->
<div x-show="isLocking" class="modal-overlay">
<div class="loading-modal">
<div class="spinner"></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 x-show="isError" class="modal-overlay">
<div class="loading-modal">
<div class="spinner"></div>
<div
class="loading-text"
style="display: flex; flex-direction: column"
>
<h3>Request Error</h3>
<p style="margin-top: 0.5rem">
Please follow the instructions properly. Exiting in
<span x-text="countdown" style="font-weight: 500"></span> seconds.
</p>
</div>
</div>
</div>
</div>
<script>
function atCommands() {
return {
isLoading: false,
isQuerying: false,
isLocking: false,
isError: false,
countdown: 5, // Initial countdown value
networkMode: null,
networkMode2: null,
bandNumbers: null,
cellNum: null,
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,
band: null,
scs: null,
apnInput: null,
prefNetworkMode: null,
simSlot: null,
nrMode: null,
lockedBands: null,
cellState: null,
invalidCellNum: "",
atCommandResponse: "",
queryCommandResponse: "",
lockBands() {
if (!this.networkMode || !this.bandNumbers) {
this.isError = true;
this.startCountdown();
console.error("Network mode and band numbers are required.");
return;
}
// Remove commas and replace with colons
const parsedBandNumbers = this.bandNumbers.replace(/,/g, ":");
// Construct the atcmd based on the selected network mode
let atcmd;
switch (this.networkMode) {
case "LTE":
atcmd = `AT+QNWPREFCFG="lte_band",${parsedBandNumbers}`;
console.log(atcmd);
break;
case "NR5G-NSA":
atcmd = `AT+QNWPREFCFG="nsa_nr5g_band",${parsedBandNumbers}`;
console.log(atcmd);
break;
case "NR5G-SA":
atcmd = `AT+QNWPREFCFG="nr5g_band",${parsedBandNumbers}`;
console.log(atcmd);
break;
default:
console.error("Invalid network mode.");
return;
}
this.isLoading = true;
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: atcmd,
})
)
.then((res) => res.text())
.then((data) => {
this.atCommandResponse = data;
this.isLocking = true;
this.startCountdown();
})
.catch((error) => {
this.isError = true;
this.startCountdown();
console.error("Error sending AT command:", error);
})
.finally(() => {
this.isLoading = false;
});
},
cellLock() {
// Error handlers
if (!this.networkMode2) {
this.isError = true;
this.startCountdown();
console.error("Network mode is required.");
return;
}
// Construct the AT command based on the selected network mode
let atcmd;
if (this.networkMode2 === "LTE") {
if (parseInt(this.cellNum) > 10) {
this.invalidCellNum = "Invalid";
this.isError = true;
this.startCountdown();
console.error("Invalid frequency number.");
return;
}
this.isLocking = true;
atcmd = `AT+QNWLOCK="common/4g",${this.cellNum}`;
for (let i = 1; i <= parseInt(this.cellNum); i++) {
atcmd += `,${this["earfcn" + i]},${this["pci" + i]}`;
}
console.log(atcmd);
} else if (this.networkMode2 === "NR5G-SA") {
this.isLocking = true;
atcmd = `AT+QNWLOCK="common/5g",${this.pci1},${this.earfcn1},${this.scs},${this.band}`;
console.log(atcmd);
}
this.sendAtCommand(atcmd);
},
restoreBands() {
const restoreCmd = 'AT+QNWPREFCFG="restore_band"';
this.sendAtCommand(restoreCmd);
},
restoreCell() {
const restoreCmd = 'AT+QNWLOCK="common/4g",0';
this.sendAtCommand(restoreCmd);
},
setAPN() {
const apnCmd = `AT+CGDCONT=1,"IPV4V6","${this.apnInput}"`;
this.sendAtCommand(apnCmd);
},
setPrefNetwork() {
// AT+QNWPREFCFG="mode_pref",<mode>
let prefCmd;
switch (this.prefNetworkMode) {
case "AUTO":
prefCmd = 'AT+QNWPREFCFG="mode_pref",AUTO';
break;
case "WCDMA":
prefCmd = 'AT+QNWPREFCFG="mode_pref",WCDMA';
break;
case "LTE ONLY":
prefCmd = 'AT+QNWPREFCFG="mode_pref",LTE';
break;
case "NR5G-NSA":
prefCmd = 'AT+QNWPREFCFG="mode_pref",LTE:NR5G';
break;
case "NR5G-SA":
prefCmd = 'AT+QNWPREFCFG="mode_pref",NR5G';
break;
default:
console.error("Invalid network mode.");
return;
}
this.sendAtCommand(prefCmd);
},
setSimSlot() {
const simCmd = `AT+QUIMSLOT=${this.simSlot}`;
this.sendAtCommand(simCmd);
},
nr5GMode() {
let nrCmd;
switch (this.nrMode) {
case "Enable All":
nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",0';
break;
case "Disable NSA":
nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",2';
break;
case "Disable SA":
nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",1';
break;
default:
console.error("Invalid NR5G mode.");
return;
}
this.queryATCommand(nrCmd);
},
showLockedBands() {
let lockedCmd;
switch (this.lockedBands) {
case "LTE":
lockedCmd = 'AT+QNWPREFCFG="lte_band"';
break;
case "NSA":
lockedCmd = 'AT+QNWPREFCFG="nsa_nr5g_band"';
break;
case "SA":
lockedCmd = 'AT+QNWPREFCFG="nr5g_band"';
break;
default:
console.error("Invalid network mode.");
return;
}
this.queryATCommand(lockedCmd);
},
showCellState() {
let cellCmd;
switch (this.cellState) {
case "LTE":
cellCmd = 'AT+QNWLOCK="common/4g"';
break;
case "NR5G-SA":
cellCmd = 'AT+QNWLOCK="common/5g"';
break;
default:
console.error("Invalid network mode.");
return;
}
this.queryATCommand(cellCmd);
},
showSupportedBands() {
const supportedCmd = 'AT+QNWPREFCFG="policy_band"';
this.queryATCommand(supportedCmd);
},
showCurrentSim() {
const simCmd = "AT+QUIMSLOT?";
this.queryATCommand(simCmd);
},
showPrefNetwork() {
const prefCmd = 'AT+QNWPREFCFG="mode_pref"';
this.queryATCommand(prefCmd);
},
showCaInfo() {
const caCmd = "AT+QCAINFO";
this.queryATCommand(caCmd);
},
servingCellInfo() {
const servingCmd = 'AT+QENG="servingcell"';
this.queryATCommand(servingCmd);
},
scanNeighbourCells() {
const scanCmd = 'AT+QENG="neighbourcell"';
this.queryATCommand(scanCmd);
},
scanNsaCells() {
const enableCmd = 'AT+QNWCFG="nr5g_meas_info",1';
const queryScanCmd = 'AT+QNWCFG="nr5g_meas_info"';
// Send the enable command first without getting the response
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: enableCmd,
})
)
.then(() => {
console.log("Enable Success.");
// Show a temporary loading query message
this.queryCommandResponse =
"Enabling NSA cell scan. Please wait...";
this.queryATCommand(queryScanCmd);
})
.catch((error) => {
this.isError = true;
this.startCountdown();
console.error("Error sending AT command:", error);
});
},
fullNetworkScan() {
const scanCmd = "AT+QSCAN=3,1";
// Show a temporary loading query message
this.queryCommandResponse =
"Full network scan initiated. This takes about a minute. Please wait...";
this.queryATCommand(scanCmd);
},
queryATCommand(atcmd) {
this.isQuerying = true;
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: atcmd,
})
)
.then((res) => res.text())
.then((data) => {
this.queryCommandResponse = data;
console.log(data);
})
.catch((error) => {
this.isError = true;
this.startCountdown();
console.error("Error sending AT command:", error);
})
.finally(() => {
this.isQuerying = false;
});
},
sendAtCommand(atcmd) {
this.isLoading = true;
this.startCountdown();
console.log(atcmd);
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: atcmd,
})
)
.then((res) => res.text())
.then((data) => {
this.atCommandResponse = data;
console.log(data);
})
.catch((error) => {
this.isError = true;
this.startCountdown();
console.error("Error sending AT command:", error);
})
.finally(() => {
this.isLoading = false;
});
},
startCountdown() {
// Decrease countdown every second
const interval = setInterval(() => {
this.countdown--;
if (this.countdown <= 0) {
clearInterval(interval);
// Reset values
this.isLocking = false;
this.isError = false;
this.isLoading = false;
this.isQuerying = false;
this.countdown = 5;
}
}, 1000);
},
};
}
const freqNumbersContainer = document.getElementById(
"freqNumbersContainer"
);
function generateFreqNumberInputs(num) {
let html = "";
const maxFields = Math.min(num, 10); // Limit to a maximum of 10 fields
for (let i = 1; i <= maxFields; i++) {
html += `
<div style="margin-top: 1rem" x-show="cellNum >= ${i} && networkMode2 == 'LTE'">
<div style="display: flex; flex-direction: row">
<input class="input is-info" type="text" placeholder="EARFCN" x-model="earfcn${i}" />
<input class="input is-info" type="text" placeholder="PCI" x-model="pci${i}" style="margin-left: 1rem" />
</div>
</div>
`;
}
return html;
}
document
.getElementById("numFreqInput")
.addEventListener("input", function () {
const cellNum = parseInt(this.value);
freqNumbersContainer.innerHTML = generateFreqNumberInputs(cellNum);
});
</script>
</body>
</html>

View File

@@ -10,6 +10,7 @@
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css" />
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
@@ -35,7 +36,8 @@
>
<div class="navbar-start">
<a class="navbar-item" href="/"> Connection Info </a>
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
<a class="navbar-item" href="/atcommander.html"> Simple Settings </a>
<a class="navbar-item" href="/bandlock.html"> Simple Network </a>
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
<a class="navbar-item" href="/speedtest.html"> Speedtest </a>
</div>

View File

@@ -9,6 +9,7 @@
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css" />
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
@@ -36,7 +37,8 @@
>
<div class="navbar-start">
<a class="navbar-item" href="/"> Connection Info </a>
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
<a class="navbar-item" href="/atcommander.html"> Simple Settings </a>
<a class="navbar-item" href="/bandlock.html"> Simple Network </a>
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
<a class="navbar-item" href="/speedtest.html"> Speedtest </a>
</div>

View File

@@ -1,4 +1,11 @@
.modal-overlay {
/* Google Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
*{
font-family: 'Poppins', sans-serif;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;

View File

@@ -10,6 +10,7 @@
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css">
<link rel="stylesheet" type="text/css" href="/css/admin.css">
<link rel="stylesheet" href="styles.css" />
</head>
<body>
@@ -30,7 +31,8 @@
<div id="navMenu" class="navbar-menu" :class="isOpen ? 'is-active' : ''">
<div class="navbar-start">
<a class="navbar-item" href="/"> Connection Info </a>
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
<a class="navbar-item" href="/atcommander.html"> Simple Settings </a>
<a class="navbar-item" href="/bandlock.html"> Simple Network </a>
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
<a class="navbar-item" href="/speedtest.html"> Speedtest </a>
</div>

Binary file not shown.

Binary file not shown.

BIN
ttyd/ttyd

Binary file not shown.