Merge pull request #1 from iamromulan/development
Merge with Development
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
# Define toolkit paths
|
# Define toolkit paths
|
||||||
GITUSER="iamromulan"
|
GITUSER="iamromulan"
|
||||||
GITTREE="development"
|
GITTREE="development"
|
||||||
|
GITMAINTREE="main"
|
||||||
|
GITDEVTREE="development"
|
||||||
TMP_DIR="/tmp"
|
TMP_DIR="/tmp"
|
||||||
USRDATA_DIR="/usrdata"
|
USRDATA_DIR="/usrdata"
|
||||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||||
@@ -11,12 +13,6 @@ SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
|||||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
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_DIR="/usrdata/tailscale/"
|
||||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||||
# AT Command Script Variables and Functions
|
# AT Command Script Variables and Functions
|
||||||
@@ -103,118 +99,105 @@ send_at_commands() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if Simple Admin is installed
|
# Check for existing Entware/opkg installation, install if not installed
|
||||||
is_simple_admin_installed() {
|
ensure_entware_installed() {
|
||||||
[ -d "$SIMPLE_ADMIN_DIR" ] && return 0 || return 1
|
remount_rw
|
||||||
|
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"
|
||||||
|
if [ "$(readlink /bin/login)" != "/opt/bin/login" ]; then
|
||||||
|
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||||
|
if [ "$?" -ne 0 ]; then
|
||||||
|
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||||
|
rm /opt/etc/shadow
|
||||||
|
rm /opt/etc/passwd
|
||||||
|
cp /etc/shadow /opt/etc/
|
||||||
|
cp /etc/passwd /opt/etc
|
||||||
|
mkdir -p /usrdata/root/bin
|
||||||
|
touch /usrdata/root/.profile
|
||||||
|
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||||
|
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||||
|
chmod +x /usrdata/root/.profile
|
||||||
|
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||||
|
rm /bin/login /usr/bin/passwd
|
||||||
|
ln -sf /opt/bin/login /bin
|
||||||
|
ln -sf /opt/bin/passwd /usr/bin/
|
||||||
|
ln -sf /opt/bin/useradd /usr/bin/
|
||||||
|
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||||
|
/opt/bin/passwd
|
||||||
|
|
||||||
|
# Install basic and useful utilities
|
||||||
|
opkg install mc htop dfc lsof
|
||||||
|
ln -sf /opt/bin/mc /bin
|
||||||
|
ln -sf /opt/bin/htop /bin
|
||||||
|
ln -sf /opt/bin/dfc /bin
|
||||||
|
ln -sf /opt/bin/lsof /bin
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "/usrdata/root/.profile" ]; then
|
||||||
|
opkg update && opkg install shadow-useradd
|
||||||
|
mkdir -p /usrdata/root/bin
|
||||||
|
touch /usrdata/root/.profile
|
||||||
|
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||||
|
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||||
|
chmod +x /usrdata/root/.profile
|
||||||
|
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ ! -f "/opt/sbin/useradd" ]; then
|
||||||
|
echo "useradd does not exist. Installing shadow-useradd..."
|
||||||
|
opkg install shadow-useradd
|
||||||
|
else
|
||||||
|
echo "useradd already exists. Continuing..."
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to install/update AT Socat Bridge
|
#Uninstall Entware if the Users chooses
|
||||||
install_update_at_socat() {
|
uninstall_entware() {
|
||||||
remount_rw
|
echo -e '\033[31mInfo: Starting Entware/OPKG uninstallation...\033[0m'
|
||||||
|
|
||||||
|
# Stop services
|
||||||
|
systemctl stop rc.unslung.service
|
||||||
|
/opt/etc/init.d/rc.unslung stop
|
||||||
|
rm /lib/systemd/system/multi-user.target.wants/rc.unslung.service
|
||||||
|
rm /lib/systemd/system/rc.unslung.service
|
||||||
|
|
||||||
# Stop and disable existing services/files before installing new ones
|
systemctl stop opt.mount
|
||||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
rm /lib/systemd/system/multi-user.target.wants/start-opt-mount.service
|
||||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
rm /lib/systemd/system/opt.mount
|
||||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
rm /lib/systemd/system/start-opt-mount.service
|
||||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
|
||||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
|
||||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
|
||||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
|
||||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
|
||||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
|
||||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
|
||||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
|
||||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
|
||||||
systemctl daemon-reload > /dev/null 2>&1
|
|
||||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
|
||||||
|
|
||||||
# Install service units
|
|
||||||
echo -e "\033[0;32mInstalling AT Socat Bridge services...\033[0m"
|
|
||||||
mkdir $SOCAT_AT_DIR
|
|
||||||
cd $SOCAT_AT_DIR
|
|
||||||
mkdir $SOCAT_AT_SYSD_DIR
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/socat-armel-static
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/killsmd7bridge
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/atcmd
|
|
||||||
cd $SOCAT_AT_SYSD_DIR
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11.service
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11-from-ttyIN.service
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11-to-ttyIN.service
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-killsmd7bridge.service
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7-from-ttyIN2.service
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7-to-ttyIN2.service
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7.service
|
|
||||||
|
|
||||||
# Set execute permissions
|
# Unmount /opt if mounted
|
||||||
cd $SOCAT_AT_DIR
|
mountpoint -q /opt && umount /opt
|
||||||
chmod +x socat-armel-static
|
|
||||||
chmod +x killsmd7bridge
|
# Remove Entware installation directory
|
||||||
chmod +x atcmd
|
rm -rf /usrdata/opt
|
||||||
|
rm -rf /opt
|
||||||
# Link new command for AT Commands from the shell
|
|
||||||
ln -sf $SOCAT_AT_DIR/atcmd /bin
|
# Reload systemctl daemon
|
||||||
|
|
||||||
# Install service units
|
|
||||||
echo -e "\033[0;32mAdding AT Socat Bridge systemd service units...\033[0m"
|
|
||||||
cp -rf $SOCAT_AT_SYSD_DIR/*.service /lib/systemd/system
|
|
||||||
ln -sf /lib/systemd/system/socat-killsmd7bridge.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
ln -sf /lib/systemd/system/socat-smd11.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
ln -sf /lib/systemd/system/socat-smd11-to-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
ln -sf /lib/systemd/system/socat-smd11-from-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
ln -sf /lib/systemd/system/socat-smd7.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
ln -sf /lib/systemd/system/socat-smd7-to-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
ln -sf /lib/systemd/system/socat-smd7-from-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl start socat-smd11
|
|
||||||
sleep 2s
|
# Optionally, clean up any modifications to /etc/profile or other system files
|
||||||
systemctl start socat-smd11-to-ttyIN
|
# Restore original link to login binary compiled by Quectel
|
||||||
systemctl start socat-smd11-from-ttyIN
|
rm /bin/login
|
||||||
echo -e "\033[0;32mAT Socat Bridge service online: smd11 to ttyOUT\033[0m"
|
ln /bin/login.shadow /bin/login
|
||||||
systemctl start socat-killsmd7bridge
|
|
||||||
sleep 1s
|
echo -e '\033[32mInfo: Entware/OPKG has been uninstalled successfully.\033[0m'
|
||||||
systemctl start socat-smd7
|
|
||||||
sleep 2s
|
|
||||||
systemctl start socat-smd7-to-ttyIN2
|
|
||||||
systemctl start socat-smd7-from-ttyIN2
|
|
||||||
echo -e "\033[0;32mAT Socat Bridge service online: smd7 to ttyOUT2\033[0m"
|
|
||||||
remount_ro
|
|
||||||
cd /
|
|
||||||
echo -e "\033[0;32mAT Socat Bridge services Installed!\033[0m"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to install Simple Firewall
|
|
||||||
install_simple_firewall() {
|
|
||||||
systemctl stop simplefirewall
|
|
||||||
systemctl stop ttl-override
|
|
||||||
echo -e "\033[0;32mInstalling/Updating Simple Firewall...\033[0m"
|
|
||||||
mount -o remount,rw /
|
|
||||||
mkdir -p "$SIMPLE_FIREWALL_DIR"
|
|
||||||
mkdir -p "$SIMPLE_FIREWALL_SYSTEMD_DIR"
|
|
||||||
wget -O "$SIMPLE_FIREWALL_DIR/simplefirewall.sh" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/simplefirewall.sh
|
|
||||||
wget -O "$SIMPLE_FIREWALL_DIR/ttl-override" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttl-override
|
|
||||||
wget -O "$SIMPLE_FIREWALL_DIR/ttlvalue" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttlvalue
|
|
||||||
chmod +x "$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
|
||||||
chmod +x "$SIMPLE_FIREWALL_DIR/ttl-override"
|
|
||||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/simplefirewall.service
|
|
||||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/ttl-override.service" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/ttl-override.service
|
|
||||||
cp -rf $SIMPLE_FIREWALL_SYSTEMD_DIR/* /lib/systemd/system
|
|
||||||
ln -sf "/lib/systemd/system/simplefirewall.service" "/lib/systemd/system/multi-user.target.wants/"
|
|
||||||
ln -sf "/lib/systemd/system/ttl-override.service" "/lib/systemd/system/multi-user.target.wants/"
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl start simplefirewall
|
|
||||||
systemctl start ttl-override
|
|
||||||
remount_ro
|
|
||||||
echo -e "\033[0;32mSimple Firewall installation/update complete.\033[0m"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# function to configure the fetures of simplefirewall
|
||||||
configure_simple_firewall() {
|
configure_simple_firewall() {
|
||||||
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
||||||
echo -e "\033[0;31mSimplefirewall is not installed, would you like to install it?\033[0m"
|
echo -e "\033[0;31mSimplefirewall is not installed, would you like to install it?\033[0m"
|
||||||
@@ -306,101 +289,65 @@ configure_simple_firewall() {
|
|||||||
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_simpleadmin_passwd(){
|
||||||
|
ensure_entware_installed
|
||||||
|
opkg update
|
||||||
|
opkg install libaprutil
|
||||||
|
wget -O /usrdata/root/bin/htpasswd https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/htpasswd && chmod +x /usrdata/root/bin/htpasswd
|
||||||
|
wget -O /usrdata/root/bin/simplepasswd https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/simplepasswd && chmod +x /usrdata/root/bin/simplepasswd
|
||||||
|
echo -e "\e[1;32mTo change your simpleadmin (admin) password in the future...\e[0m"
|
||||||
|
echo -e "\e[1;32mIn the console type simplepasswd and press enter\e[0m"
|
||||||
|
/usrdata/root/bin/simplepasswd
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
set_root_passwd() {
|
||||||
|
echo -e "\e[1;31mPlease set the root/console password.\e[0m"
|
||||||
|
/opt/bin/passwd
|
||||||
|
}
|
||||||
|
|
||||||
# Function to install/update Simple Admin
|
# Function to install/update Simple Admin
|
||||||
install_simple_admin() {
|
install_simple_admin() {
|
||||||
while true; do
|
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;32mWhat version of Simple Admin do you want to install? This will start a webserver on port 80/443 on test build\e[0m"
|
||||||
echo -e "\e[1;32m1) Full Install\e[0m"
|
echo -e "\e[1;32m1) Stable current version, (Main Branch)\e[0m"
|
||||||
echo -e "\e[1;34m2) No AT Commands, List only\e[0m"
|
echo -e "\e[1;31m2) Install Test Build (Development Branch)\e[0m"
|
||||||
echo -e "\e[1;33m3) TTL Only\e[0m"
|
echo -e "\e[0;33m3) Return to Main Menu\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;32mSelect your choice: \e[0m"
|
echo -e "\e[1;32mSelect your choice: \e[0m"
|
||||||
read choice
|
read choice
|
||||||
|
|
||||||
case $choice in
|
case $choice in
|
||||||
1)
|
1)
|
||||||
install_update_at_socat
|
echo -e "\e[1;32mYou are using the development toolkit; Use the one from main if you want the stable version right now\e[0m"
|
||||||
install_simple_firewall
|
break
|
||||||
remount_rw
|
;;
|
||||||
cd $TMP_DIR
|
2)
|
||||||
wget $GITHUB_SIMPADMIN_FULL_URL -O simpleadminfull.zip
|
ensure_entware_installed
|
||||||
unzip -o simpleadminfull.zip
|
echo -e "\e[1;31m2) Installing simpleadmin from the development test branch\e[0m"
|
||||||
cp -Rf quectel-rgmii-toolkit-simpleadminfull/simpleadmin/ $USRDATA_DIR
|
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||||
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
|
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||||
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
wget -O /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_socat-at-bridge.sh && chmod +x /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||||
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
echo -e "\e[1;32mInstalling/updating dependency: socat-at-bridge\e[0m"
|
||||||
systemctl daemon-reload
|
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||||
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
|
/usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||||
ln -sf /lib/systemd/system/simpleadmin_generate_status.service /lib/systemd/system/multi-user.target.wants/
|
echo -e "\e[1;32m Dependency: socat-at-bridge has been updated/installed.\e[0m"
|
||||||
systemctl start simpleadmin_generate_status
|
sleep 1
|
||||||
systemctl start simpleadmin_httpd
|
wget -O /usrdata/simpleupdates/scripts/update_simplefirewall.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_simplefirewall.sh && chmod +x /usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||||
remount_ro
|
echo -e "\e[1;32mInstalling/updating dependency: simplefirewall\e[0m"
|
||||||
echo "Cleaning up..."
|
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||||
rm /tmp/simpleadminfull.zip
|
/usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||||
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminfull/
|
echo -e "\e[1;32m Dependency: simplefirewall has been updated/installed.\e[0m"
|
||||||
break
|
sleep 1
|
||||||
;;
|
set_simpleadmin_passwd
|
||||||
2)
|
wget -O /usrdata/simpleupdates/scripts/update_simpleadmin.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_simpleadmin.sh && chmod +x /usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||||
install_update_at_socat
|
echo -e "\e[1;32mInstalling/updating: Simpleadmin content\e[0m"
|
||||||
install_simple_firewall
|
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||||
remount_rw
|
/usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||||
cd $TMP_DIR
|
echo -e "\e[1;32mSimpleadmin content has been updated/installed.\e[0m"
|
||||||
wget $GITHUB_SIMPADMIN_NOCMD_URL -O simpleadminnoatcmds.zip
|
sleep 1
|
||||||
unzip -o simpleadminnoatcmds.zip
|
break
|
||||||
cp -Rf quectel-rgmii-toolkit-simpleadminnoatcmds/simpleadmin/ $USRDATA_DIR
|
;;
|
||||||
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
|
3)
|
||||||
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
|
|
||||||
echo "Cleaning up..."
|
|
||||||
rm /tmp/simpleadminnoatcmds.zip
|
|
||||||
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminnoatcmds/
|
|
||||||
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)
|
|
||||||
echo "Returning to main menu..."
|
echo "Returning to main menu..."
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
@@ -415,7 +362,6 @@ install_simple_admin() {
|
|||||||
uninstall_simpleadmin_components() {
|
uninstall_simpleadmin_components() {
|
||||||
echo -e "\e[1;32mStarting the uninstallation process for Simpleadmin components.\e[0m"
|
echo -e "\e[1;32mStarting the uninstallation process for Simpleadmin components.\e[0m"
|
||||||
echo -e "\e[1;32mNote: Uninstalling certain components may affect the functionality of others.\e[0m"
|
echo -e "\e[1;32mNote: Uninstalling certain components may affect the functionality of others.\e[0m"
|
||||||
echo -e "\e[1;36mIf you are upgrading from an older version of the toolkit uninstall/say yes to all everything.\e[0m"
|
|
||||||
remount_rw
|
remount_rw
|
||||||
|
|
||||||
# Uninstall Simple Firewall
|
# Uninstall Simple Firewall
|
||||||
@@ -443,49 +389,67 @@ uninstall_simpleadmin_components() {
|
|||||||
read -p "Enter your choice (1 or 2): " choice_socat_at_bridge
|
read -p "Enter your choice (1 or 2): " choice_socat_at_bridge
|
||||||
if [ "$choice_socat_at_bridge" -eq 1 ]; then
|
if [ "$choice_socat_at_bridge" -eq 1 ]; then
|
||||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||||
systemctl daemon-reload > /dev/null 2>&1
|
systemctl daemon-reload > /dev/null 2>&1
|
||||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||||
rm -rf "/usrdata/micropython" > /dev/null 2>&1
|
rm -rf "/usrdata/micropython" > /dev/null 2>&1
|
||||||
rm -rf "/usrdata/at-telnet" > /dev/null 2>&1
|
rm -rf "/usrdata/at-telnet" > /dev/null 2>&1
|
||||||
echo -e "\033[0;32mAT Socat Bridge services removed!...\033[0m"
|
echo -e "\033[0;32mAT Socat Bridge services removed!...\033[0m"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Uninstall the rest of Simpleadmin
|
# Uninstall ttyd
|
||||||
echo -e "\e[1;32mDo you want to uninstall the rest of Simpleadmin?\e[0m"
|
echo -e "\e[1;32mDo you want to uninstall ttyd (simpleadmin console)?\e[0m"
|
||||||
|
echo -e "\e[1;31mWarning: Do not uninstall if you are currently using ttyd to do this!!!\e[0m"
|
||||||
echo -e "\e[1;32m1) Yes\e[0m"
|
echo -e "\e[1;32m1) Yes\e[0m"
|
||||||
echo -e "\e[1;31m2) No\e[0m"
|
echo -e "\e[1;31m2) No\e[0m"
|
||||||
read -p "Enter your choice (1 or 2): " choice_simpleadmin
|
read -p "Enter your choice (1 or 2): " choice_simpleadmin
|
||||||
if [ "$choice_simpleadmin" -eq 1 ]; then
|
if [ "$choice_simpleadmin" -eq 1 ]; then
|
||||||
echo "Uninstalling the rest of Simpleadmin..."
|
echo -e "\e[1;34mUninstalling ttyd...\e[0m"
|
||||||
systemctl stop simpleadmin_httpd
|
systemctl stop ttyd
|
||||||
systemctl stop simpleadmin_generate_status
|
rm -rf /usrdata/ttyd
|
||||||
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
rm /lib/systemd/system/ttyd.service
|
||||||
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
rm /lib/systemd/system/multi-user.target.wants/ttyd.service
|
||||||
systemctl daemon-reload
|
rm /bin/ttyd
|
||||||
rm -rf "$SIMPLE_ADMIN_DIR"
|
echo -e "\e[1;32mttyd has been uninstalled.\e[0m"
|
||||||
echo "The rest of Simpleadmin uninstalled."
|
fi
|
||||||
|
|
||||||
|
echo "Uninstalling the rest of Simpleadmin..."
|
||||||
|
|
||||||
|
# Check if Lighttpd service is installed and remove it if present
|
||||||
|
if [ -f "/lib/systemd/system/lighttpd.service" ]; then
|
||||||
|
echo "Lighttpd detected, uninstalling Lighttpd and its modules..."
|
||||||
|
systemctl stop lighttpd
|
||||||
|
opkg --force-remove --force-removal-of-dependent-packages remove lighttpd-mod-authn_file lighttpd-mod-auth lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy lighttpd
|
||||||
|
rm -rf $LIGHTTPD_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
systemctl stop simpleadmin_generate_status
|
||||||
|
systemctl stop simpleadmin_httpd
|
||||||
|
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||||
|
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||||
|
echo "The rest of Simpleadmin and Lighttpd (if present) uninstalled."
|
||||||
remount_ro
|
remount_ro
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Uninstallation process completed."
|
echo "Uninstallation process completed."
|
||||||
}
|
}
|
||||||
@@ -494,13 +458,13 @@ uninstall_simpleadmin_components() {
|
|||||||
tailscale_menu() {
|
tailscale_menu() {
|
||||||
while true; do
|
while true; do
|
||||||
echo -e "\e[1;32mTailscale Menu\e[0m"
|
echo -e "\e[1;32mTailscale Menu\e[0m"
|
||||||
echo -e "\e[1;32m1) Install/Update/Remove Tailscale\e[0m"
|
echo -e "\e[1;32m1) Install/Update Tailscale\e[0m"
|
||||||
echo -e "\e[1;36m2) Configure Tailscale\e[0m"
|
echo -e "\e[1;36m2) Configure Tailscale\e[0m"
|
||||||
echo -e "\e[1;31m3) Return to Main Menu\e[0m"
|
echo -e "\e[1;31m3) Return to Main Menu\e[0m"
|
||||||
read -p "Enter your choice: " tailscale_choice
|
read -p "Enter your choice: " tailscale_choice
|
||||||
|
|
||||||
case $tailscale_choice in
|
case $tailscale_choice in
|
||||||
1) install_update_remove_tailscale;;
|
1) install_update_tailscale;;
|
||||||
2) configure_tailscale;;
|
2) configure_tailscale;;
|
||||||
3) break;;
|
3) break;;
|
||||||
*) echo "Invalid option";;
|
*) echo "Invalid option";;
|
||||||
@@ -509,62 +473,16 @@ tailscale_menu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Function to install, update, or remove Tailscale
|
# Function to install, update, or remove Tailscale
|
||||||
install_update_remove_tailscale() {
|
install_update_tailscale() {
|
||||||
if [ -d "$TAILSCALE_DIR" ]; then
|
echo -e "\e[1;31m2) Installing tailscale from the $GITTREE branch\e[0m"
|
||||||
echo "Tailscale is already installed."
|
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||||
echo "1) Update Tailscale"
|
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||||
echo "2) Remove Tailscale"
|
wget -O /usrdata/simpleupdates/scripts/update_tailscale.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_tailscale.sh && chmod +x /usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||||
read -p "Enter your choice: " tailscale_update_remove_choice
|
echo -e "\e[1;32mInstalling/updating: Tailscale\e[0m"
|
||||||
|
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||||
case $tailscale_update_remove_choice in
|
remount_rw
|
||||||
1)
|
/usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||||
echo "Updating Tailscale..."
|
echo -e "\e[1;32m Tailscale has been updated/installed.\e[0m"
|
||||||
/usrdata/tailscale/tailscale update
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
echo "Removing Tailscale..."
|
|
||||||
remount_rw
|
|
||||||
$TAILSCALE_DIR/tailscale down
|
|
||||||
$TAILSCALE_DIR/tailscale logout
|
|
||||||
systemctl stop tailscaled
|
|
||||||
rm -f /lib/systemd/system/tailscaled.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
rm -rf $TAILSCALE_DIR
|
|
||||||
remount_ro
|
|
||||||
echo "Tailscale removed successfully."
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid option";;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo "Installing Tailscale..."
|
|
||||||
remount_rw
|
|
||||||
echo "Creating /usrdata/tailscale/"
|
|
||||||
mkdir $TAILSCALE_DIR
|
|
||||||
mkdir $TAILSCALE_SYSD_DIR
|
|
||||||
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
|
|
||||||
echo "Downloading systemd files..."
|
|
||||||
cd $TAILSCALE_SYSD_DIR
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.service
|
|
||||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.defaults
|
|
||||||
sleep 2s
|
|
||||||
echo "Setting Permissions..."
|
|
||||||
chmod +x /usrdata/tailscale/tailscaled
|
|
||||||
chmod +x /usrdata/tailscale/tailscale
|
|
||||||
echo "Copy systemd units..."
|
|
||||||
cp -rf /usrdata/tailscale/systemd/* /lib/systemd/system
|
|
||||||
ln -sf /lib/systemd/system/tailscaled.service /lib/systemd/system/multi-user.target.wants/
|
|
||||||
systemctl daemon-reload
|
|
||||||
echo "Starting Tailscaled..."
|
|
||||||
systemctl start tailscaled
|
|
||||||
cd /
|
|
||||||
remount_ro
|
|
||||||
echo "Tailscale installed successfully."
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to Configure Tailscale
|
# Function to Configure Tailscale
|
||||||
@@ -795,57 +713,43 @@ WantedBy=multi-user.target" > "$cfun_service_path"
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function for TTYd install
|
|
||||||
install_ttyd() {
|
|
||||||
echo -e "\e[1;34mStarting ttyd installation process...\e[0m"
|
|
||||||
|
|
||||||
if [ ! -f "/opt/bin/opkg" ]; then
|
install_sshd() {
|
||||||
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
|
if [ -d "/usrdata/sshd" ]; then
|
||||||
cd /tmp && wget -O installentware.sh "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/installentware.sh" && chmod +x installentware.sh && ./installentware.sh
|
echo -e "\e[1;31mSSHD is currently installed.\e[0m"
|
||||||
if [ "$?" -ne 0 ]; then
|
echo -e "Do you want to update or uninstall?"
|
||||||
echo -e "\e[1;31mEntware/OPKG installation failed. Please check your internet connection or the repository URL.\e[0m"
|
echo -e "1.) Update"
|
||||||
exit 1
|
echo -e "2.) Uninstall"
|
||||||
fi
|
read -p "Select an option (1 or 2): " sshd_choice
|
||||||
cd /
|
|
||||||
else
|
case $sshd_choice in
|
||||||
echo -e "\e[1;32mEntware/OPKG is already installed.\e[0m"
|
1)
|
||||||
|
echo -e "\e[1;31m2) Installing sshd from the $GITTREE branch\e[0m"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
echo -e "\e[1;31mUninstalling SSHD...\e[0m"
|
||||||
|
systemctl stop sshd
|
||||||
|
rm /lib/systemd/system/sshd.service
|
||||||
|
opkg remove openssh-server-pam
|
||||||
|
echo -e "\e[1;32mSSHD has been uninstalled successfully.\e[0m"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "\e[1;31mInvalid option. Please select 1 or 2.\e[0m"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mount -o remount,rw /
|
# Proceed with installation or updating if not uninstalling
|
||||||
opkg update && opkg install shadow-login shadow-passwd
|
ensure_entware_installed
|
||||||
if [ "$?" -ne 0 ]; then
|
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||||
exit 1
|
wget -O /usrdata/simpleupdates/scripts/update_sshd.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleupdates/scripts/update_sshd.sh && chmod +x /usrdata/simpleupdates/scripts/update_sshd.sh
|
||||||
fi
|
echo -e "\e[1;32mInstalling/updating: SSHd\e[0m"
|
||||||
|
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||||
# Replacing the login and passwd binaries
|
/usrdata/simpleupdates/scripts/update_sshd.sh
|
||||||
rm /opt/etc/shadow
|
echo -e "\e[1;32m SSHd has been updated/installed.\e[0m"
|
||||||
cp /etc/shadow /opt/etc/
|
|
||||||
rm /bin/login /usr/bin/passwd
|
|
||||||
ln -sf /opt/bin/login /bin
|
|
||||||
ln -sf /opt/bin/passwd /usr/bin/
|
|
||||||
echo -e "\e[1;31mPlease set your system login password.\e[0m"
|
|
||||||
/usr/bin/passwd
|
|
||||||
|
|
||||||
# Setting up ttyd
|
|
||||||
mkdir -p /usrdata/ttyd/scripts /usrdata/ttyd/systemd
|
|
||||||
cd /usrdata/ttyd/
|
|
||||||
wget -O ttyd "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/ttyd/ttyd" && chmod +x ttyd
|
|
||||||
wget -O scripts/ttyd.bash "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/ttyd/scripts/ttyd.bash" && chmod +x scripts/ttyd.bash
|
|
||||||
wget -O systemd/ttyd.service "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/ttyd/systemd/ttyd.service"
|
|
||||||
cp systemd/ttyd.service /lib/systemd/system/
|
|
||||||
ln -sf /lib/systemd/system/ttyd.service /etc/systemd/system/multi-user.target.wants/
|
|
||||||
|
|
||||||
# Enabling and starting ttyd service
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl enable ttyd
|
|
||||||
systemctl start ttyd
|
|
||||||
if [ "$?" -ne 0 ]; then
|
|
||||||
echo -e "\e[1;31mFailed to start ttyd service. Please check the systemd service file and ttyd binary.\e[0m"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\e[1;32mInstall Complete! ttyd server is up on port 443. Note: No TLS/SSL enabled yet.\e[0m"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -918,14 +822,19 @@ echo " :+##+. "
|
|||||||
echo "Select an option:"
|
echo "Select an option:"
|
||||||
echo -e "\e[0m"
|
echo -e "\e[0m"
|
||||||
echo -e "\e[96m1) Send AT Commands\e[0m" # Cyan
|
echo -e "\e[96m1) Send AT Commands\e[0m" # Cyan
|
||||||
echo -e "\e[93m2) Install/Update/Uninstall Simple Admin\e[0m" # Yellow
|
echo -e "\e[93m2) Install Simple Admin\e[0m" # Yellow
|
||||||
echo -e "\e[95m3) Simple Firewall Management\e[0m" # Light Purple
|
echo -e "\e[95m3) Set Simpleadmin (admin) password\e[0m" # Light Purple
|
||||||
echo -e "\e[94m4) Tailscale Management\e[0m" # Light Blue
|
echo -e "\e[94m4) Set Console/ttyd (root) password\e[0m" # Light Blue
|
||||||
echo -e "\e[92m5) Install/Change or remove Daily Reboot Timer\e[0m" # Light Green
|
echo -e "\e[91m5) Uninstall Simple Admin\e[0m" # Light Red
|
||||||
echo -e "\e[91m6) Install/Uninstall CFUN 0 Fix\e[0m" # Light Red
|
echo -e "\e[95m6) Simple Firewall Management\e[0m" # Light Purple
|
||||||
echo -e "\e[96m7) Install Entware/OPKG (BETA/Advanced)\e[0m" # Cyan (repeated color for additional options)
|
echo -e "\e[94m7) Tailscale Management\e[0m" # Light Blue
|
||||||
echo -e "\e[96m8) Install TTYd (BETA,443,No TLS/SSL)\e[0m" # Cyan
|
echo -e "\e[92m8) Install/Change or remove Daily Reboot Timer\e[0m" # Light Green
|
||||||
echo -e "\e[93m9) Exit\e[0m" # Yellow (repeated color for exit option)
|
echo -e "\e[96m9) Install/Uninstall CFUN 0 Fix\e[0m" # Cyan (repeated color for additional options)
|
||||||
|
echo -e "\e[91m10) Uninstall Entware/OPKG\e[0m" # Light Red
|
||||||
|
echo -e "\e[92m11) Install Speedtest.net CLI app (speedtest command)\e[0m" # Light Green
|
||||||
|
echo -e "\e[92m12) Install Fast.com CLI app (fast command)(tops out at 40Mbps)\e[0m" # Light Green
|
||||||
|
echo -e "\e[92m13) Install OpenSSH Server\e[0m" # Light Green
|
||||||
|
echo -e "\e[93m14) Exit\e[0m" # Yellow (repeated color for exit option)
|
||||||
read -p "Enter your choice: " choice
|
read -p "Enter your choice: " choice
|
||||||
|
|
||||||
case $choice in
|
case $choice in
|
||||||
@@ -933,48 +842,97 @@ echo " :+##+. "
|
|||||||
send_at_commands
|
send_at_commands
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
if is_simple_admin_installed; then
|
install_simple_admin
|
||||||
echo -e "\e[1;31mSimple Admin is already installed. It must be removed first\e[0m"
|
|
||||||
echo -e "\e[1;32m1) Remove\e[0m" # Green
|
|
||||||
echo -e "\e[0;33m2) Return to main menu\e[0m"
|
|
||||||
read -p "Enter your choice: " simple_admin_choice
|
|
||||||
case $simple_admin_choice in
|
|
||||||
1) uninstall_simpleadmin_components;;
|
|
||||||
2) break;;
|
|
||||||
*) echo -e "\e[1;31mInvalid option\e[0m";;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo -e "\e[1;32mInstalling Simple Admin...\e[0m"
|
|
||||||
install_simple_admin
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
3)
|
3) set_simpleadmin_passwd
|
||||||
configure_simple_firewall
|
;;
|
||||||
|
4)
|
||||||
|
set_root_passwd
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
uninstall_simpleadmin_components
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
configure_simple_firewall
|
||||||
;;
|
;;
|
||||||
|
|
||||||
4)
|
7)
|
||||||
tailscale_menu
|
tailscale_menu
|
||||||
;;
|
;;
|
||||||
5)
|
8)
|
||||||
manage_reboot_timer
|
manage_reboot_timer
|
||||||
;;
|
;;
|
||||||
6)
|
9)
|
||||||
manage_cfun_fix
|
manage_cfun_fix
|
||||||
;;
|
;;
|
||||||
7)
|
10)
|
||||||
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
|
echo -e "\033[31mAre you sure you want to uninstall entware?\033[0m"
|
||||||
cd /tmp && wget -O installentware.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/installentware.sh && chmod +x installentware.sh && ./installentware.sh
|
echo -e "\033[31m1) Yes\033[0m"
|
||||||
|
echo -e "\033[31m2) No\033[0m"
|
||||||
|
read -p "Select an option (1 or 2): " user_choice
|
||||||
|
|
||||||
|
case $user_choice in
|
||||||
|
1)
|
||||||
|
# If yes, uninstall existing entware
|
||||||
|
echo -e "\033[31mUninstalling existing entware...\033[0m"
|
||||||
|
uninstall_entware # Assuming uninstall_entware is a defined function or command
|
||||||
|
echo -e "\033[31mEntware has been uninstalled.\033[0m"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
# If no, exit the script
|
||||||
|
echo -e "\033[31mUninstallation cancelled.\033[0m"
|
||||||
|
exit # Use 'exit' to terminate the script outside a loop
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Handle invalid input
|
||||||
|
echo -e "\033[31mInvalid option. Please select 1 or 2.\033[0m"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
|
||||||
|
11)
|
||||||
|
ensure_entware_installed
|
||||||
|
echo -e "\e[1;32mInstalling Speedtest.net CLI (speedtest command)\e[0m"
|
||||||
|
remount_rw
|
||||||
|
mkdir /usrdata/root
|
||||||
|
mkdir /usrdata/root/bin
|
||||||
|
cd /usrdata/root/bin
|
||||||
|
wget https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||||
|
tar -xzf ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||||
|
rm ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||||
|
rm speedtest.md
|
||||||
cd /
|
cd /
|
||||||
|
ln -sf /usrdata/root/bin/speedtest /bin
|
||||||
|
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"
|
||||||
;;
|
;;
|
||||||
8)
|
12)
|
||||||
install_ttyd
|
echo -e "\e[1;32mInstalling fast.com CLI (fast command)\e[0m"
|
||||||
;;
|
remount_rw
|
||||||
9)
|
mkdir /usrdata/root
|
||||||
echo -e "\e[1;32mGoodbye!\e[0m"
|
mkdir /usrdata/root/bin
|
||||||
|
cd /usrdata/root/bin
|
||||||
|
wget -O fast https://github.com/ddo/fast/releases/download/v0.0.4/fast_linux_arm && chmod +x fast
|
||||||
|
cd /
|
||||||
|
ln -sf /usrdata/root/bin/fast /bin
|
||||||
|
remount_ro
|
||||||
|
echo -e "\e[1;32mFast.com CLI (speedtest command) installed!!\e[0m"
|
||||||
|
echo -e "\e[1;32mTry running the command 'fast'\e[0m"
|
||||||
|
echo -e "\e[1;32mThe fast.com test tops out at 40Mbps on the modem\e[0m"
|
||||||
|
;;
|
||||||
|
13)
|
||||||
|
install_sshd
|
||||||
|
;;
|
||||||
|
14)
|
||||||
|
echo -e "\e[1;32mGoodbye!\e[0m"
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo -e "\e[1;31mInvalid option\e[0m"
|
echo -e "\e[1;31mInvalid option\e[0m"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Modified by iamromulan to set up a proper entware environment for Quectel RM5xx series m.2 modems
|
||||||
TYPE='generic'
|
TYPE='generic'
|
||||||
#|---------|-----------------|
|
#|---------|-----------------|
|
||||||
|
#| TARGET | Quectel Modem |
|
||||||
#| ARCH | armv7sf-k3.2 |
|
#| ARCH | armv7sf-k3.2 |
|
||||||
#| LOADER | ld-linux.so.3 |
|
#| LOADER | ld-linux.so.3 |
|
||||||
#| GLIBC | 2.27 |
|
#| GLIBC | 2.27 |
|
||||||
@@ -16,64 +17,6 @@ PRE_OPKG_PATH=$(which opkg)
|
|||||||
# Remount filesystem as read-write
|
# Remount filesystem as read-write
|
||||||
mount -o remount,rw /
|
mount -o remount,rw /
|
||||||
|
|
||||||
uninstall_entware() {
|
|
||||||
echo -e '\033[31mInfo: Starting Entware/OPKG uninstallation...\033[0m'
|
|
||||||
|
|
||||||
# Stop services
|
|
||||||
systemctl stop rc.unslung.service
|
|
||||||
/opt/etc/init.d/rc.unslung stop
|
|
||||||
rm /lib/systemd/system/multi-user.target.wants/rc.unslung.service
|
|
||||||
rm /lib/systemd/system/rc.unslung.service
|
|
||||||
|
|
||||||
systemctl stop opt.mount
|
|
||||||
rm /lib/systemd/system/multi-user.target.wants/start-opt-mount.service
|
|
||||||
rm /lib/systemd/system/opt.mount
|
|
||||||
rm /lib/systemd/system/start-opt-mount.service
|
|
||||||
|
|
||||||
# Unmount /opt if mounted
|
|
||||||
mountpoint -q /opt && umount /opt
|
|
||||||
|
|
||||||
# Remove Entware installation directory
|
|
||||||
rm -rf /usrdata/opt
|
|
||||||
rm -rf /opt
|
|
||||||
|
|
||||||
# Reload systemctl daemon
|
|
||||||
systemctl daemon-reload
|
|
||||||
|
|
||||||
# Optionally, clean up any modifications to /etc/profile or other system files
|
|
||||||
# This step depends on the specific changes made by the user or the installation script
|
|
||||||
|
|
||||||
echo -e '\033[32mInfo: Entware/OPKG has been uninstalled successfully.\033[0m'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if /opt exists
|
|
||||||
if [ -d /opt ]; then
|
|
||||||
echo -e "\033[32mDo you want to uninstall Entware/OPKG first? It is already installed.\033[0m"
|
|
||||||
echo -e "\033[32m1) Yes\033[0m"
|
|
||||||
echo -e "\033[32m2) No\033[0m"
|
|
||||||
echo -e "\033[32m3) Cancel\033[0m"
|
|
||||||
read -p "Select an option: " choice
|
|
||||||
|
|
||||||
case $choice in
|
|
||||||
1)
|
|
||||||
# Call the uninstall function
|
|
||||||
uninstall_entware
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
# Continue with the script
|
|
||||||
echo "Continuing with the script..."
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
echo "Canceling. Exiting script."
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid option. Please select 1, 2, or 3."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
create_opt_mount() {
|
create_opt_mount() {
|
||||||
# Bind /usrdata/opt to /opt
|
# Bind /usrdata/opt to /opt
|
||||||
echo -e '\033[32mInfo: Setting up /opt mount to /usrdata/opt...\033[0m'
|
echo -e '\033[32mInfo: Setting up /opt mount to /usrdata/opt...\033[0m'
|
||||||
@@ -114,32 +57,13 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
if [ -n "$PRE_OPKG_PATH" ]; then
|
if [ -n "$PRE_OPKG_PATH" ]; then
|
||||||
while true; do
|
# Automatically rename the existing opkg binary
|
||||||
echo -e "\033[32mopkg already exists at: $PRE_OPKG_PATH\033[0m"
|
mv "$PRE_OPKG_PATH" "${PRE_OPKG_PATH}_old"
|
||||||
echo -e "\033[32mDo you want to rename it to opkg_old?\033[0m"
|
echo -e "\033[32mFactory/Already existing opkg has been renamed to opkg_old.\033[0m"
|
||||||
echo -e "\033[32m1) Yes (Highly Recommended)\033[0m"
|
|
||||||
echo -e "\033[32m2) No (The opkg command may not work)\033[0m"
|
|
||||||
read -p "Select an option (1 or 2): " user_choice
|
|
||||||
|
|
||||||
|
|
||||||
case $user_choice in
|
|
||||||
1)
|
|
||||||
mv "$PRE_OPKG_PATH" "${PRE_OPKG_PATH}_old"
|
|
||||||
echo "Factory/Already existing opkg has been renamed to opkg_old."
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
echo "Proceeding without renaming opkg."
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid option. Please select 1 or 2."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
else
|
else
|
||||||
echo "Info: no existing opkg binary detected, proceeding with installation"
|
echo "Info: no existing opkg binary detected, proceeding with installation"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e '\033[32mInfo: Creating /opt mount pointed to /usrdata/opt ...\033[0m'
|
echo -e '\033[32mInfo: Creating /opt mount pointed to /usrdata/opt ...\033[0m'
|
||||||
create_opt_mount
|
create_opt_mount
|
||||||
echo -e '\033[32mInfo: Proceeding with main installation ...\033[0m'
|
echo -e '\033[32mInfo: Proceeding with main installation ...\033[0m'
|
||||||
@@ -206,9 +130,38 @@ systemctl start rc.unslung.service
|
|||||||
echo -e '\033[32mInfo: Congratulations!\033[0m'
|
echo -e '\033[32mInfo: Congratulations!\033[0m'
|
||||||
echo -e '\033[32mInfo: If there are no errors above then Entware was successfully initialized.\033[0m'
|
echo -e '\033[32mInfo: If there are no errors above then Entware was successfully initialized.\033[0m'
|
||||||
echo -e '\033[32mInfo: Add /opt/bin & /opt/sbin to $PATH variable\033[0m'
|
echo -e '\033[32mInfo: Add /opt/bin & /opt/sbin to $PATH variable\033[0m'
|
||||||
echo -e '\033[32mInfo: Run export PATH=/opt/bin:/opt/sbin:$PATH to do it for this session only\033[0m'
|
|
||||||
echo -e '\033[32mInfo: opkg at /opt/bin will be linked to /bin but any package you install with opkg will not be automatically.\033[0m'
|
|
||||||
ln -sf /opt/bin/opkg /bin
|
ln -sf /opt/bin/opkg /bin
|
||||||
opkg update
|
echo -e '\033[32mInfo: Patching Quectel Login Binary\033[0m'
|
||||||
|
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||||
|
if [ "$?" -ne 0 ]; then
|
||||||
|
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||||
|
rm /opt/etc/shadow
|
||||||
|
rm /opt/etc/passwd
|
||||||
|
cp /etc/shadow /opt/etc/
|
||||||
|
cp /etc/passwd /opt/etc
|
||||||
|
mkdir /usrdata/root
|
||||||
|
mkdir /usrdata/root/bin
|
||||||
|
touch /usrdata/root/.profile
|
||||||
|
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||||
|
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||||
|
chmod +x /usrdata/root/.profile
|
||||||
|
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||||
|
rm /bin/login /usr/bin/passwd
|
||||||
|
ln -sf /opt/bin/login /bin
|
||||||
|
ln -sf /opt/bin/passwd /usr/bin/
|
||||||
|
ln -sf /opt/bin/useradd /usr/bin/
|
||||||
|
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||||
|
/usr/bin/passwd
|
||||||
|
|
||||||
|
# Install basic and useful utilites
|
||||||
|
opkg install mc htop dfc lsof
|
||||||
|
ln -sf /opt/bin/mc /bin
|
||||||
|
ln -sf /opt/bin/htop /bin
|
||||||
|
ln -sf /opt/bin/dfc /bin
|
||||||
|
ln -sf /opt/bin/lsof /bin
|
||||||
# Remount filesystem as read-only
|
# Remount filesystem as read-only
|
||||||
mount -o remount,ro /
|
mount -o remount,ro /
|
||||||
|
|||||||
1
simpleadmin/.rev
Normal file
1
simpleadmin/.rev
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
7
simpleadmin/console/.profile
Normal file
7
simpleadmin/console/.profile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#Path
|
||||||
|
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:opt/bin:/opt/sbin:/usrdata/root/bin
|
||||||
|
|
||||||
|
#Post-login execution
|
||||||
|
start_menu.sh
|
||||||
150
simpleadmin/console/menu/LAN_settings.sh
Normal file
150
simpleadmin/console/menu/LAN_settings.sh
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
CONFIG_FILE="/etc/data/mobileap_cfg.xml"
|
||||||
|
|
||||||
|
# Display Messages in Colors
|
||||||
|
display_random_color() {
|
||||||
|
local msg="$1"
|
||||||
|
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||||
|
local num_colors=${#colors[@]}
|
||||||
|
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||||
|
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
display_green() {
|
||||||
|
echo -e "\033[0;32m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
display_red() {
|
||||||
|
echo -e "\033[0;31m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check and Install xml binary if not present
|
||||||
|
check_and_install_xml() {
|
||||||
|
if [ ! -f "/opt/bin/xml" ]; then
|
||||||
|
echo "xml binary not found. Attempting to install xmlstarlet..."
|
||||||
|
opkg update
|
||||||
|
opkg install xmlstarlet
|
||||||
|
# Verify installation
|
||||||
|
if [ ! -f "/opt/bin/xml" ]; then
|
||||||
|
echo "Failed to install xmlstarlet. Exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "xml binary is available."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Edit XML Value
|
||||||
|
edit_xml_value() {
|
||||||
|
local node="$1"
|
||||||
|
local new_value="$2"
|
||||||
|
/opt/bin/xml ed -L -u "$node" -v "$new_value" "$CONFIG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get Current XML Value
|
||||||
|
get_current_value() {
|
||||||
|
/opt/bin/xml sel -t -v "$1" "$CONFIG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enable/Disable Menu
|
||||||
|
enable_disable_menu() {
|
||||||
|
local node="$1"
|
||||||
|
local current_value=$(get_current_value "$node")
|
||||||
|
echo "Current status: $([ "$current_value" == "1" ] && echo "Enabled" || echo "Disabled")"
|
||||||
|
echo "1. Enable"
|
||||||
|
echo "2. Disable"
|
||||||
|
read -p "Choose an option to toggle (1-2): " choice
|
||||||
|
local new_value="$([ "$choice" == "1" ] && echo "1" || echo "0")"
|
||||||
|
edit_xml_value "$node" "$new_value"
|
||||||
|
display_green "After making changes, please reboot to have them take effect."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Edit Simple Value
|
||||||
|
edit_simple_value() {
|
||||||
|
local node="$1"
|
||||||
|
local description="$2"
|
||||||
|
local current=$(get_current_value "$node")
|
||||||
|
echo "Current $description: $current"
|
||||||
|
read -p "Enter new $description: " new_value
|
||||||
|
edit_xml_value "$node" "$new_value"
|
||||||
|
display_green "After making changes, please reboot to have them take effect."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Edit DHCP IP Range
|
||||||
|
edit_dhcp_range() {
|
||||||
|
local start_ip=$(get_current_value "//MobileAPLanCfg/DHCPCfg/StartIP")
|
||||||
|
local end_ip=$(get_current_value "//MobileAPLanCfg/DHCPCfg/EndIP")
|
||||||
|
echo "Current Start IP: $start_ip"
|
||||||
|
echo "Current End IP: $end_ip"
|
||||||
|
read -p "Enter new Start IP: " new_start_ip
|
||||||
|
read -p "Enter new End IP: " new_end_ip
|
||||||
|
edit_xml_value "//MobileAPLanCfg/DHCPCfg/StartIP" "$new_start_ip"
|
||||||
|
edit_xml_value "//MobileAPLanCfg/DHCPCfg/EndIP" "$new_end_ip"
|
||||||
|
display_green "After making changes, please reboot to have them take effect."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reboot the system
|
||||||
|
reboot_system() {
|
||||||
|
echo "Rebooting system..."
|
||||||
|
atcmd 'AT+CFUN=1,1' # Ensure this command is correct for your system
|
||||||
|
echo "System reboot initiated. Good luck."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main Menu
|
||||||
|
main_menu() {
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
display_red "Warning, these changes can break access over the network. Know what you are doing, and be prepared to use ADB to fix this just in case."
|
||||||
|
echo "Configuration Menu"
|
||||||
|
echo "------------------"
|
||||||
|
display_green "1. Edit Gateway IPV4 Address"
|
||||||
|
display_green "2. Edit Gateway URL"
|
||||||
|
display_green "3. Edit LAN DHCP Start/End Range"
|
||||||
|
display_green "4. Edit LAN Subnet Mask"
|
||||||
|
display_green "5. Edit DHCPv6 Base address"
|
||||||
|
display_green "6. Toggle IPv4 NAT"
|
||||||
|
display_green "7. Toggle IPv6 NAT"
|
||||||
|
display_green "8. Toggle DHCP Server"
|
||||||
|
display_green "9. Toggle DHCPv4"
|
||||||
|
display_green "10. Toggle DHCPv6"
|
||||||
|
display_green "11. Toggle WAN Autoconnect"
|
||||||
|
display_green "12. Toggle WAN AutoReconnect"
|
||||||
|
display_green "13. Toggle Roaming"
|
||||||
|
display_green "14. Toggle WAN DNSv4 Passthrough"
|
||||||
|
display_green "15. Toggle WAN DNSv6 Passthrough"
|
||||||
|
display_green "16. Toggle IPPT NAT/Ability to access gateway while in IPPT mode"
|
||||||
|
display_green "17. Toggle UPnP"
|
||||||
|
display_green "18. Reboot System"
|
||||||
|
display_green "19. Exit"
|
||||||
|
echo
|
||||||
|
read -p "Select an option (1-19): " option
|
||||||
|
|
||||||
|
case "$option" in
|
||||||
|
1) edit_simple_value "//MobileAPLanCfg/APIPAddr" "Gateway IPV4 Address";;
|
||||||
|
2) edit_simple_value "//MobileAPLanCfg/GatewayURL" "Gateway URL";;
|
||||||
|
3) edit_dhcp_range;;
|
||||||
|
4) edit_simple_value "//MobileAPLanCfg/SubNetMask" "LAN Subnet Mask";;
|
||||||
|
5) edit_simple_value "//MobileAPLanCfg/ULAIPv6BaseAddr" "DHCPv6 Base Address";;
|
||||||
|
6) enable_disable_menu "//MobileAPNatCfg/IPv4NATDisable";;
|
||||||
|
7) enable_disable_menu "//MobileAPNatv6Cfg/EnableIPv6NAT";;
|
||||||
|
8) enable_disable_menu "//MobileAPLanCfg/EnableDHCPServer";;
|
||||||
|
9) enable_disable_menu "//MobileAPLanCfg/EnableIPV4";;
|
||||||
|
10) enable_disable_menu "//MobileAPLanCfg/EnableIPV6";;
|
||||||
|
11) enable_disable_menu "//MobileAPWanCfg/AutoConnect";;
|
||||||
|
12) enable_disable_menu "//MobileAPWanCfg/ReConnect";;
|
||||||
|
13) enable_disable_menu "//MobileAPWanCfg/Roaming";;
|
||||||
|
14) enable_disable_menu "//Dhcpv4Cfg/EnableDhcpv4Dns";;
|
||||||
|
15) enable_disable_menu "//Dhcpv6Cfg/EnableDhcpv6Dns";;
|
||||||
|
16) enable_disable_menu "//IPPassthroughFeatureWithNAT";;
|
||||||
|
17) enable_disable_menu "//MobileAPSrvcCfg/UPnP";;
|
||||||
|
18) reboot_system;;
|
||||||
|
19) break;;
|
||||||
|
*) echo "Invalid option. Please try again.";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start by checking and installing xml if necessary, then mount filesystem as rw and run the menu
|
||||||
|
mount -o remount,rw /
|
||||||
|
check_and_install_xml
|
||||||
|
main_menu
|
||||||
125
simpleadmin/console/menu/sfirewall_settings.sh
Normal file
125
simpleadmin/console/menu/sfirewall_settings.sh
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||||
|
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||||
|
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||||
|
|
||||||
|
# Display Messages in Colors
|
||||||
|
display_random_color() {
|
||||||
|
local msg="$1"
|
||||||
|
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||||
|
local num_colors=${#colors[@]}
|
||||||
|
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||||
|
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
display_green() {
|
||||||
|
echo -e "\033[0;32m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
display_red() {
|
||||||
|
echo -e "\033[0;31m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_portblocks() {
|
||||||
|
current_ports_line=$(grep '^PORTS=' "$SIMPLE_FIREWALL_SCRIPT")
|
||||||
|
ports=$(echo "$current_ports_line" | cut -d'=' -f2 | tr -d '()' | tr ' ' '\n' | grep -o '[0-9]\+')
|
||||||
|
echo -e "\e[1;32mCurrent configured ports:\e[0m"
|
||||||
|
echo "$ports" | awk '{print NR") "$0}'
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
echo -e "\e[1;32mEnter a port number to add/remove, or type 'done' or 'exit' to finish:\e[0m"
|
||||||
|
read port
|
||||||
|
if [ "$port" = "done" ] || [ "$port" = "exit" ]; then
|
||||||
|
if [ "$port" = "exit" ]; then
|
||||||
|
echo -e "\e[1;31mExiting without making changes...\e[0m"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
elif ! echo "$port" | grep -qE '^[0-9]+$'; then
|
||||||
|
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||||
|
elif echo "$ports" | grep -q "^$port\$"; then
|
||||||
|
ports=$(echo "$ports" | grep -v "^$port\$")
|
||||||
|
echo -e "\e[1;32mPort $port removed.\e[0m"
|
||||||
|
else
|
||||||
|
ports=$(echo "$ports"; echo "$port" | grep -o '[0-9]\+')
|
||||||
|
echo -e "\e[1;32mPort $port added.\e[0m"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$port" != "exit" ]; then
|
||||||
|
new_ports_line="PORTS=($(echo "$ports" | tr '\n' ' '))"
|
||||||
|
sed -i "s/$current_ports_line/$new_ports_line/" "$SIMPLE_FIREWALL_SCRIPT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ttl(){
|
||||||
|
# TTL configuration code
|
||||||
|
ttl_value=$(cat /usrdata/simplefirewall/ttlvalue)
|
||||||
|
if [ "$ttl_value" -eq 0 ]; then
|
||||||
|
echo -e "\e[1;31mTTL is not set.\e[0m"
|
||||||
|
else
|
||||||
|
echo -e "\e[1;32mTTL value is set to $ttl_value.\e[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\e[1;31mType 'exit' to cancel.\e[0m"
|
||||||
|
read -p "What do you want the TTL value to be: " new_ttl_value
|
||||||
|
if [ "$new_ttl_value" = "exit" ]; then
|
||||||
|
echo -e "\e[1;31mExiting TTL configuration...\e[0m"
|
||||||
|
return
|
||||||
|
elif ! echo "$new_ttl_value" | grep -qE '^[0-9]+$'; then
|
||||||
|
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||||
|
return
|
||||||
|
else
|
||||||
|
/usrdata/simplefirewall/ttl-override stop
|
||||||
|
echo "$new_ttl_value" > /usrdata/simplefirewall/ttlvalue
|
||||||
|
/usrdata/simplefirewall/ttl-override start
|
||||||
|
echo -e "\033[0;32mTTL value updated to $new_ttl_value.\033[0m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# function to configure the fetures of simplefirewall
|
||||||
|
simple_firewall_menu() {
|
||||||
|
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
||||||
|
echo -e "\033[0;31mSimplefirewall is not installed, would you like to install it?\033[0m"
|
||||||
|
echo -e "\033[0;32m1) Yes\033[0m"
|
||||||
|
echo -e "\033[0;31m2) No\033[0m"
|
||||||
|
read -p "Enter your choice (1-2): " install_choice
|
||||||
|
|
||||||
|
case $install_choice in
|
||||||
|
1)
|
||||||
|
install_simple_firewall
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "\033[0;31mInvalid choice. Please select either 1 or 2.\033[0m"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\e[1;32mConfigure Simple Firewall:\e[0m"
|
||||||
|
echo -e "\e[38;5;208m1) Configure incoming port block\e[0m"
|
||||||
|
echo -e "\e[38;5;27m2) Configure TTL\e[0m"
|
||||||
|
read -p "Enter your choice (1-2): " menu_choice
|
||||||
|
|
||||||
|
case $menu_choice in
|
||||||
|
1)
|
||||||
|
set_portblocks
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
set_ttl
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "\e[1;31mInvalid choice. Please select either 1 or 2.\e[0m"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
systemctl restart simplefirewall
|
||||||
|
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start by checking and installing xml if necessary, then mount filesystem as rw and run the menu
|
||||||
|
mount -o remount,rw /
|
||||||
|
simple_firewall_menu
|
||||||
143
simpleadmin/console/menu/start_menu.sh
Normal file
143
simpleadmin/console/menu/start_menu.sh
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define executable files path
|
||||||
|
EXE=/usrdata/root/bin
|
||||||
|
MENU_SH=/usrdata/simpleadmin/console/menu
|
||||||
|
|
||||||
|
# Display Messages in Colors
|
||||||
|
display_random_color() {
|
||||||
|
local msg="$1"
|
||||||
|
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||||
|
local num_colors=${#colors[@]}
|
||||||
|
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||||
|
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
display_green() {
|
||||||
|
echo -e "\033[0;32m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
display_red() {
|
||||||
|
echo -e "\033[0;31m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Menus
|
||||||
|
|
||||||
|
toolkit() {
|
||||||
|
while true; do
|
||||||
|
display_green "Welcome to iamromulan's Simple Console Menu"
|
||||||
|
display_green "Select an option:"
|
||||||
|
echo "------------------"
|
||||||
|
display_green "1. LAN Settings"
|
||||||
|
display_green "2. Change simpleadmin (admin) password"
|
||||||
|
display_green "3. Change root password (shell/ssh/console)"
|
||||||
|
display_green "4. Open File Browser/Editor (mc)"
|
||||||
|
display_green "5. View Used/Available space"
|
||||||
|
display_green "6. Open Task Manager/View CPU Load"
|
||||||
|
display_green "7. Run speedtest.net test"
|
||||||
|
display_green "8. Run fast.com test (30Mbps max)"
|
||||||
|
display_green "9. Get and run the Toolkit"
|
||||||
|
display_green "10. Get and run the Development/unstable Toolkit"
|
||||||
|
display_green "11. Exit (Enter Root Shell)"
|
||||||
|
echo
|
||||||
|
read -p "Select an option (1-11): " option
|
||||||
|
|
||||||
|
case "$option" in
|
||||||
|
1) $MEU/LAN_settings ;;
|
||||||
|
2) $EXE/simplepasswd ;;
|
||||||
|
3) passwd ;;
|
||||||
|
4) mc ;;
|
||||||
|
5) dfc ;;
|
||||||
|
6) htop ;;
|
||||||
|
7) $EXE/speedtest ;;
|
||||||
|
8) $EXE/fast ;;
|
||||||
|
9) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||||
|
10) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||||
|
11) break ;;
|
||||||
|
*) echo "Invalid option. Please try again." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
apps() {
|
||||||
|
while true; do
|
||||||
|
display_green "Welcome to iamromulan's Simple Console Menu"
|
||||||
|
display_green "Select an option:"
|
||||||
|
echo "------------------"
|
||||||
|
display_green "1. LAN Settings"
|
||||||
|
display_green "2. Change simpleadmin (admin) password"
|
||||||
|
display_green "3. Change root password (shell/ssh/console)"
|
||||||
|
display_green "4. Open File Browser/Editor (mc)"
|
||||||
|
display_green "5. View Used/Available space"
|
||||||
|
display_green "6. Open Task Manager/View CPU Load"
|
||||||
|
display_green "7. Run speedtest.net test"
|
||||||
|
display_green "8. Run fast.com test (30Mbps max)"
|
||||||
|
display_green "9. Get and run the Toolkit"
|
||||||
|
display_green "10. Get and run the Development/unstable Toolkit"
|
||||||
|
display_green "11. Exit (Enter Root Shell)"
|
||||||
|
echo
|
||||||
|
read -p "Select an option (1-11): " option
|
||||||
|
|
||||||
|
case "$option" in
|
||||||
|
1) $menu_sh/LAN_settings ;;
|
||||||
|
2) $EXE/simplepasswd ;;
|
||||||
|
3) passwd ;;
|
||||||
|
4) mc ;;
|
||||||
|
5) dfc ;;
|
||||||
|
6) htop ;;
|
||||||
|
7) $EXE/speedtest ;;
|
||||||
|
8) $EXE/fast ;;
|
||||||
|
9) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||||
|
10) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||||
|
11) break ;;
|
||||||
|
*) echo "Invalid option. Please try again." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
settings() {
|
||||||
|
while true; do
|
||||||
|
display_green "Welcome to iamromulan's Simple Console Menu"
|
||||||
|
display_green "Select an option:"
|
||||||
|
echo "------------------"
|
||||||
|
display_green "1. LAN Settings"
|
||||||
|
display_green "2. Change simpleadmin (admin) password"
|
||||||
|
display_green "3. Change root password (shell/ssh/console)"
|
||||||
|
display_green "4. Go back"
|
||||||
|
echo
|
||||||
|
read -p "Select an option (1-11): " option
|
||||||
|
|
||||||
|
case "$option" in
|
||||||
|
1) $MENU_SH/LAN_settings ;;
|
||||||
|
2) $EXE/simplepasswd ;;
|
||||||
|
3) passwd ;;
|
||||||
|
4) break ;;
|
||||||
|
*) echo "Invalid option. Please try again." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main_menu() {
|
||||||
|
while true; do
|
||||||
|
display_green "Welcome to iamromulan's Simple Console Menu"
|
||||||
|
display_green "To get back to this from the root shell, just type 'menu'"
|
||||||
|
display_green "Select an option:"
|
||||||
|
echo "------------------"
|
||||||
|
display_random_color "1) Apps"
|
||||||
|
display_random_color "2) Settings"
|
||||||
|
display_random_color "3) Toolkit"
|
||||||
|
display_random_color "4) Exit (Enter Root Shell)"
|
||||||
|
echo
|
||||||
|
read -p "Select an option (1-11): " option
|
||||||
|
|
||||||
|
case "$option" in
|
||||||
|
1) apps ;;
|
||||||
|
2) settings ;;
|
||||||
|
3) toolkit ;;
|
||||||
|
4) break ;;
|
||||||
|
*) echo "Invalid option. Please try again." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main_menu
|
||||||
27
simpleadmin/console/services/ethernet_watchdog.sh
Normal file
27
simpleadmin/console/services/ethernet_watchdog.sh
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define the command to execute when the ethernet port breaks
|
||||||
|
command_to_execute="/usrdata/socat-at-bridge/atcmd 'AT+CFUN=1,1'"
|
||||||
|
|
||||||
|
# Define the monitoring function
|
||||||
|
watch() {
|
||||||
|
while true; do
|
||||||
|
# Extract the last 60 lines of dmesg and count the specific pattern occurrences
|
||||||
|
count=$(dmesg | tail -60 | grep -e "eth0: cmd = 0xff, should be 0x47" -e "eth0: pci link is down" | grep -c "eth0")
|
||||||
|
|
||||||
|
# Check if the count of patterns is 4 or more
|
||||||
|
if [ "$count" -ge 4 ]; then
|
||||||
|
echo "Condition met, executing command..."
|
||||||
|
eval "$command_to_execute"
|
||||||
|
# Optionally, add a break here if you want the script to stop after executing the command
|
||||||
|
# break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sleep for 3 seconds before checking again
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initial delay before starting monitoring
|
||||||
|
sleep 30
|
||||||
|
watch
|
||||||
28
simpleadmin/console/services/ping_watchdog.sh
Normal file
28
simpleadmin/console/services/ping_watchdog.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define the hostname or IP address to ping
|
||||||
|
HOSTNAME="google.com"
|
||||||
|
|
||||||
|
# Number of pings to attempt
|
||||||
|
PING_COUNT=6
|
||||||
|
|
||||||
|
# Initialize a counter for successful pings
|
||||||
|
success_count=0
|
||||||
|
|
||||||
|
# Attempt to ping the specified number of times
|
||||||
|
for i in $(seq 1 $PING_COUNT); do
|
||||||
|
# Ping the hostname with a timeout of 1 second per ping
|
||||||
|
if ping -c 1 -W 1 $HOSTNAME &> /dev/null; then
|
||||||
|
((success_count++))
|
||||||
|
else
|
||||||
|
echo "Ping attempt $i failed."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if all pings failed
|
||||||
|
if [ $success_count -eq 0 ]; then
|
||||||
|
echo "All $PING_COUNT ping attempts failed, executing AT command."
|
||||||
|
/bin/atcmd 'AT+CFUN=1,1'
|
||||||
|
else
|
||||||
|
echo "$success_count out of $PING_COUNT ping attempts were successful."
|
||||||
|
fi
|
||||||
14
simpleadmin/console/services/systemd/ping_watchdog.service
Normal file
14
simpleadmin/console/services/systemd/ping_watchdog.service
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Ping Watchdog Service
|
||||||
|
Wants=network.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStartPre=/bin/sleep 60 # Sleep for 60 seconds to ensure the network is ready
|
||||||
|
ExecStart=/usrdata/simpleadmin/console/services/ping_watchdog.sh
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=30s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -1,7 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Read the serial number and remove the last two digits
|
# Check if /usrdata/socat-at-bridge/atcmd exists
|
||||||
serial_number=$(cat /sys/devices/soc0/serial_number | sed 's/..$//')
|
if [ -f "/usrdata/socat-at-bridge/atcmd" ]; then
|
||||||
|
# Read the serial number
|
||||||
|
serial_number=$(/usrdata/socat-at-bridge/atcmd 'AT+EGMR=0,5' | grep '+EGMR:' | cut -d '"' -f2)
|
||||||
|
# Read the firmware revision
|
||||||
|
firmware_revision=$(/usrdata/socat-at-bridge/atcmd 'AT+CGMR' | grep -o 'RM[0-9A-Z]*' | head -1)
|
||||||
|
else
|
||||||
|
serial_number="UNKNOWN"
|
||||||
|
firmware_revision="UNKNOWN"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "=============================================================="
|
echo "=============================================================="
|
||||||
echo "=============================================================="
|
echo "=============================================================="
|
||||||
@@ -82,9 +90,10 @@ echo " :@@@@@*. "
|
|||||||
echo " .=@@@@@- "
|
echo " .=@@@@@- "
|
||||||
echo " :+##+. "
|
echo " :+##+. "
|
||||||
echo "=============================================================="
|
echo "=============================================================="
|
||||||
echo "Test ttyd startup file by iamromulan V0.1"
|
echo "TTYd session file by iamromulan v1.1"
|
||||||
echo "quectel-ID: $serial_number"
|
echo "Firmware Revision: $firmware_revision"
|
||||||
|
echo "Serial Number: $serial_number"
|
||||||
echo "=============================================================="
|
echo "=============================================================="
|
||||||
|
|
||||||
# Start a login session
|
# Start a login session
|
||||||
exec /bin/login
|
exec /bin/login
|
||||||
BIN
simpleadmin/htpasswd
Normal file
BIN
simpleadmin/htpasswd
Normal file
Binary file not shown.
47
simpleadmin/lighttpd.conf
Normal file
47
simpleadmin/lighttpd.conf
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
server.modules = (
|
||||||
|
"mod_redirect",
|
||||||
|
"mod_cgi",
|
||||||
|
"mod_proxy",
|
||||||
|
"mod_openssl",
|
||||||
|
"mod_authn_file",
|
||||||
|
)
|
||||||
|
|
||||||
|
server.username = "www-data"
|
||||||
|
server.groupname = "dialout"
|
||||||
|
|
||||||
|
server.port = 80
|
||||||
|
server.document-root = "/usrdata/simpleadmin/www"
|
||||||
|
index-file.names = ( "index.html" )
|
||||||
|
|
||||||
|
auth.backend = "htpasswd"
|
||||||
|
auth.backend.htpasswd.userfile = "/opt/etc/.htpasswd"
|
||||||
|
|
||||||
|
$SERVER["socket"] == "0.0.0.0:443" {
|
||||||
|
ssl.engine = "enable"
|
||||||
|
ssl.privkey= "/usrdata/simpleadmin/server.key"
|
||||||
|
ssl.pemfile= "/usrdata/simpleadmin/server.crt"
|
||||||
|
ssl.acme-tls-1 = "/etc/simpleadmin/dehydrated/tls-alpn-01"
|
||||||
|
ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2") # (lighttpd 1.4.56 default; recommended to accept only TLSv1.2 and TLSv1.3)
|
||||||
|
auth.require = ( "/" => (
|
||||||
|
"method" => "basic",
|
||||||
|
"realm" => "Authorized users only",
|
||||||
|
"require" => "valid-user"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect everything to https
|
||||||
|
$HTTP["scheme"] == "http" {
|
||||||
|
url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Anything in /cgi-bin will be run as a script
|
||||||
|
$HTTP["url"] =~ "/cgi-bin/" {
|
||||||
|
cgi.assign = ( "" => "" )
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle proxy to ttyd if it's running
|
||||||
|
$HTTP["url"] =~ "(^/console)" {
|
||||||
|
proxy.header = ("map-urlpath" => ( "/console" => "/" ), "upgrade" => "enable" )
|
||||||
|
proxy.server = ( "" => ("" => ( "host" => "127.0.0.1", "port" => 8080 )))
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
# Run AT+CGMM to get the modem model
|
|
||||||
echo -en "AT+CGMM\r\n" | microcom -t 1000 /dev/ttyOUT > /tmp/modemmodel.txt
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# Run AT+CGCONTRDP once then proceed to while loop
|
|
||||||
echo -en "AT+CGCONTRDP=1\r\n" | microcom -t 1000 /dev/ttyOUT > /tmp/apn.txt
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# Run AT+QUIMSLOT? to get the current sim slot
|
|
||||||
echo -en "AT+QUIMSLOT?\r\n" | microcom -t 1000 /dev/ttyOUT > /tmp/simslot.txt
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# Send request to modem and wait 3 seconds for data
|
|
||||||
echo -en "AT+QSPN;+CEREG=2;+CEREG?;+CEREG=0;+C5GREG=2;+C5GREG?;+C5GREG=0;+CSQ;+QENG=\"servingcell\";+QRSRP;+QCAINFO;+QNWPREFCFG=\"mode_pref\";+QTEMP\r\n" \
|
|
||||||
| microcom -t 3000 /dev/ttyOUT > /tmp/modemstatus.txt
|
|
||||||
if [ $? -eq 0 ]
|
|
||||||
then
|
|
||||||
# Parse
|
|
||||||
if [ -f /tmp/modemstatus.txt ]
|
|
||||||
then
|
|
||||||
/usrdata/simpleadmin/scripts/modemstatus_parse.sh
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
sleep 25 # Add a sleep to avoid CPU overload
|
|
||||||
done
|
|
||||||
@@ -1,522 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Adapted to work with RJ45 / Quectel Board Dev
|
|
||||||
# Quectel AT Parsing Original source ROOter2203
|
|
||||||
# https://github.com/ofmodemsandmen/ROOterSource2203/blob/6636758b945ff16b6c5b54494de04b74b011c204/package/rooter/ext-rooter-basic/files/usr/lib/rooter/common/quecteldata.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
rspr2rssi() {
|
|
||||||
echo ${RSCP} ${BW_N} | awk '{printf "%.0f\n", (($1+10*log(12*$2)/log(10)))}'
|
|
||||||
}
|
|
||||||
|
|
||||||
lte_bw() {
|
|
||||||
BW=$(echo $BW | grep -o "[0-5]\{1\}")
|
|
||||||
case $BW in
|
|
||||||
"0")
|
|
||||||
BW="1.4" ;;
|
|
||||||
"1")
|
|
||||||
BW="3" ;;
|
|
||||||
"2"|"3"|"4"|"5")
|
|
||||||
BW=$((($(echo $BW) - 1) * 5)) ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
nr_bw() {
|
|
||||||
BW=$(echo $BW | grep -o "[0-9]\{1,2\}")
|
|
||||||
case $BW in
|
|
||||||
"0"|"1"|"2"|"3"|"4"|"5")
|
|
||||||
BW=$((($(echo $BW) + 1) * 5)) ;;
|
|
||||||
"6"|"7"|"8"|"9"|"10"|"11"|"12")
|
|
||||||
BW=$((($(echo $BW) - 2) * 10)) ;;
|
|
||||||
"13")
|
|
||||||
BW="200" ;;
|
|
||||||
"14")
|
|
||||||
BW="400" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to get the secondary LTE & NR5G bands
|
|
||||||
# Now conditionally calls the functions to get the secondary bands
|
|
||||||
# Only apply | sed '1d' to NR_BAND when network mode is SA
|
|
||||||
get_secondary_bands() {
|
|
||||||
# Extract LTE BANDs from SCC lines
|
|
||||||
SCC_BANDS=$(echo "$OX" | grep '+QCAINFO: "SCC"' | grep -o '"LTE BAND [0-9]\+"' | tr -d '"' | sed '1d')
|
|
||||||
|
|
||||||
# Extract NR5G BANDs from SCC lines
|
|
||||||
NR_BAND=$(echo "$OX" | grep '+QCAINFO: "SCC"' | grep -o '"NR5G BAND [0-9]\+"' | tr -d '"')
|
|
||||||
|
|
||||||
# Check if both SCC and NR bands are non-empty
|
|
||||||
if [ -n "$SCC_BANDS" ] && [ -n "$NR_BAND" ]; then
|
|
||||||
# Concatenate LTE BANDs with NR5G BANDs
|
|
||||||
SC_BANDS="$SCC_BANDS<br />$NR_BAND"
|
|
||||||
else
|
|
||||||
# Set SC_BANDS to the non-empty variable or empty if both are empty
|
|
||||||
SC_BANDS="${SCC_BANDS}${NR_BAND}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the modem model from /tmp/modemmodel.txt and parse it
|
|
||||||
MODEM_MODEL=$(</tmp/modemmodel.txt)
|
|
||||||
# Get the model name from the modem model (they either start with RG or RM)
|
|
||||||
MODEM_MODEL=$(echo "$MODEM_MODEL" | grep -o "RG[^ ]\+\|RM[^ ]\+")
|
|
||||||
|
|
||||||
# Get the APN from /tmp/apn.txt and parse it
|
|
||||||
APN=$(grep "^+CGCONTRDP" /tmp/apn.txt | awk -F',' '{gsub(/"/, "", $3); print $3}')
|
|
||||||
|
|
||||||
# Get the SIM slot from /tmp/simslot.txt and parse it
|
|
||||||
# simslot.txt looks like this: +QUIMSLOT: 1
|
|
||||||
SIMSLOT=$(</tmp/simslot.txt)
|
|
||||||
SIMSLOT=$(echo "$SIMSLOT" | grep -o "[0-9]")
|
|
||||||
# Append SIM before the SIM slot number
|
|
||||||
SIMSLOT="SIM "$SIMSLOT
|
|
||||||
|
|
||||||
# Read File
|
|
||||||
OX=$(</tmp/modemstatus.txt)
|
|
||||||
|
|
||||||
OX=$(echo $OX | tr 'a-z' 'A-Z')
|
|
||||||
|
|
||||||
RSRP=""
|
|
||||||
RSRQ=""
|
|
||||||
CHANNEL="-"
|
|
||||||
ECIO="-"
|
|
||||||
RSCP="-"
|
|
||||||
ECIO1=" "
|
|
||||||
RSCP1=" "
|
|
||||||
MODE="-"
|
|
||||||
MODTYPE="-"
|
|
||||||
NETMODE="-"
|
|
||||||
LBAND="-"
|
|
||||||
PCI="-"
|
|
||||||
CTEMP="-"
|
|
||||||
SINR="-"
|
|
||||||
COPS="-"
|
|
||||||
COPS_MCC="-"
|
|
||||||
COPS_MNC="-"
|
|
||||||
CID=""
|
|
||||||
CID5=""
|
|
||||||
RAT=""
|
|
||||||
QSPN=$(echo $OX | grep -o '+QSPN: "[^"]*","[^"]*","[^"]*",[^"]*,"[^"]*"' | cut -c 8-)
|
|
||||||
# GET MCCMNC from the last field of QSPN
|
|
||||||
MCCMNC=$(echo $QSPN | cut -d, -f5 | tr -d '"')
|
|
||||||
PROVIDER=$(echo $QSPN | cut -d, -f1 | tr -d '"')
|
|
||||||
PROVIDER_ID=$(echo $QSPN | cut -d, -f5 | tr -d '"')
|
|
||||||
CSQ=$(echo $OX | grep -o "+CSQ: [0-9]\{1,2\}" | grep -o "[0-9]\{1,2\}")
|
|
||||||
if [ "$CSQ" = "99" ]; then
|
|
||||||
CSQ=""
|
|
||||||
fi
|
|
||||||
if [ -n "$CSQ" ]; then
|
|
||||||
CSQ_PER=$(($CSQ * 100/31))"%"
|
|
||||||
CSQ_RSSI=$((2 * CSQ - 113))" dBm"
|
|
||||||
else
|
|
||||||
CSQ="-"
|
|
||||||
CSQ_PER="-"
|
|
||||||
CSQ_RSSI="-"
|
|
||||||
fi
|
|
||||||
|
|
||||||
NR_NSA=$(echo $OX | grep -o "+QENG:[ ]\?\"NR5G-NSA\",")
|
|
||||||
NR_SA=$(echo $OX | grep -o "+QENG: \"SERVINGCELL\",[^,]\+,\"NR5G-SA\",\"[DFT]\{3\}\",")
|
|
||||||
if [ -n "$NR_NSA" ]; then
|
|
||||||
QENG=",,"$(echo $OX" " | grep -o "+QENG: \"LTE\".\+\"NR5G-NSA\"," | tr " " ",")
|
|
||||||
if [ -z "$QENG5" ]; then
|
|
||||||
# Fixed an issue where the last 2 digits were not included in the regex
|
|
||||||
QENG5=$(echo $OX | grep -o "+QENG:[ ]\?\"NR5G-NSA\",[0-9]\{3\},[0-9]\{2,3\},[0-9]\{1,5\},-[0-9]\{2,3\},[-0-9]\{1,3\},-[0-9]\{2,3\},[0-9]\{1,6\},[0-9]\{1,3\},[0-9]\{1,3\},[0-9]\{1,3\}")
|
|
||||||
if [ -n "$QENG5" ]; then
|
|
||||||
QENG5=$QENG5",,"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif [ -n "$NR_SA" ]; then
|
|
||||||
QENG=$(echo $NR_SA | tr " " ",")
|
|
||||||
QENG5=$(echo $OX | grep -o "+QENG: \"SERVINGCELL\",[^,]\+,\"NR5G-SA\",\"[DFT]\{3\}\",[ 0-9]\{3,4\},[0-9]\{2,3\},[0-9A-F]\{1,10\},[0-9]\{1,5\},[0-9A-F]\{2,6\},[0-9]\{6,7\},[0-9]\{1,3\},[0-9]\{1,2\},-[0-9]\{2,5\},-[0-9]\{2,3\},[-0-9]\{1,3\}")
|
|
||||||
else
|
|
||||||
QENG=$(echo $OX" " | grep -o "+QENG: [^ ]\+ " | tr " " ",")
|
|
||||||
fi
|
|
||||||
QCA=$(echo $OX" " | grep -o "+QCAINFO: \"S[CS]\{2\}\".\+NWSCANMODE" | tr " " ",")
|
|
||||||
QNSM=$(echo $OX | grep -o "+QCFG: \"NWSCANMODE\",[0-9]")
|
|
||||||
QNWP=$(echo $OX | grep -o "+QNWPREFCFG: \"MODE_PREF\",[A-Z5:]\+" | cut -d, -f2)
|
|
||||||
QTEMP=$(echo $OX | grep -o "+QTEMP: [0-9]\{1,3\}")
|
|
||||||
if [ -z "$QTEMP" ]; then
|
|
||||||
QTEMP=$(echo $OX | grep -o "+QTEMP:[ ]\?\"XO[_-]THERM[_-][^,]\+,[\"]\?[0-9]\{1,3\}" | grep -o "[0-9]\{1,3\}")
|
|
||||||
fi
|
|
||||||
if [ -z "$QTEMP" ]; then
|
|
||||||
QTEMP=$(echo $OX | grep -o "+QTEMP:[ ]\?\"MDM-CORE-USR.\+[0-9]\{1,3\}\"" | cut -d\" -f4)
|
|
||||||
fi
|
|
||||||
if [ -z "$QTEMP" ]; then
|
|
||||||
QTEMP=$(echo $OX | grep -o "+QTEMP:[ ]\?\"MDMSS.\+[0-9]\{1,3\}\"" | cut -d\" -f4)
|
|
||||||
fi
|
|
||||||
if [ -n "$QTEMP" ]; then
|
|
||||||
CTEMP=$(echo $QTEMP | grep -o "[0-9]\{1,3\}")$(printf "\xc2\xb0")"C"
|
|
||||||
fi
|
|
||||||
RAT=$(echo $QENG | cut -d, -f4 | grep -o "[-A-Z5]\{3,7\}")
|
|
||||||
|
|
||||||
|
|
||||||
rm -f /tmp/modnetwork
|
|
||||||
case $RAT in
|
|
||||||
"GSM")
|
|
||||||
MODE="GSM"
|
|
||||||
;;
|
|
||||||
"WCDMA")
|
|
||||||
MODE="WCDMA"
|
|
||||||
CHANNEL=$(echo $QENG | cut -d, -f9)
|
|
||||||
RSCP=$(echo $QENG | cut -d, -f12)
|
|
||||||
RSCP="-"$(echo $RSCP | grep -o "[0-9]\{1,3\}")
|
|
||||||
ECIO=$(echo $QENG | cut -d, -f13)
|
|
||||||
ECIO="-"$(echo $ECIO | grep -o "[0-9]\{1,3\}")
|
|
||||||
;;
|
|
||||||
"LTE"|"CAT-M"|"CAT-NB")
|
|
||||||
MODE=$(echo $QENG | cut -d, -f5 | grep -o "[DFT]\{3\}")
|
|
||||||
if [ -n "$MODE" ]; then
|
|
||||||
MODE="$RAT $MODE"
|
|
||||||
else
|
|
||||||
MODE="$RAT"
|
|
||||||
fi
|
|
||||||
get_secondary_bands
|
|
||||||
PCI=$(echo $QENG | cut -d, -f9)
|
|
||||||
CHANNEL=$(echo $QENG | cut -d, -f10)
|
|
||||||
LBAND=$(echo $QENG | cut -d, -f11 | grep -o "[0-9]\{1,3\}")
|
|
||||||
BW=$(echo $QENG | cut -d, -f12)
|
|
||||||
lte_bw
|
|
||||||
BWU=$BW
|
|
||||||
BW=$(echo $QENG | cut -d, -f13)
|
|
||||||
lte_bw
|
|
||||||
BWD=$BW
|
|
||||||
if [ -z "$BWD" ]; then
|
|
||||||
BWD="unknown"
|
|
||||||
fi
|
|
||||||
if [ -z "$BWU" ]; then
|
|
||||||
BWU="unknown"
|
|
||||||
fi
|
|
||||||
if [ -n "$LBAND" ]; then
|
|
||||||
PC_BAND="LTE BAND "$LBAND
|
|
||||||
LBAND="B"$LBAND" (Bandwidth $BWD MHz Down | $BWU MHz Up)"
|
|
||||||
fi
|
|
||||||
RSRP=$(echo $QENG | cut -d, -f15 | grep -o "[0-9]\{1,3\}")
|
|
||||||
if [ -n "$RSRP" ]; then
|
|
||||||
RSCP="-"$RSRP
|
|
||||||
RSRPLTE=$RSCP
|
|
||||||
fi
|
|
||||||
RSRQ=$(echo $QENG | cut -d, -f16 | grep -o "[0-9]\{1,3\}")
|
|
||||||
if [ -n "$RSRQ" ]; then
|
|
||||||
ECIO="-"$RSRQ
|
|
||||||
fi
|
|
||||||
RSSI=$(echo $QENG | cut -d, -f17 | grep -o "\-[0-9]\{1,3\}")
|
|
||||||
if [ -n "$RSSI" ]; then
|
|
||||||
CSQ_RSSI=$RSSI" dBm"
|
|
||||||
fi
|
|
||||||
SINRR=$(echo $QENG | cut -d, -f18 | grep -o "[0-9]\{1,3\}")
|
|
||||||
if [ -n "$SINRR" ]; then
|
|
||||||
if [ $SINRR -le 25 ]; then
|
|
||||||
SINR=$((($(echo $SINRR) * 2) -20))" dB"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ -n "$(echo $QENG | cut -d, -f21)" ]; then
|
|
||||||
CQI=$(echo $QENG | cut -d, -f19 | grep "^[0-9]\+$")
|
|
||||||
if [ -n "$SINR" -a -n "$CQI" -a "$CQI" != "0" ]; then
|
|
||||||
SINR=$SINR" (CQI $CQI)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ -n "$NR_NSA" ]; then
|
|
||||||
# Changed network mode to NR5G NSA for easy identification
|
|
||||||
MODE="NR5G NSA"
|
|
||||||
echo "0" > /tmp/modnetwork
|
|
||||||
if [ -n "$QENG5" ]; then
|
|
||||||
QENG5=$QENG5",,"
|
|
||||||
# Append the initial PCI value rather than overwriting it
|
|
||||||
get_secondary_bands
|
|
||||||
PCI="$PCI, "$(echo $QENG5 | cut -d, -f4)
|
|
||||||
SCHV=$(echo $QENG5 | cut -d, -f8)
|
|
||||||
SLBV=$(echo $QENG5 | cut -d, -f9) # Now correctly captures the NR band
|
|
||||||
BW=$(echo $QENG5 | cut -d, -f10) # Now gets the correct BW
|
|
||||||
if [ -n "$SLBV" ]; then
|
|
||||||
LBAND=$LBAND"<br />n"$SLBV
|
|
||||||
if [ -n "$BW" ]; then
|
|
||||||
nr_bw
|
|
||||||
LBAND=$LBAND" (Bandwidth $BW MHz)"
|
|
||||||
fi
|
|
||||||
if [ "$SCHV" -ge 123400 ]; then
|
|
||||||
CHANNEL=$CHANNEL", "$SCHV
|
|
||||||
else
|
|
||||||
CHANNEL=$CHANNEL", -"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# removed the (unknown NR5G BAND) and replaced with No NR5G Band to avoid confusion
|
|
||||||
LBAND=$LBAND"<br />No NR5G Band Detected"
|
|
||||||
CHANNEL=$CHANNEL", -"
|
|
||||||
fi
|
|
||||||
RSCP=$RSCP" dBm<br />"$(echo $QENG5 | cut -d, -f5)
|
|
||||||
SINRR=$(echo $QENG5 | cut -d, -f6 | grep -o "[0-9]\{1,3\}")
|
|
||||||
if [ -n "$SINRR" ]; then
|
|
||||||
if [ $SINRR -le 30 ]; then
|
|
||||||
SINR=$SINR"<br />"$((($(echo $SINRR) * 2) -20))" dB"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
ECIO=$ECIO" (4G) dB<br />"$(echo $QENG5 | cut -d, -f7)" (5G) "
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ -z "$LBAND" ]; then
|
|
||||||
LBAND="-"
|
|
||||||
else
|
|
||||||
if [ -n "$QCA" ]; then
|
|
||||||
QCA=$(echo $QCA | grep -o "\"S[CS]\{2\}\"[-0-9A-Z,\"]\+")
|
|
||||||
for QCAL in $(echo "$QCA"); do
|
|
||||||
if [ $(echo "$QCAL" | cut -d, -f7) = "2" ]; then
|
|
||||||
SCHV=$(echo $QCAL | cut -d, -f2 | grep -o "[0-9]\+")
|
|
||||||
SRATP="B"
|
|
||||||
if [ -n "$SCHV" ]; then
|
|
||||||
CHANNEL="$CHANNEL, $SCHV"
|
|
||||||
if [ "$SCHV" -gt 123400 ]; then
|
|
||||||
SRATP="n"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
SLBV=$(echo $QCAL | cut -d, -f6 | grep -o "[0-9]\{1,2\}")
|
|
||||||
if [ -n "$SLBV" ]; then
|
|
||||||
LBAND=$LBAND"<br />"$SRATP$SLBV
|
|
||||||
BWD=$(echo $QCAL | cut -d, -f3 | grep -o "[0-9]\{1,3\}")
|
|
||||||
if [ -n "$BWD" ]; then
|
|
||||||
UPDOWN=$(echo $QCAL | cut -d, -f13)
|
|
||||||
case "$UPDOWN" in
|
|
||||||
"UL" )
|
|
||||||
CATYPE="CA"$(printf "\xe2\x86\x91") ;;
|
|
||||||
"DL" )
|
|
||||||
CATYPE="CA"$(printf "\xe2\x86\x93") ;;
|
|
||||||
* )
|
|
||||||
CATYPE="CA" ;;
|
|
||||||
esac
|
|
||||||
if [ $BWD -gt 14 ]; then
|
|
||||||
LBAND=$LBAND" ("$CATYPE", Bandwidth "$(($(echo $BWD) / 5))" MHz)"
|
|
||||||
else
|
|
||||||
LBAND=$LBAND" ("$CATYPE", Bandwidth 1.4 MHz)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
LBAND=$LBAND
|
|
||||||
fi
|
|
||||||
PCI="$PCI, "$(echo $QCAL | cut -d, -f8)
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ $RAT = "CAT-M" ] || [ $RAT = "CAT-NB" ]; then
|
|
||||||
LBAND="B$(echo $QENG | cut -d, -f11) ($RAT)"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"NR5G-SA")
|
|
||||||
MODE="NR5G-SA"
|
|
||||||
echo "0" > /tmp/modnetwork
|
|
||||||
if [ -n "$QENG5" ]; then
|
|
||||||
MODE="$RAT $(echo $QENG5 | cut -d, -f4)"
|
|
||||||
PCI=$(echo $QENG5 | cut -d, -f8)
|
|
||||||
get_secondary_bands
|
|
||||||
# Apply | sed '1d' to NR_BAND
|
|
||||||
NR_BAND=$(echo $NR_BAND | sed '1d')
|
|
||||||
CHANNEL=$(echo $QENG5 | cut -d, -f10)
|
|
||||||
LBAND=$(echo $QENG5 | cut -d, -f11)
|
|
||||||
PC_BAND="NR5G BAND "$LBAND
|
|
||||||
BW=$(echo $QENG5 | cut -d, -f12)
|
|
||||||
nr_bw
|
|
||||||
LBAND="n"$LBAND" (Bandwidth $BW MHz)"
|
|
||||||
RSCP=$(echo $QENG5 | cut -d, -f13)
|
|
||||||
ECIO=$(echo $QENG5 | cut -d, -f14)
|
|
||||||
if [ "$CSQ_PER" = "-" ]; then
|
|
||||||
BW_N=($BW * 5)
|
|
||||||
RSSI=$(rspr2rssi)
|
|
||||||
CSQ_PER=$((100 - (($RSSI + 51) * 100/-62)))"%"
|
|
||||||
CSQ=$((($RSSI + 113) / 2))
|
|
||||||
CSQ_RSSI=$RSSI" dBm"
|
|
||||||
fi
|
|
||||||
SINRR=$(echo $QENG5 | cut -d, -f15 | grep -o "[0-9]\{1,3\}")
|
|
||||||
if [ -n "$SINRR" ]; then
|
|
||||||
if [ $SINRR -le 30 ]; then
|
|
||||||
SINR=$((($(echo $SINRR) * 2) -20))" dB"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
QRSRP=$(echo "$OX" | grep -o "+QRSRP:[^,]\+,-[0-9]\{1,5\},-[0-9]\{1,5\},-[0-9]\{1,5\}[^ ]*")
|
|
||||||
if [ -n "$QRSRP" ] && [ "$RAT" != "WCDMA" ]; then
|
|
||||||
QRSRP1=$(echo $QRSRP | cut -d, -f1 | grep -o "[-0-9]\+")
|
|
||||||
QRSRP2=$(echo $QRSRP | cut -d, -f2)
|
|
||||||
QRSRP3=$(echo $QRSRP | cut -d, -f3)
|
|
||||||
QRSRP4=$(echo $QRSRP | cut -d, -f4)
|
|
||||||
QRSRPtype=$(echo $QRSRP | cut -d, -f5)
|
|
||||||
if [ "$QRSRPtype" == "NR5G" ]; then
|
|
||||||
if [ -n "$NR_SA" ]; then
|
|
||||||
RSCP=$QRSRP1
|
|
||||||
if [ -n "$QRSRP2" -a "$QRSRP2" != "-32768" ]; then
|
|
||||||
RSCP1="RxD "$QRSRP2
|
|
||||||
fi
|
|
||||||
if [ -n "$QRSRP3" -a "$QRSRP3" != "-32768" -a "$QRSRP3" != "-44" ]; then
|
|
||||||
RSCP=$RSCP" dBm<br />"$QRSRP3
|
|
||||||
fi
|
|
||||||
if [ -n "$QRSRP4" -a "$QRSRP4" != "-32768" -a "$QRSRP4" != "-44" ]; then
|
|
||||||
RSCP1="RxD "$QRSRP4
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
RSCP=$RSRPLTE
|
|
||||||
if [ -n "$QRSRP1" -a "$QRSRP1" != "-32768" -a "$QRSRP1" != "-44" ]; then
|
|
||||||
RSCP=$RSCP" (4G) dBm<br />"$QRSRP1
|
|
||||||
if [ -n "$QRSRP2" -a "$QRSRP2" != "-32768" -a "$QRSRP2" != "-44" ]; then
|
|
||||||
RSCP="$RSCP, $QRSRP2"
|
|
||||||
if [ -n "$QRSRP3" -a "$QRSRP3" != "-32768" -a "$QRSRP3" != "-44" ]; then
|
|
||||||
RSCP="$RSCP, $QRSRP3"
|
|
||||||
if [ -n "$QRSRP4" -a "$QRSRP4" != "-32768" -a "$QRSRP4" != "-44" ]; then
|
|
||||||
RSCP="$RSCP, $QRSRP4"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
RSCP=$RSCP" (5G) "
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif [ "$QRSRP2$QRSRP3$QRSRP4" != "-44-44-44" -a -z "$QENG5" ]; then
|
|
||||||
RSCP=$QRSRP1
|
|
||||||
if [ "$QRSRP3$QRSRP4" == "-140-140" -o "$QRSRP3$QRSRP4" == "-44-44" -o "$QRSRP3$QRSRP4" == "-32768-32768" ]; then
|
|
||||||
RSCP1="RxD "$(echo $QRSRP | cut -d, -f2)
|
|
||||||
else
|
|
||||||
RSCP=$RSCP" dBm (RxD "$QRSRP2" dBm)<br />"$QRSRP3
|
|
||||||
RSCP1="RxD "$QRSRP4
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
QNSM=$(echo "$QNSM" | grep -o "[0-9]")
|
|
||||||
if [ -n "$QNSM" ]; then
|
|
||||||
MODTYPE="6"
|
|
||||||
case $QNSM in
|
|
||||||
"0" )
|
|
||||||
NETMODE="1" ;;
|
|
||||||
"1" )
|
|
||||||
NETMODE="3" ;;
|
|
||||||
"2"|"5" )
|
|
||||||
NETMODE="5" ;;
|
|
||||||
"3" )
|
|
||||||
NETMODE="7" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
if [ -n "$QNWP" ]; then
|
|
||||||
MODTYPE="6"
|
|
||||||
case $QNWP in
|
|
||||||
"AUTO" )
|
|
||||||
NETMODE="1" ;;
|
|
||||||
"WCDMA" )
|
|
||||||
NETMODE="5" ;;
|
|
||||||
"LTE" )
|
|
||||||
NETMODE="7" ;;
|
|
||||||
"LTE:NR5G" )
|
|
||||||
NETMODE="8" ;;
|
|
||||||
"NR5G" )
|
|
||||||
NETMODE="9" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
OX=$(echo "${OX//[ \"]/}")
|
|
||||||
|
|
||||||
REGV=$(echo "$OX" | grep -o "+C5GREG:2,[0-9],[A-F0-9]\{2,6\},[A-F0-9]\{5,10\},[0-9]\{1,2\}")
|
|
||||||
if [ -n "$REGV" ]; then
|
|
||||||
LAC5=$(echo "$REGV" | cut -d, -f3)
|
|
||||||
LAC5=$LAC5" ($(printf "%d" 0x$LAC5))"
|
|
||||||
CID5=$(echo "$REGV" | cut -d, -f4)
|
|
||||||
CID5L=$(printf "%010X" 0x$CID5)
|
|
||||||
RNC5=${CID5L:1:6}
|
|
||||||
RNC5=$RNC5" ($(printf "%d" 0x$RNC5))"
|
|
||||||
CID5=${CID5L:7:3}
|
|
||||||
CID5="Short $(printf "%X" 0x$CID5) ($(printf "%d" 0x$CID5)), Long $(printf "%X" 0x$CID5L) ($(printf "%d" 0x$CID5L))"
|
|
||||||
RAT=$(echo "$REGV" | cut -d, -f5)
|
|
||||||
fi
|
|
||||||
REGV=$(echo "$OX" | grep -o "+CEREG:2,[0-9],[A-F0-9]\{2,4\},[A-F0-9]\{5,8\}")
|
|
||||||
REGFMT="3GPP"
|
|
||||||
if [ -z "$REGV" ]; then
|
|
||||||
REGV=$(echo "$OX" | grep -o "+CEREG:2,[0-9],[A-F0-9]\{2,4\},[A-F0-9]\{1,3\},[A-F0-9]\{5,8\}")
|
|
||||||
REGFMT="SW"
|
|
||||||
fi
|
|
||||||
if [ -n "$REGV" ]; then
|
|
||||||
LAC=$(echo "$REGV" | cut -d, -f3)
|
|
||||||
LAC=$(printf "%04X" 0x$LAC)" ($(printf "%d" 0x$LAC))"
|
|
||||||
if [ $REGFMT = "3GPP" ]; then
|
|
||||||
CID=$(echo "$REGV" | cut -d, -f4)
|
|
||||||
else
|
|
||||||
CID=$(echo "$REGV" | cut -d, -f5)
|
|
||||||
fi
|
|
||||||
CIDL=$(printf "%08X" 0x$CID)
|
|
||||||
RNC=${CIDL:1:5}
|
|
||||||
RNC=$RNC" ($(printf "%d" 0x$RNC))"
|
|
||||||
CID=${CIDL:6:2}
|
|
||||||
CID="Short $(printf "%X" 0x$CID) ($(printf "%d" 0x$CID)), Long $(printf "%X" 0x$CIDL) ($(printf "%d" 0x$CIDL))"
|
|
||||||
|
|
||||||
else
|
|
||||||
REGV=$(echo "$OX" | grep -o "+CREG:2,[0-9],[A-F0-9]\{2,4\},[A-F0-9]\{2,8\}")
|
|
||||||
if [ -n "$REGV" ]; then
|
|
||||||
LAC=$(echo "$REGV" | cut -d, -f3)
|
|
||||||
CID=$(echo "$REGV" | cut -d, -f4)
|
|
||||||
if [ ${#CID} -gt 4 ]; then
|
|
||||||
LAC=$(printf "%04X" 0x$LAC)" ($(printf "%d" 0x$LAC))"
|
|
||||||
CIDL=$(printf "%08X" 0x$CID)
|
|
||||||
RNC=${CIDL:1:3}
|
|
||||||
CID=${CIDL:4:4}
|
|
||||||
CID="Short $(printf "%X" 0x$CID) ($(printf "%d" 0x$CID)), Long $(printf "%X" 0x$CIDL) ($(printf "%d" 0x$CIDL))"
|
|
||||||
else
|
|
||||||
LAC=""
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
LAC=""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
REGSTAT=$(echo "$REGV" | cut -d, -f2)
|
|
||||||
if [ "$REGSTAT" == "5" -a "$COPS" != "-" ]; then
|
|
||||||
COPS_MNC=$COPS_MNC" (Roaming)"
|
|
||||||
fi
|
|
||||||
if [ -n "$CID" -a -n "$CID5" ] && [ "$RAT" == "13" -o "$RAT" == "10" ]; then
|
|
||||||
LAC="4G $LAC, 5G $LAC5"
|
|
||||||
CID="4G $CID<br />5G $CID5"
|
|
||||||
RNC="4G $RNC, 5G $RNC5"
|
|
||||||
elif [ -n "$CID5" ]; then
|
|
||||||
LAC=$LAC5
|
|
||||||
CID=$CID5
|
|
||||||
RNC=$RNC5
|
|
||||||
fi
|
|
||||||
if [ -z "$LAC" ]; then
|
|
||||||
LAC="-"
|
|
||||||
CID="-"
|
|
||||||
RNC="-"
|
|
||||||
fi
|
|
||||||
|
|
||||||
LUPDATE=$(date +%s)
|
|
||||||
rm -fR /tmp/signal.txt
|
|
||||||
MODEZ=$(echo $MODE | tr -d '"')
|
|
||||||
{
|
|
||||||
echo 'PROVIDER="'"$PROVIDER"'"'
|
|
||||||
echo 'CSQ="'"$CSQ"'"'
|
|
||||||
echo 'CSQ_PER="'"$CSQ_PER"'"'
|
|
||||||
echo 'CSQ_RSSI="'"$CSQ_RSSI"'"'
|
|
||||||
echo 'ECIO="'"$ECIO"'"'
|
|
||||||
echo 'RSCP="'"$RSCP"'"'
|
|
||||||
echo 'ECIO1="'"$ECIO1"'"'
|
|
||||||
echo 'RSCP1="'"$RSCP1"'"'
|
|
||||||
echo 'MODE="'"$MODEZ"'"'
|
|
||||||
echo 'MODTYPE="'"$MODTYPE"'"'
|
|
||||||
echo 'NETMODE="'"$NETMODE"'"'
|
|
||||||
echo 'CHANNEL="'"$CHANNEL"'"'
|
|
||||||
echo 'LBAND="'"$LBAND"'"'
|
|
||||||
echo 'PC_BAND="'"$PC_BAND"'"'
|
|
||||||
echo 'SC_BANDS="'"$SC_BANDS"'"'
|
|
||||||
echo 'APN="'"$APN"'"'
|
|
||||||
echo 'MODEM_MODEL="'"$MODEM_MODEL"'"'
|
|
||||||
echo 'SIMSLOT="'"$SIMSLOT"'"'
|
|
||||||
echo 'PCI="'"$PCI"'"'
|
|
||||||
echo 'TEMP="'"$CTEMP"'"'
|
|
||||||
echo 'SINR="'"$SINR"'"'
|
|
||||||
echo 'LASTUPDATE="'"$LUPDATE"'"'
|
|
||||||
echo 'COPS="'"$COPS"'"'
|
|
||||||
echo 'COPS_MCC="'"$COPS_MCC"'"'
|
|
||||||
echo 'COPS_MNC="'"$COPS_MNC"'"'
|
|
||||||
echo 'MCCMNC="'"$MCCMNC"'"'
|
|
||||||
echo 'LAC="'"$LAC"'"'
|
|
||||||
echo 'LAC_NUM="'""'"'
|
|
||||||
echo 'CID="'"$CID"'"'
|
|
||||||
echo 'CID_NUM="'""'"'
|
|
||||||
echo 'RNC="'"$RNC"'"'
|
|
||||||
echo 'RNC_NUM="'""'"'
|
|
||||||
} > /tmp/signal.txt
|
|
||||||
|
|
||||||
# Pregenerate JSON File
|
|
||||||
/usrdata/simpleadmin/scripts/tojson.sh /tmp/signal.txt > /tmp/modemstatus.json
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# sarav (hello@grity.com)
|
|
||||||
# convert key=value to json
|
|
||||||
# Created at Gritfy ( Devops Junction )
|
|
||||||
# Updated by: dr-dolomite to make it more robust since it was failing on some casess
|
|
||||||
|
|
||||||
file_name="$1"
|
|
||||||
|
|
||||||
echo "{"
|
|
||||||
last_line=$(wc -l < "$file_name")
|
|
||||||
first_line=true
|
|
||||||
|
|
||||||
while IFS='=' read -r key value || [[ -n "$key" ]]; do
|
|
||||||
# Skip empty lines and comments
|
|
||||||
if [[ -z "$key" || "$key" == \#* ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Trim leading and trailing whitespace from key and value
|
|
||||||
key=$(echo "$key" | awk '{$1=$1};1')
|
|
||||||
value=$(echo "$value" | awk '{$1=$1};1')
|
|
||||||
|
|
||||||
# Check if value includes double quotes inside it like: "value,"value"". If there is, remove the inner double quotes.
|
|
||||||
if [[ "$value" == *\"* ]]; then
|
|
||||||
value=$(echo "$value" | sed 's/\"//g')
|
|
||||||
# enclose the value in double quotes again
|
|
||||||
value="\"$value\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if value is empty, if so, skip printing this key-value pair
|
|
||||||
if [[ -z "$value" ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print comma before each pair except for the first one
|
|
||||||
if $first_line; then
|
|
||||||
first_line=false
|
|
||||||
else
|
|
||||||
printf ','
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print key-value pair in JSON format without surrounding double quotes on value
|
|
||||||
printf ' "%s" : %s' "$key" "$value"
|
|
||||||
|
|
||||||
printf '\n'
|
|
||||||
done < "$file_name"
|
|
||||||
|
|
||||||
echo "}"
|
|
||||||
5
simpleadmin/simplepasswd
Normal file
5
simpleadmin/simplepasswd
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#/bin/bash
|
||||||
|
|
||||||
|
echo -e "\e[1;31mPlease set your simpleadmin (User: admin) web login password.\e[0m"
|
||||||
|
/usrdata/root/bin/htpasswd -c /opt/etc/.htpasswd admin
|
||||||
|
echo -e "\e[1;32mPassword set.\e[0m"
|
||||||
14
simpleadmin/systemd/lighttpd.service
Normal file
14
simpleadmin/systemd/lighttpd.service
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Lighttpd Daemon
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
PIDFile=/opt/var/run/lighttpd.pid
|
||||||
|
ExecStartPre=/opt/sbin/lighttpd -tt -f /usrdata/simpleadmin/lighttpd.conf
|
||||||
|
ExecStart=/opt/sbin/lighttpd -D -f /usrdata/simpleadmin/lighttpd.conf
|
||||||
|
ExecReload=/bin/kill -USR1 $MAINPID
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Simpleadmin service to generate status from modem
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/usrdata/simpleadmin/scripts/build_modem_status
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=SimpleAdmin httpd service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
ExecStart=/usr/sbin/httpd -f -h /usrdata/simpleadmin/www -p 8080
|
|
||||||
ExecStop=/bin/kill -WINCH ${MAINPID}
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
12
simpleadmin/systemd/ttyd.service
Normal file
12
simpleadmin/systemd/ttyd.service
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=TTYD Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStartPre=/bin/sleep 5
|
||||||
|
ExecStart=/usrdata/simpleadmin/ttyd -i 127.0.0.1 -p 8080 -t 'theme={"foreground":"white","background":"black"}' -t fontSize=25 --writable /usrdata/simpleadmin/console/ttyd.bash
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -1,303 +0,0 @@
|
|||||||
<!-- !Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc. -->
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<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>RM5xxx AT Commands</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" />
|
|
||||||
</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"> AT Commands </a>
|
|
||||||
<a class="navbar-item" href="/sms.html"> SMS </a>
|
|
||||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<!-- END NAV -->
|
|
||||||
<div class="container" x-data="atCommands()">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-12">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="card">
|
|
||||||
<header class="card-header">
|
|
||||||
<p class="card-header-title">AT Command</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="content">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label">AT Command</label>
|
|
||||||
<div class="control">
|
|
||||||
<input
|
|
||||||
class="input"
|
|
||||||
type="text"
|
|
||||||
placeholder="ATI"
|
|
||||||
x-model="atcmd"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<p class="control">
|
|
||||||
<button
|
|
||||||
class="button is-success"
|
|
||||||
@click="sendAtCommand()"
|
|
||||||
:disabled="isLoading"
|
|
||||||
>
|
|
||||||
Send AT Command
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="button is-danger"
|
|
||||||
@click="clearResponses()"
|
|
||||||
:disabled="atCommandResponse === ''"
|
|
||||||
>
|
|
||||||
Clear
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-8">
|
|
||||||
<div class="card">
|
|
||||||
<header class="card-header">
|
|
||||||
<p class="card-header-title">ATI Response</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="content">
|
|
||||||
<textarea
|
|
||||||
class="textarea"
|
|
||||||
placeholder="Please send only 1 AT command at a time"
|
|
||||||
rows="10"
|
|
||||||
x-text="isLoading ? 'Fetching response, please wait...' : atCommandResponse"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- START Useful Commands Section -->
|
|
||||||
<div class="container">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-12">
|
|
||||||
<div class="card">
|
|
||||||
<header class="card-header">
|
|
||||||
<p class="card-header-title">Useful Commands</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="content">
|
|
||||||
<!-- <div class="field" style="margin-bottom: 1rem">
|
|
||||||
<p class="control">
|
|
||||||
<button
|
|
||||||
class="button is-danger"
|
|
||||||
click="sendRebootCommand()"
|
|
||||||
:disabled="isRebootClicked"
|
|
||||||
|
|
||||||
>
|
|
||||||
Reboot
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div> -->
|
|
||||||
<!-- Add your useful commands content here -->
|
|
||||||
<p>Here are some useful commands:</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
See https://github.com/iamromulan/RM520N-GL#at-commands 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>
|
|
||||||
</div>
|
|
||||||
<!-- END Useful Commands Section -->
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function atCommands() {
|
|
||||||
return {
|
|
||||||
isLoading: false,
|
|
||||||
atcmd: null,
|
|
||||||
atCommandResponse: "",
|
|
||||||
sendAtCommand() {
|
|
||||||
this.isLoading = true;
|
|
||||||
fetch(
|
|
||||||
"/cgi-bin/get_atcommand?" +
|
|
||||||
new URLSearchParams({
|
|
||||||
atcmd: this.atcmd,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
return res.text();
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
this.atCommandResponse = data;
|
|
||||||
this.isLoading = false;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.isLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
clearResponses() {
|
|
||||||
this.atCommandResponse = "";
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendRebootCommand() {
|
|
||||||
var isRebootClicked = true;
|
|
||||||
console.log("Reboot command triggered");
|
|
||||||
var atcmd = "AT+CFUN=1,1";
|
|
||||||
fetch(
|
|
||||||
"/cgi-bin/get_atcommand?" +
|
|
||||||
new URLSearchParams({
|
|
||||||
atcmd: atcmd,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
return res.text();
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
console.log(data); // Logging the response for debugging purposes
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Error:", error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -16,8 +16,8 @@ fi
|
|||||||
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
|
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
|
||||||
if [ -n "${MYATCMD}" ]; then
|
if [ -n "${MYATCMD}" ]; then
|
||||||
x=$(urldecode "$atcmd")
|
x=$(urldecode "$atcmd")
|
||||||
# Initialize wait time to 2 seconds
|
# Initialize wait time to 1 second
|
||||||
wait_time=2
|
wait_time=1000
|
||||||
while true; do
|
while true; do
|
||||||
runcmd=$(echo -en "$x\r\n" | microcom -t $wait_time /dev/ttyOUT2)
|
runcmd=$(echo -en "$x\r\n" | microcom -t $wait_time /dev/ttyOUT2)
|
||||||
# Check if "OK" or "ERROR" is present in the response
|
# Check if "OK" or "ERROR" is present in the response
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ ! -f /tmp/modemstatus.json ]
|
|
||||||
then
|
|
||||||
/usrdata/simpleadmin/scripts/modemstatus_parse.sh > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
runcmd=$(</tmp/modemstatus.json)
|
|
||||||
|
|
||||||
echo "Content-type: text/json"
|
|
||||||
echo ""
|
|
||||||
cat <<EOT
|
|
||||||
$runcmd
|
|
||||||
19
simpleadmin/www/cgi-bin/get_ping
Normal file
19
simpleadmin/www/cgi-bin/get_ping
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script will ping 8.8.8.8 and return the result
|
||||||
|
# If the ping is successful, it will return "OK"
|
||||||
|
# If the ping fails, it will return "ERROR"
|
||||||
|
|
||||||
|
# Send the ping command and store the output
|
||||||
|
ping_output=$(ping -c 1 8.8.8.8)
|
||||||
|
|
||||||
|
# Check if the output contains "0% packet loss"
|
||||||
|
if echo "$ping_output" | grep -q "0% packet loss"; then
|
||||||
|
echo "Content-type: text/plain"
|
||||||
|
echo ""
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Content-type: text/plain"
|
||||||
|
echo ""
|
||||||
|
echo "ERROR"
|
||||||
|
fi
|
||||||
20
simpleadmin/www/cgi-bin/get_sms
Normal file
20
simpleadmin/www/cgi-bin/get_sms
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This is a simple scrip that fetches the SMS messages from the device
|
||||||
|
SMS_MESSAGE_INDICATION="AT+CNMI=2,1"
|
||||||
|
SMS_FORMAT="AT+CMGF=1"
|
||||||
|
SMS_LIST="AT+CMGL=\"ALL\""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
runcmd=$(echo -en "$SMS_LIST\r\n" | microcom -t 2000 /dev/ttyOUT2)
|
||||||
|
if [[ $runcmd =~ "OK" ]] || [[ $runcmd =~ "ERROR" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
((wait_time++))
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Print the list of SMS messages as JSON plain text
|
||||||
|
echo "Content-type: text/plain"
|
||||||
|
echo ""
|
||||||
|
echo $runcmd
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Check iptables for ttlvalue
|
# Check iptables for ttlvalue
|
||||||
ttlvalue=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
|
ttlvalue=$(/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -vnL | grep TTL | awk '{print $13}' | head -n1)
|
||||||
ttlenabled=true;
|
ttlenabled=true;
|
||||||
|
|
||||||
# Set Variables
|
# Set Variables
|
||||||
@@ -16,4 +16,5 @@ cat <<EOT
|
|||||||
{
|
{
|
||||||
"isEnabled": $ttlenabled,
|
"isEnabled": $ttlenabled,
|
||||||
"ttl": $ttlvalue
|
"ttl": $ttlvalue
|
||||||
}
|
}
|
||||||
|
EOT
|
||||||
|
|||||||
44
simpleadmin/www/cgi-bin/send_sms
Normal file
44
simpleadmin/www/cgi-bin/send_sms
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||||
|
function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
|
||||||
|
|
||||||
|
if [ "${QUERY_STRING}" ]; then
|
||||||
|
export IFS="&"
|
||||||
|
for cmd in ${QUERY_STRING}; do
|
||||||
|
if [ "$(echo $cmd | grep '=')" ]; then
|
||||||
|
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||||
|
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||||
|
eval $key=$value
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract phone number and message from inputs
|
||||||
|
phone_number="$number"
|
||||||
|
message="$msg"
|
||||||
|
|
||||||
|
# Prepare AT command with phone number and message
|
||||||
|
ATCMD="AT+CMGS=\"$phone_number\""
|
||||||
|
|
||||||
|
MYATCMD=$(printf '%b\n' "${ATCMD//%/\\x}")
|
||||||
|
if [ -n "${MYATCMD}" ]; then
|
||||||
|
x=$(urldecode "$ATCMD")
|
||||||
|
# Send the AT command to initiate message sending
|
||||||
|
echo -en "$x\r\n" | microcom /dev/ttyOUT2
|
||||||
|
# Wait for a brief moment (assuming the message sending is instantaneous)
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Send the message
|
||||||
|
echo -en "$message\c"
|
||||||
|
|
||||||
|
# Send Ctrl+Z to terminate the message
|
||||||
|
echo -en "\032"
|
||||||
|
|
||||||
|
# Ensure microcom reads the response (assuming microcom will show response instantly)
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# Capture and output the response
|
||||||
|
runcmd=$(microcom /dev/ttyOUT2)
|
||||||
|
echo "Content-type: text/plain"
|
||||||
|
echo "$runcmd"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin
|
||||||
# Get query
|
# Get query
|
||||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||||
|
|
||||||
@@ -22,28 +22,28 @@ setTTL=$(printf '%b\n' "${ttlvalue//%/\\x}")
|
|||||||
|
|
||||||
if [ -n "${setTTL}" ]; then
|
if [ -n "${setTTL}" ]; then
|
||||||
# Stop Service To Remove Rules
|
# Stop Service To Remove Rules
|
||||||
/usrdata/simplefirewall/ttl-override stop
|
/opt/bin/sudo /usrdata/simplefirewall/ttl-override stop
|
||||||
|
|
||||||
# Check iptables is still set
|
# Check iptables is still set
|
||||||
ttlcheck=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
|
ttlcheck=$(/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||||
|
|
||||||
# If TTL is still set manually remove values
|
# If TTL is still set manually remove values
|
||||||
if [ !-z "${ttlcheck}" ]; then
|
if [ ! -z "${ttlcheck}" ]; then
|
||||||
iptables -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set ${ttlcheck} &>/dev/null || true
|
/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set ${ttlcheck} &>/dev/null || true
|
||||||
ip6tables -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set ${ttlcheck} &>/dev/null || true
|
/opt/bin/sudo /usr/sbin/ip6tables -w 5 -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set ${ttlcheck} &>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Echo TTL to file
|
# Echo TTL to file
|
||||||
echo $setTTL > /usrdata/simplefirewall/ttlvalue
|
echo $setTTL > /usrdata/simplefirewall/ttlvalue
|
||||||
|
|
||||||
# Set Start Service
|
# Set Start Service
|
||||||
/usrdata/simplefirewall/ttl-override start
|
/opt/bin/sudo /usrdata/simplefirewall/ttl-override start
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check iptables for ttlvalue
|
# Check iptables for ttlvalue
|
||||||
ttlvalue=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
|
ttlvalue=$(/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||||
ttlenabled=true;
|
ttlenabled=true;
|
||||||
|
|
||||||
# Set Variables
|
# Set Variables
|
||||||
@@ -58,4 +58,5 @@ cat <<EOT
|
|||||||
{
|
{
|
||||||
"isEnabled": $ttlenabled,
|
"isEnabled": $ttlenabled,
|
||||||
"ttl": $ttlvalue
|
"ttl": $ttlvalue
|
||||||
}
|
}
|
||||||
|
EOT
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
:root{
|
|
||||||
::-webkit-scrollbar{height:10px;width:10px}::-webkit-scrollbar-track{background:#efefef;border-radius:6px}::-webkit-scrollbar-thumb{background:#d5d5d5;border-radius:6px}::-webkit-scrollbar-thumb:hover{background:#c4c4c4}
|
|
||||||
}
|
|
||||||
html, body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 1.5;
|
|
||||||
height: 100%;
|
|
||||||
background: #ECF0F3;
|
|
||||||
}
|
|
||||||
nav.navbar {
|
|
||||||
border-top: 4px solid #276cda;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
.navbar-item.brand-text {
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
.navbar-item, .navbar-link {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.columns {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
.menu-label {
|
|
||||||
color: #8F99A3;
|
|
||||||
letter-spacing: 1.3;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.menu-list a {
|
|
||||||
color: #0F1D38;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.menu-list a:hover {
|
|
||||||
background-color: transparent;
|
|
||||||
color: #276cda;
|
|
||||||
}
|
|
||||||
.menu-list a.is-active {
|
|
||||||
background-color: transparent;
|
|
||||||
color: #276cda;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.18);
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
.card-header-title {
|
|
||||||
color: #8F99A3;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
.info-tiles {
|
|
||||||
margin: 1rem 0;
|
|
||||||
}
|
|
||||||
.info-tiles .subtitle {
|
|
||||||
font-weight: 300;
|
|
||||||
color: #8F99A3;
|
|
||||||
}
|
|
||||||
.hero.welcome.is-info {
|
|
||||||
background: #36D1DC;
|
|
||||||
background: -webkit-linear-gradient(to right, #5B86E5, #36D1DC);
|
|
||||||
background: linear-gradient(to right, #5B86E5, #36D1DC);
|
|
||||||
}
|
|
||||||
.hero.welcome .title, .hero.welcome .subtitle {
|
|
||||||
color: hsl(192, 17%, 99%);
|
|
||||||
}
|
|
||||||
.card .content {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.card-footer-item {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #8F99A3;
|
|
||||||
}
|
|
||||||
.card-footer-item:hover {
|
|
||||||
}
|
|
||||||
.card-table .table {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.events-card .card-table {
|
|
||||||
height: 330px;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
6
simpleadmin/www/css/bootstrap.min.css
vendored
Normal file
6
simpleadmin/www/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
simpleadmin/www/css/bulma.css
vendored
1
simpleadmin/www/css/bulma.css
vendored
File diff suppressed because one or more lines are too long
95
simpleadmin/www/css/styles.css
Normal file
95
simpleadmin/www/css/styles.css
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* import poppins */
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap");
|
||||||
|
|
||||||
|
/* import fontawesome icons */
|
||||||
|
@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css");
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: "Poppins", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox .form-check-input {
|
||||||
|
margin-right: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-modal {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border: 3px dotted #000;
|
||||||
|
border-style: solid solid dotted dotted;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: rotation 2s linear infinite;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader::after {
|
||||||
|
content: "";
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
border: 3px dotted #0b5ed7;
|
||||||
|
border-style: solid solid dotted;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: rotationBack 1s linear infinite;
|
||||||
|
transform-origin: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes rotationBack {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(-360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-warning {
|
||||||
|
background-color: #ffb70f !important;
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-medium {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
357
simpleadmin/www/deviceinfo.html
Normal file
357
simpleadmin/www/deviceinfo.html
Normal file
@@ -0,0 +1,357 @@
|
|||||||
|
<!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>Simple Admin</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" />
|
||||||
|
|
||||||
|
<!-- 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="fetchDeviceInfo()">
|
||||||
|
<nav class="navbar navbar-expand-lg mt-2">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="/"
|
||||||
|
><span class="mb-0 h4">Simple Admin</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="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/settings.html">Simple Settings</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/sms.html">SMS</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/console">Console</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" href="/deviceinfo.html" aria-current="page" >Device Information</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link text-reset" id="darkModeToggle">Dark Mode</button>
|
||||||
|
</span>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link" href="logout.html">Log Out</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="row mt-5 gap-3">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Device Information</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-text">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Manufacturer</th>
|
||||||
|
<td x-text="manufacturer"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Model Name</th>
|
||||||
|
<td x-text="modelName"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Firmware version</th>
|
||||||
|
<td class="col-md-2" x-text="firmwareVersion"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">IMSI</th>
|
||||||
|
<td class="col-md-2" x-text="imsi"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">ICCID</th>
|
||||||
|
<td class="col-md-2" x-text="iccid"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">IMEI</th>
|
||||||
|
<td class="col-md-2">
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
type="text"
|
||||||
|
x-model="newImei"
|
||||||
|
x-bind:placeholder="imei === '-' ? 'Fetching IMEI...' : imei"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="openModal()"
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th scope="row">LAN IP</th>
|
||||||
|
<td class="col-md-2" x-text="lanIp"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">WWAN IPv<sup>4</sup></th>
|
||||||
|
<td class="col-md-2" x-text="wwanIpv4"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">WWAN IPv<sup>6</sup></th>
|
||||||
|
<td class="col-md-2" x-text="wwanIpv6"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Simple Admin Version</th>
|
||||||
|
<td class="col-md-2">SimpleAdminRev-Alpha-0.3</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
Visit our
|
||||||
|
<a
|
||||||
|
href="https://github.com/iamromulan/quectel-rgmii-toolkit.gits"
|
||||||
|
target="_blank"
|
||||||
|
class="text-reset"
|
||||||
|
>repository</a
|
||||||
|
>
|
||||||
|
or
|
||||||
|
<a
|
||||||
|
href="https://github.com/iamromulan/quectel-rgmii-configuration-notes.git"
|
||||||
|
target="_blank"
|
||||||
|
class="text-reset"
|
||||||
|
>documentation</a
|
||||||
|
>
|
||||||
|
for more information. All rights reserved. 2024
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Loading Modal for Reboot -->
|
||||||
|
<div class="modal-overlay" x-show="showModal">
|
||||||
|
<div class="loading-modal">
|
||||||
|
<div
|
||||||
|
class="loading-text"
|
||||||
|
style="display: flex; flex-direction: column"
|
||||||
|
>
|
||||||
|
<h3>This will reboot the modem.</h3>
|
||||||
|
<p style="margin-top: 0.5rem">Continue?</p>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid gap-2 d-md-block">
|
||||||
|
<button
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
@click="updateIMEI()"
|
||||||
|
>
|
||||||
|
Reboot
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-danger"
|
||||||
|
type="button"
|
||||||
|
@click="closeModal()"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Reboot Modal Countdown -->
|
||||||
|
<div class="modal-overlay" x-show="isRebooting">
|
||||||
|
<div class="loading-modal">
|
||||||
|
<div class="loader"></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.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<script src="/js/dark-mode.js"></script>
|
||||||
|
<script>
|
||||||
|
function fetchDeviceInfo() {
|
||||||
|
return {
|
||||||
|
manufacturer: "-",
|
||||||
|
modelName: "-",
|
||||||
|
firmwareVersion: "-",
|
||||||
|
imsi: "-",
|
||||||
|
iccid: "-",
|
||||||
|
imei: "-",
|
||||||
|
newImei: null,
|
||||||
|
lanIp: "-",
|
||||||
|
wwanIpv4: "-",
|
||||||
|
wwanIpv6: "-",
|
||||||
|
simpleAdminVersion: "-",
|
||||||
|
atcmd: null,
|
||||||
|
atCommandResponse: "",
|
||||||
|
showModal: false,
|
||||||
|
isLoading: false,
|
||||||
|
isRebooting: false,
|
||||||
|
countdown: 3,
|
||||||
|
|
||||||
|
sendATCommand() {
|
||||||
|
if (!this.atcmd) {
|
||||||
|
// Use ATI as default command
|
||||||
|
console.log(
|
||||||
|
"AT Command is empty, using ATI as default command: "
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = true;
|
||||||
|
fetch(
|
||||||
|
"/cgi-bin/get_atcommand?" +
|
||||||
|
new URLSearchParams({
|
||||||
|
atcmd: this.atcmd,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
return res.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.atCommandResponse = data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error: ", error);
|
||||||
|
this.showError = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchATCommand() {
|
||||||
|
this.atcmd =
|
||||||
|
'AT+CGMI;+CGMM;+QGMR;+CIMI;+ICCID;+CGSN;+QMAP="LANIP";+QMAP="WWAN"';
|
||||||
|
this.isLoading = true;
|
||||||
|
fetch(
|
||||||
|
"/cgi-bin/get_atcommand?" +
|
||||||
|
new URLSearchParams({
|
||||||
|
atcmd: this.atcmd,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
return res.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.atCommandResponse = data;
|
||||||
|
this.parseFetchedData();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error: ", error);
|
||||||
|
this.showError = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
parseFetchedData() {
|
||||||
|
const lines = this.atCommandResponse.split("\n");
|
||||||
|
|
||||||
|
console.log("AT Command Response: ", lines);
|
||||||
|
|
||||||
|
this.manufacturer = lines[1].trim();
|
||||||
|
this.modelName = lines[3].trim();
|
||||||
|
this.firmwareVersion = lines[5].trim();
|
||||||
|
this.imsi = lines[7].trim();
|
||||||
|
this.iccid = lines[9].trim().replace("+ICCID: ", "");
|
||||||
|
this.imei = lines[11].trim();
|
||||||
|
this.lanIp = lines[13].trim().split(",")[3];
|
||||||
|
this.wwanIpv4 = lines[15].trim().split(",")[4].replace(/"/g, "");
|
||||||
|
this.wwanIpv6 = lines[16].trim().split(",")[4].replace(/"/g, "");
|
||||||
|
this.simpleAdminVersion = "SimpleAdminRev-Alpha-0.5";
|
||||||
|
this.isLoading = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateIMEI() {
|
||||||
|
this.atcmd = `AT+EGMR=1,7,"${this.newImei}"`;
|
||||||
|
this.sendATCommand();
|
||||||
|
this.rebootDevice();
|
||||||
|
},
|
||||||
|
|
||||||
|
rebootDevice() {
|
||||||
|
this.atcmd = "AT+CFUN=1,1";
|
||||||
|
this.sendATCommand();
|
||||||
|
|
||||||
|
this.isLoading = true;
|
||||||
|
this.showModal = false;
|
||||||
|
this.isRebooting = true;
|
||||||
|
this.countdown = 40;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
this.countdown--;
|
||||||
|
if (this.countdown === 0) {
|
||||||
|
clearInterval(interval);
|
||||||
|
this.isLoading = false;
|
||||||
|
this.showModal = false;
|
||||||
|
this.isRebooting = false;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
openModal() {
|
||||||
|
if (!this.newImei) {
|
||||||
|
alert("No new IMEI provided.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.newImei.length !== 15) {
|
||||||
|
alert("IMEI is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.newImei === this.imei) {
|
||||||
|
alert("IMEI is the same as the current IMEI");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showModal = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
closeModal() {
|
||||||
|
this.showModal = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.fetchATCommand();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File diff suppressed because it is too large
Load Diff
7
simpleadmin/www/js/bootstrap.bundle.min.js
vendored
Normal file
7
simpleadmin/www/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
29
simpleadmin/www/js/dark-mode.js
Normal file
29
simpleadmin/www/js/dark-mode.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Function to toggle dark mode
|
||||||
|
const toggleDarkMode = () => {
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
const currentTheme = html.getAttribute('data-bs-theme');
|
||||||
|
|
||||||
|
if (currentTheme === 'dark') {
|
||||||
|
html.removeAttribute('data-bs-theme');
|
||||||
|
darkModeToggle.textContent = 'Dark Mode';
|
||||||
|
localStorage.setItem('theme', 'light'); // Store the theme in localStorage
|
||||||
|
} else {
|
||||||
|
html.setAttribute('data-bs-theme', 'dark');
|
||||||
|
darkModeToggle.textContent = 'Light Mode';
|
||||||
|
localStorage.setItem('theme', 'dark'); // Store the theme in localStorage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const darkModeToggle = document.getElementById('darkModeToggle');
|
||||||
|
|
||||||
|
// Check if theme preference is stored in localStorage
|
||||||
|
const storedTheme = localStorage.getItem('theme');
|
||||||
|
if (storedTheme) {
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
html.setAttribute('data-bs-theme', storedTheme);
|
||||||
|
if (storedTheme === 'dark') {
|
||||||
|
darkModeToggle.textContent = 'Light Mode';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
darkModeToggle.addEventListener('click', toggleDarkMode);
|
||||||
37
simpleadmin/www/js/generate-freq-box.js
Normal file
37
simpleadmin/www/js/generate-freq-box.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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 class="input-group mb-3" x-show="cellNum >= ${i} && networkModeCell == 'LTE'">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
aria-label="EARFCN"
|
||||||
|
placeholder="EARFCN"
|
||||||
|
class="form-control"
|
||||||
|
x-model="earfcn${i}"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
aria-label="PCI"
|
||||||
|
placeholder="PCI"
|
||||||
|
class="form-control"
|
||||||
|
x-model="pci${i}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const cellNumInput = document.querySelector("[aria-label='NumCells']");
|
||||||
|
cellNumInput.addEventListener("input", function () {
|
||||||
|
const cellNum = parseInt(this.value);
|
||||||
|
freqNumbersContainer.innerHTML = generateFreqNumberInputs(cellNum);
|
||||||
|
});
|
||||||
|
});
|
||||||
58
simpleadmin/www/js/parse-settings.js
Normal file
58
simpleadmin/www/js/parse-settings.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
function parseCurrentSettings(rawdata) {
|
||||||
|
const data = rawdata;
|
||||||
|
|
||||||
|
const lines = data.split("\n");
|
||||||
|
console.log(lines);
|
||||||
|
|
||||||
|
// Remove QUIMSLOT and only take 1 or 2
|
||||||
|
this.sim = lines[1].split(":")[1].trim();
|
||||||
|
this.apn = lines[3].split(",")[2].replace(/\"/g, "");
|
||||||
|
this.cellLock4GStatus = lines[5].split(",")[1].replace(/\"/g, "");
|
||||||
|
this.cellLock5GStatus = lines[7].split(",")[1].replace(/\"/g, "");
|
||||||
|
this.prefNetwork = lines[9].split(",")[1].replace(/\"/g, "");
|
||||||
|
this.nrModeControlStatus = lines[11].split(",")[1].replace(/\"/g, "");
|
||||||
|
|
||||||
|
|
||||||
|
let bands = [];
|
||||||
|
|
||||||
|
// Append the values if there is separated by comma
|
||||||
|
for (let i = 13; i < 17; i++) {
|
||||||
|
if (lines[i].split(",").length > 1) {
|
||||||
|
bands.push(lines[i].split(",")[3].replace(/\"/g, ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bands = bands;
|
||||||
|
|
||||||
|
if (this.cellLock4GStatus == 1 && this.cellLock5GStatus == 1) {
|
||||||
|
this.cellLockStatus = "Locked to 4G and 5G";
|
||||||
|
} else if (this.cellLock4GStatus == 1) {
|
||||||
|
this.cellLockStatus = "Locked to 4G";
|
||||||
|
}
|
||||||
|
else if (this.cellLock5GStatus == 1) {
|
||||||
|
this.cellLockStatus = "Locked to 5G";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.cellLockStatus = "Not Locked";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.nrModeControlStatus == 0) {
|
||||||
|
this.nrModeControlStatus = "Not Disabled";
|
||||||
|
}
|
||||||
|
else if (this.nrModeControlStatus == 1) {
|
||||||
|
this.nrModeControlStatus = "SA Disabled";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.nrModeControlStatus = "NSA Disabled";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
sim: sim,
|
||||||
|
apn: apn,
|
||||||
|
cellLockStatus: cellLockStatus,
|
||||||
|
prefNetwork: prefNetwork,
|
||||||
|
nrModeControl: nrModeControlStatus,
|
||||||
|
bands: bands
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
76
simpleadmin/www/js/populate-checkbox.js
Normal file
76
simpleadmin/www/js/populate-checkbox.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
function populateCheckboxes(lte_band, nsa_nr5g_band, nr5g_band, locked_lte_bands, locked_nsa_bands, locked_sa_bands, cellLock) {
|
||||||
|
var checkboxesForm = document.getElementById("checkboxForm");
|
||||||
|
var selectedMode = document.getElementById("networkModeBand").value;
|
||||||
|
var bands;
|
||||||
|
|
||||||
|
// Determine bands based on selected network mode
|
||||||
|
if (selectedMode === "LTE") {
|
||||||
|
bands = lte_band;
|
||||||
|
} else if (selectedMode === "NSA") {
|
||||||
|
bands = nsa_nr5g_band;
|
||||||
|
} else if (selectedMode === "SA") {
|
||||||
|
bands = nr5g_band;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkboxesForm.innerHTML = ""; // Clear existing checkboxes
|
||||||
|
|
||||||
|
var bandsArray;
|
||||||
|
if (bands !== null) {
|
||||||
|
bandsArray = bands.split(":");
|
||||||
|
bandsArray.forEach(function(band, index) {
|
||||||
|
if (index % 5 === 0) {
|
||||||
|
currentRow = document.createElement("div");
|
||||||
|
currentRow.className = "row mb-2 mx-auto"; // Add margin bottom for spacing
|
||||||
|
checkboxesForm.appendChild(currentRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkboxDiv = document.createElement("div");
|
||||||
|
checkboxDiv.className = "form-check form-check-reverse col-2"; // Each checkbox takes a column
|
||||||
|
var checkboxInput = document.createElement("input");
|
||||||
|
checkboxInput.className = "form-check-input";
|
||||||
|
checkboxInput.type = "checkbox";
|
||||||
|
checkboxInput.id = "inlineCheckbox" + band;
|
||||||
|
checkboxInput.value = band;
|
||||||
|
checkboxInput.autocomplete = "off";
|
||||||
|
|
||||||
|
// Store the locked bands in an array
|
||||||
|
var locked_lte_bands_array = locked_lte_bands.split(":");
|
||||||
|
var locked_nsa_bands_array = locked_nsa_bands.split(":");
|
||||||
|
var locked_sa_bands_array = locked_sa_bands.split(":");
|
||||||
|
|
||||||
|
// Check if the current band is locked
|
||||||
|
var isLocked = false;
|
||||||
|
if (selectedMode === "LTE") {
|
||||||
|
if (locked_lte_bands_array.includes(band)) {
|
||||||
|
isLocked = true;
|
||||||
|
}
|
||||||
|
} else if (selectedMode === "NSA") {
|
||||||
|
if (locked_nsa_bands_array.includes(band)) {
|
||||||
|
isLocked = true;
|
||||||
|
}
|
||||||
|
} else if (selectedMode === "SA") {
|
||||||
|
if (locked_sa_bands_array.includes(band)) {
|
||||||
|
isLocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLocked) {
|
||||||
|
checkboxInput.checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkboxLabel = document.createElement("label");
|
||||||
|
checkboxLabel.className = "form-check-label";
|
||||||
|
checkboxLabel.htmlFor = "inlineCheckbox" + band;
|
||||||
|
checkboxLabel.innerText = "B" + band;
|
||||||
|
|
||||||
|
checkboxDiv.appendChild(checkboxInput);
|
||||||
|
checkboxDiv.appendChild(checkboxLabel);
|
||||||
|
currentRow.appendChild(checkboxDiv);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentRow;
|
||||||
|
addCheckboxListeners(cellLock);
|
||||||
|
}
|
||||||
47
simpleadmin/www/logout.html
Normal file
47
simpleadmin/www/logout.html
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<!-- change to a much simpler tab title -->
|
||||||
|
<title>Simple Admin</title>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<!-- 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">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<!-- END NAV -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.location=window.location.href.replace(/:\/\//, '://log:out@');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
930
simpleadmin/www/network.html
Normal file
930
simpleadmin/www/network.html
Normal file
@@ -0,0 +1,930 @@
|
|||||||
|
<!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>Simple Admin</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" />
|
||||||
|
|
||||||
|
<!-- 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">Simple Admin</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="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" href="network.html" aria-current="page">Simple Network</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/settings.html">Simple Settings</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/sms.html">SMS</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/console">Console</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="deviceinfo.html">Device Information</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link text-reset" id="darkModeToggle">Dark Mode</button>
|
||||||
|
</span>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link" href="logout.html">Log Out</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">Band Locking</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="isLoading">
|
||||||
|
Fetching supported bands...
|
||||||
|
</h5>
|
||||||
|
<form id="checkboxForm" x-show="isLoading === 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()"
|
||||||
|
>
|
||||||
|
Lock Bands
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-info m-2"
|
||||||
|
id="uncheckAll"
|
||||||
|
>
|
||||||
|
Uncheck All
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-danger m-2"
|
||||||
|
@click="resetBandLocking()"
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<p x-text="'Active bands: ' + bands"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row gap-3 mt-4">
|
||||||
|
<div class="col">
|
||||||
|
<form>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Network Utilities</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 input-group grid gap-3">
|
||||||
|
<label for="SIM1" class="form-label"> Change SIM</label>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<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"
|
||||||
|
>Select Preferred Network</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"
|
||||||
|
>NR5G Mode Control</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()"
|
||||||
|
>
|
||||||
|
Save Changes
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Cell Locking</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>
|
||||||
|
</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 requestATInfo(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 getSupportedBands() {
|
||||||
|
const atcmd = 'AT+QNWPREFCFG="policy_band"';
|
||||||
|
return requestATInfo(atcmd).then((rawdata) => {
|
||||||
|
let { lte_bands, nsa_bands, sa_bands } = parseSupportedBands(rawdata);
|
||||||
|
|
||||||
|
return {
|
||||||
|
lte_bands: lte_bands,
|
||||||
|
nsa_bands: nsa_bands,
|
||||||
|
sa_bands: sa_bands,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function 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
|
||||||
|
const lte_bands = bands.lte_band.join(":");
|
||||||
|
const nsa_bands = bands.nsa_nr5g_band.join(":");
|
||||||
|
const sa_bands = bands.nr5g_band.join(":");
|
||||||
|
|
||||||
|
return {
|
||||||
|
lte_bands,
|
||||||
|
nsa_bands,
|
||||||
|
sa_bands,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function 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
|
||||||
|
const locked_lte_bands = bands.lte_band.join(":");
|
||||||
|
const locked_nsa_bands = bands.nsa_nr5g_band.join(":");
|
||||||
|
const locked_sa_bands = bands.nr5g_band.join(":");
|
||||||
|
|
||||||
|
return {
|
||||||
|
locked_lte_bands,
|
||||||
|
locked_nsa_bands,
|
||||||
|
locked_sa_bands,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLockedBands() {
|
||||||
|
const atcmd =
|
||||||
|
'AT+QNWPREFCFG="lte_band";+QNWPREFCFG= "nsa_nr5g_band";+QNWPREFCFG= "nr5g_band"';
|
||||||
|
|
||||||
|
return requestATInfo(atcmd).then((rawdata) => {
|
||||||
|
const lockedBandsData = parseLockedBands(rawdata);
|
||||||
|
return lockedBandsData;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentSettings() {
|
||||||
|
const atcmd =
|
||||||
|
'AT+QUIMSLOT?;+CGCONTRDP=1;+QNWLOCK="common/4g";+QNWLOCK="common/5g";+QNWPREFCFG="mode_pref";+QNWPREFCFG="nr5g_disable_mode";+QCAINFO';
|
||||||
|
|
||||||
|
return requestATInfo(atcmd).then((rawdata) => {
|
||||||
|
const settings = parseCurrentSettings(rawdata);
|
||||||
|
return {
|
||||||
|
sim: settings.sim,
|
||||||
|
apn: settings.apn,
|
||||||
|
cellLockStatus: settings.cellLockStatus,
|
||||||
|
prefNetwork: settings.prefNetwork,
|
||||||
|
nrModeControl: settings.nrModeControl,
|
||||||
|
bands: settings.bands,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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: "-",
|
||||||
|
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: null,
|
||||||
|
bands: "Fetching Bands...",
|
||||||
|
init() {
|
||||||
|
// Function to populate checkboxes
|
||||||
|
const showPopulateCheckboxes = () => {
|
||||||
|
this.isLoading = true;
|
||||||
|
Promise.all([getSupportedBands(), getLockedBands()])
|
||||||
|
.then(([supportedBandsData, lockedBandsData]) => {
|
||||||
|
this.lte_bands = supportedBandsData.lte_bands;
|
||||||
|
this.nsa_bands = supportedBandsData.nsa_bands;
|
||||||
|
this.sa_bands = supportedBandsData.sa_bands;
|
||||||
|
this.locked_lte_bands = lockedBandsData.locked_lte_bands;
|
||||||
|
this.locked_nsa_bands = lockedBandsData.locked_nsa_bands;
|
||||||
|
this.locked_sa_bands = lockedBandsData.locked_sa_bands;
|
||||||
|
|
||||||
|
// Once both promises are resolved, call populateCheckboxes
|
||||||
|
populateCheckboxes(
|
||||||
|
this.lte_bands,
|
||||||
|
this.nsa_bands,
|
||||||
|
this.sa_bands,
|
||||||
|
this.locked_lte_bands,
|
||||||
|
this.locked_nsa_bands,
|
||||||
|
this.locked_sa_bands,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set isLoading to false after populating checkboxes
|
||||||
|
this.isLoading = false;
|
||||||
|
|
||||||
|
// Add event listeners to checkboxes after populating them
|
||||||
|
addCheckboxListeners(this);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error:", error);
|
||||||
|
// Handle errors if any
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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 get the current settings
|
||||||
|
const getCurrentSettingsData = () => {
|
||||||
|
getCurrentSettings().then((settings) => {
|
||||||
|
this.sim = settings.sim;
|
||||||
|
this.apn = settings.apn;
|
||||||
|
this.cellLockStatus = settings.cellLockStatus;
|
||||||
|
this.prefNetwork = settings.prefNetwork;
|
||||||
|
this.nrModeControl = settings.nrModeControl;
|
||||||
|
this.bands = settings.bands;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
getCurrentSettingsData();
|
||||||
|
},
|
||||||
|
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 5 second countdown
|
||||||
|
this.showModal = true;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
atAPN = `+CGDCONT=1,"IP","${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);
|
||||||
|
|
||||||
|
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 = `+QNWLOCK="common/4g",${cellNum},${validPairs
|
||||||
|
.map((pair) => `${pair.earfcn},${pair.pci}`)
|
||||||
|
.join(",")}`;
|
||||||
|
atcmd = "AT+CFUN=0;" + atcmd + ";+CFUN=1";
|
||||||
|
|
||||||
|
// 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 = `+QNWLOCK="common/5g",${earfcn},${pci},${scs},${band}`;
|
||||||
|
atcmd = "AT+CFUN=0;" + atcmd + ";+CFUN=1";
|
||||||
|
|
||||||
|
// 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+CFUN=0;+QNWLOCK="common/4g,0;+CFUN=1"';
|
||||||
|
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+CFUN=0;+QNWLOCK="common/5g,0;+CFUN=1"';
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script src="/js/dark-mode.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
666
simpleadmin/www/settings.html
Normal file
666
simpleadmin/www/settings.html
Normal file
@@ -0,0 +1,666 @@
|
|||||||
|
<!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>Simple Admin</title>
|
||||||
|
<link rel="stylesheet" href="/css/styles.css" />
|
||||||
|
<link rel="stylesheet" href="/css/bootstrap.min.css" />
|
||||||
|
|
||||||
|
<!-- 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="simpleSettings()">
|
||||||
|
<nav class="navbar navbar-expand-lg mt-2">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="/"
|
||||||
|
><span class="mb-0 h4">Simple Admin</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="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" href="/settings.html" aria-current="page">Simple Settings</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/sms.html">SMS</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/console">Console</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/deviceinfo.html"
|
||||||
|
>Device Information</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link text-reset" id="darkModeToggle">Dark Mode</button>
|
||||||
|
</span>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link" href="logout.html">Log Out</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="row mt-5 mb-4">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">AT Terminal</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-text">
|
||||||
|
<div class="form-floating mb-4">
|
||||||
|
<!-- At commands output here -->
|
||||||
|
<textarea
|
||||||
|
class="form-control"
|
||||||
|
placeholder="ATI"
|
||||||
|
id="atOutputBox"
|
||||||
|
style="height: 220px"
|
||||||
|
x-text="atCommandResponse"
|
||||||
|
readonly
|
||||||
|
>
|
||||||
|
<label for="floatingTextarea">ATI</label>
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="col-md-4 mb-3">
|
||||||
|
<label for="exampleInputEmail1" class="form-label"
|
||||||
|
>AT Command</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="atCommandInput"
|
||||||
|
placeholder="ATI"
|
||||||
|
aria-describedby="atCommandInput"
|
||||||
|
x-model="atcmd"
|
||||||
|
@keydown.enter = "sendATCommand()"
|
||||||
|
/>
|
||||||
|
<div id="atCommandInputHelper" class="form-text">
|
||||||
|
Seperate multiple commands with comma (,).
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="d-grid gap-2 d-md-flex justify-content-md-start"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn btn-primary me-md-2"
|
||||||
|
type="button"
|
||||||
|
@click="sendATCommand()"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-danger"
|
||||||
|
type="button"
|
||||||
|
@click="clearResponses()"
|
||||||
|
:disabled="isClean"
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">One Click Utilities</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-text">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Reboot</th>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-danger"
|
||||||
|
@click="showRebootModal()"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Reboot
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Reset AT Commands Settings</th>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-danger"
|
||||||
|
@click="resetATCommands()"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">ETH IP Passthrough</th>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="ethPassthroughEnable()"
|
||||||
|
x-show="ethPassStatus === false"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Enable
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-danger"
|
||||||
|
@click="ethPassthroughDisable()"
|
||||||
|
x-show="ethPassStatus === true"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Disable
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Onboard DNS Proxy</th>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="onBoardDNSProxyEnable()"
|
||||||
|
x-show="DNSProxyStatus === false"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Enable
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-danger"
|
||||||
|
@click="onBoardDNSProxyDisable()"
|
||||||
|
x-show="DNSProxyStatus === true"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Disable
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">USB Mode</th>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="usbModeEnable()"
|
||||||
|
x-show="USBModeStatus === true"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Enable
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-danger"
|
||||||
|
@click="usbModeDisable()"
|
||||||
|
x-show="USBModeStatus === false"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Disable
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Scan Neighbour LTE</th>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="scanLTE()"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Scan LTE
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Scan Neighbour NSA</th>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="scanNSA()"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Scan NSA
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header">TTL and Network Scan Settings</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<label for="TTLState" class="form-label"
|
||||||
|
>TTL State and Value</label
|
||||||
|
>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div
|
||||||
|
class="p-3 text-primary-emphasis bg-primary-subtle border border-primary-subtle rounded-3"
|
||||||
|
x-show="ttlStatus === true"
|
||||||
|
>
|
||||||
|
TTL is Active
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="p-3 text-danger-emphasis bg-danger-subtle border border-danger-subtle rounded-3"
|
||||||
|
x-show="ttlStatus === false"
|
||||||
|
>
|
||||||
|
TTL is Inactive
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div
|
||||||
|
class="p-3 text-info-emphasis bg-info-subtle border border-info-subtle rounded-3 mb-4"
|
||||||
|
x-text="ttlvalue"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-text mb-3">
|
||||||
|
<div class="mb-4">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="ttlInput"
|
||||||
|
placeholder="TTL Value"
|
||||||
|
x-model="newTTL"
|
||||||
|
/>
|
||||||
|
<div id="ttlValueHelper" class="form-text">
|
||||||
|
Set TTL Value to 0 to disable.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
@click="setTTL()"
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-text">
|
||||||
|
<!-- Select Input Scan Here -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="networkScan" class="form-label"
|
||||||
|
>Network Scan</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-select"
|
||||||
|
id="networkScan"
|
||||||
|
x-model="fullScanModeType"
|
||||||
|
>
|
||||||
|
<option selected>Choose Scan Mode</option>
|
||||||
|
<option value="LTE">LTE</option>
|
||||||
|
<option value="NR5G">NR5G</option>
|
||||||
|
<option value="ALL">ALL</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
@click="fullScanMode()"
|
||||||
|
:disabled="isLoading"
|
||||||
|
x-text="scanStart ? 'Scanning... Please wait.' : 'Start Scan'"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Loading Modal for Reboot -->
|
||||||
|
<div class="modal-overlay" x-show="showModal">
|
||||||
|
<div class="loading-modal">
|
||||||
|
<div
|
||||||
|
class="loading-text"
|
||||||
|
style="display: flex; flex-direction: column"
|
||||||
|
>
|
||||||
|
<h3>This will reboot the modem.</h3>
|
||||||
|
<p style="margin-top: 0.5rem">Continue?</p>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid gap-2 d-md-block">
|
||||||
|
<button
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
@click="rebootDevice()"
|
||||||
|
>
|
||||||
|
Reboot
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-danger"
|
||||||
|
type="button"
|
||||||
|
@click="closeModal()"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Reboot Modal Countdown -->
|
||||||
|
<div class="modal-overlay" x-show="isRebooting">
|
||||||
|
<div class="loading-modal">
|
||||||
|
<div class="loader"></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.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<script src="/js/dark-mode.js"></script>
|
||||||
|
<script>
|
||||||
|
function simpleSettings() {
|
||||||
|
return {
|
||||||
|
isLoading: false,
|
||||||
|
showSuccess: false,
|
||||||
|
showError: false,
|
||||||
|
isClean: true,
|
||||||
|
showModal: false,
|
||||||
|
isRebooting: false,
|
||||||
|
atcmd: "",
|
||||||
|
fetchATCommand: "",
|
||||||
|
countdown: 0,
|
||||||
|
atCommandResponse: "",
|
||||||
|
currentSettingsResponse: "",
|
||||||
|
ttldata: null,
|
||||||
|
ttlvalue: 0,
|
||||||
|
ttlStatus: false,
|
||||||
|
newTTL: null,
|
||||||
|
ethPassStatus: false,
|
||||||
|
DNSProxyStatus: true,
|
||||||
|
USBModeStatus: true,
|
||||||
|
fullScanModeType: "",
|
||||||
|
scanStart: false,
|
||||||
|
|
||||||
|
closeModal() {
|
||||||
|
this.confirmModal = false;
|
||||||
|
this.showModal = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
showRebootModal() {
|
||||||
|
this.showModal = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
sendATCommand() {
|
||||||
|
if (!this.atcmd) {
|
||||||
|
// Use ATI as default command
|
||||||
|
this.atcmd = "ATI";
|
||||||
|
console.log(
|
||||||
|
"AT Command is empty, using ATI as default command: ",
|
||||||
|
this.atcmd
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = true;
|
||||||
|
fetch(
|
||||||
|
"/cgi-bin/get_atcommand?" +
|
||||||
|
new URLSearchParams({
|
||||||
|
atcmd: this.atcmd,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
return res.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.atCommandResponse = data;
|
||||||
|
this.isLoading = false;
|
||||||
|
this.isClean = false;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error: ", error);
|
||||||
|
this.showError = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
clearResponses() {
|
||||||
|
this.atCommandResponse = "";
|
||||||
|
this.isClean = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
rebootDevice() {
|
||||||
|
this.atcmd = "AT+CFUN=1,1";
|
||||||
|
this.sendATCommand();
|
||||||
|
|
||||||
|
this.atCommandResponse = "";
|
||||||
|
this.showModal = false;
|
||||||
|
this.isRebooting = true;
|
||||||
|
this.countdown = 40;
|
||||||
|
|
||||||
|
// Do the countdown
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
this.countdown--;
|
||||||
|
if (this.countdown === 0) {
|
||||||
|
clearInterval(interval);
|
||||||
|
this.isRebooting = false;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
resetATCommands() {
|
||||||
|
this.atcmd = "AT&F";
|
||||||
|
this.sendATCommand();
|
||||||
|
console.log("Resetting AT Commands");
|
||||||
|
this.atcmd = "";
|
||||||
|
this.atCommandResponse = "";
|
||||||
|
this.showRebootModal();
|
||||||
|
},
|
||||||
|
|
||||||
|
ethPassthroughEnable() {
|
||||||
|
this.atcmd = 'AT+QMAP="MPDN_RULE",0,1,0,1,1,"FF:FF:FF:FF:FF:FF"';
|
||||||
|
this.sendATCommand();
|
||||||
|
this.fetchCurrentSettings();
|
||||||
|
},
|
||||||
|
|
||||||
|
ethPassthroughDisable() {
|
||||||
|
this.atcmd = 'AT+QMAP="MPDN_RULE",0';
|
||||||
|
this.sendATCommand();
|
||||||
|
this.fetchCurrentSettings();
|
||||||
|
},
|
||||||
|
|
||||||
|
onBoardDNSProxyEnable() {
|
||||||
|
this.atcmd = 'AT+QMAP="DHCPV4DNS","enable"';
|
||||||
|
this.sendATCommand();
|
||||||
|
this.fetchCurrentSettings();
|
||||||
|
},
|
||||||
|
|
||||||
|
onBoardDNSProxyDisable() {
|
||||||
|
this.atcmd = 'AT+QMAP="DHCPV4DNS","disable"';
|
||||||
|
this.sendATCommand();
|
||||||
|
this.fetchCurrentSettings();
|
||||||
|
},
|
||||||
|
|
||||||
|
usbModeEnable() {
|
||||||
|
this.atcmd = "AT+QMAPWAC=1";
|
||||||
|
this.sendATCommand();
|
||||||
|
this.fetchCurrentSettings();
|
||||||
|
},
|
||||||
|
|
||||||
|
usbModeDisable() {
|
||||||
|
this.atcmd = "AT+QMAPWAC=0";
|
||||||
|
this.sendATCommand();
|
||||||
|
this.fetchCurrentSettings();
|
||||||
|
},
|
||||||
|
|
||||||
|
scanLTE() {
|
||||||
|
this.atcmd = 'AT+QENG="neighbourcell"';
|
||||||
|
this.sendATCommand();
|
||||||
|
},
|
||||||
|
|
||||||
|
scanNSA() {
|
||||||
|
this.atcmd =
|
||||||
|
'AT+QNWCFG="nr5g_meas_info",1;+QNWCFG="nr5g_meas_info"';
|
||||||
|
this.sendATCommand();
|
||||||
|
},
|
||||||
|
|
||||||
|
fullScanMode() {
|
||||||
|
switch (this.fullScanModeType) {
|
||||||
|
case "LTE":
|
||||||
|
this.atcmd = "AT+QSCAN=1,1";
|
||||||
|
this.scanStart = true;
|
||||||
|
this.atCommandResponse = "Scanning all available LTE networks... This might take a while."
|
||||||
|
this.sendATCommand();
|
||||||
|
this.scanStart = false;
|
||||||
|
break;
|
||||||
|
case "NR5G":
|
||||||
|
this.atcmd = "AT+QSCAN=2,1";
|
||||||
|
this.scanStart = true;
|
||||||
|
this.atCommandResponse = "Scanning all available NR5G-SA networks... This might take a while."
|
||||||
|
this.sendATCommand();
|
||||||
|
this.scanStart = false;
|
||||||
|
break;
|
||||||
|
case "ALL":
|
||||||
|
this.atcmd = "AT+QSCAN=3,1";
|
||||||
|
this.scanStart = true;
|
||||||
|
this.atCommandResponse = "Scanning all available networks... This might take a while."
|
||||||
|
this.sendATCommand();
|
||||||
|
this.scanStart = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
alert("Select a Scan Mode First");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchCurrentSettings() {
|
||||||
|
this.fetchATCommand =
|
||||||
|
'AT+QMAP="MPDN_RULE";+QMAP="DHCPV4DNS";+QMAPWAC?';
|
||||||
|
fetch(
|
||||||
|
"/cgi-bin/get_atcommand?" +
|
||||||
|
new URLSearchParams({
|
||||||
|
atcmd: this.fetchATCommand,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
return res.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
// Set the value of currentSettingsResponse
|
||||||
|
this.currentSettingsResponse = data;
|
||||||
|
const currentData = data.split("\n");
|
||||||
|
|
||||||
|
const testEthpass = currentData[1].match(
|
||||||
|
/\+QMAP: "MPDN_rule",0,0,0,0,0/
|
||||||
|
);
|
||||||
|
|
||||||
|
if (testEthpass) {
|
||||||
|
this.ethPassStatus = false;
|
||||||
|
} else {
|
||||||
|
this.ethPassStatus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const testDNSProxy = currentData[6].match(
|
||||||
|
/\+QMAP: "DHCPV4DNS","enable"/
|
||||||
|
);
|
||||||
|
|
||||||
|
if (testDNSProxy) {
|
||||||
|
this.DNSProxyStatus = true;
|
||||||
|
} else {
|
||||||
|
this.DNSProxyStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const testUSBMode = currentData[8].match(/\+QMAPWAC: 1/);
|
||||||
|
|
||||||
|
if (testUSBMode) {
|
||||||
|
this.USBModeStatus = true;
|
||||||
|
} else {
|
||||||
|
this.USBModeStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear atcmd
|
||||||
|
this.atcmd = "";
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error: ", error);
|
||||||
|
this.showError = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchTTL() {
|
||||||
|
fetch("/cgi-bin/get_ttl_status")
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
this.ttldata = data;
|
||||||
|
this.ttlStatus = this.ttldata.isEnabled;
|
||||||
|
this.ttlvalue = this.ttldata.ttl;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
setTTL() {
|
||||||
|
this.isLoading = true; // Set loading state while updating TTL
|
||||||
|
|
||||||
|
fetch(
|
||||||
|
"/cgi-bin/set_ttl?" +
|
||||||
|
new URLSearchParams({
|
||||||
|
ttlvalue: this.newTTL,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
// Once TTL is updated, fetch the updated TTL data
|
||||||
|
this.fetchTTL();
|
||||||
|
this.isLoading = false; // Set loading state back to false
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error updating TTL: ", error);
|
||||||
|
this.isLoading = false; // Ensure loading state is properly handled in case of error
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.fetchTTL();
|
||||||
|
this.fetchCurrentSettings();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,158 +1,294 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en" data-bs-theme="light">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<!-- change to a much simpler tab title -->
|
|
||||||
<title>Simple Admin</title>
|
<title>Simple Admin</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" />
|
||||||
|
|
||||||
|
<!-- Import BootStrap Javascript -->
|
||||||
|
<script src="/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="/js/alpinejs.min.js" defer></script>
|
<script src="/js/alpinejs.min.js" defer></script>
|
||||||
<link rel="stylesheet" href="/css/bulma.css" />
|
<script src="/js/auth.js"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
|
|
||||||
</head>
|
</head>
|
||||||
|
<body onload="isAuthenticated()">
|
||||||
<body>
|
<main>
|
||||||
<!-- START NAV -->
|
<div class="container my-4" x-data="fetchSMS()">
|
||||||
<nav class="navbar is-black" x-data="{ isOpen: false }">
|
<nav class="navbar navbar-expand-lg mt-2">
|
||||||
<div class="container">
|
<div class="container-fluid">
|
||||||
<div class="navbar-brand">
|
<a class="navbar-brand" href="/"
|
||||||
<a class="navbar-item brand-text" href="/"> Simple Admin </a>
|
><span class="mb-0 h4">Simple Admin</span></a
|
||||||
<a
|
>
|
||||||
role="button"
|
<button
|
||||||
class="navbar-burger burger"
|
class="navbar-toggler"
|
||||||
@click="isOpen = !isOpen"
|
type="button"
|
||||||
>
|
data-bs-toggle="collapse"
|
||||||
<span aria-hidden="true"></span>
|
data-bs-target="#navbarText"
|
||||||
<span aria-hidden="true"></span>
|
aria-controls="navbarText"
|
||||||
<span aria-hidden="true"></span>
|
aria-expanded="false"
|
||||||
</a>
|
aria-label="Toggle navigation"
|
||||||
</div>
|
>
|
||||||
<div
|
<span class="navbar-toggler-icon"></span>
|
||||||
id="navMenu"
|
</button>
|
||||||
class="navbar-menu"
|
<div class="collapse navbar-collapse" id="navbarText">
|
||||||
:class="isOpen ? 'is-active' : ''"
|
<ul class="navbar-nav me-auto mb-2 ml-4 mb-lg-0">
|
||||||
>
|
<li class="nav-item">
|
||||||
<div class="navbar-start">
|
<a class="nav-link" href="/">Home</a>
|
||||||
<a class="navbar-item" href="/"> Connection Info </a>
|
</li>
|
||||||
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
|
<li class="nav-item">
|
||||||
<a class="navbar-item" href="/sms.html"> SMS </a>
|
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/settings.html">Simple Settings</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" href="/sms.html" aria-current="page">SMS</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/console">Console</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/deviceinfo.html"
|
||||||
|
>Device Information</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link text-reset" id="darkModeToggle">Dark Mode</button>
|
||||||
|
</span>
|
||||||
|
<span class="navbar-text">
|
||||||
|
<button class="btn btn-link" href="logout.html">Log Out</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
</div>
|
|
||||||
</nav>
|
<div class="row mt-5 mb-4">
|
||||||
<!-- END NAV -->
|
<div class="col">
|
||||||
<div class="container" x-data="atCommands()">
|
<div class="card">
|
||||||
<div class="columns">
|
<div class="card-header">SMS Manager</div>
|
||||||
<div class="column is-12">
|
<div class="card-body">
|
||||||
<div class="columns">
|
<div class="card-text">
|
||||||
<div class="column is-8">
|
<div class="col">
|
||||||
<div class="card">
|
<div
|
||||||
<header class="card-header">
|
style="
|
||||||
<p class="card-header-title">SMS Viewer</p>
|
max-height: 400px;
|
||||||
<div class="field">
|
overflow-y: scroll;
|
||||||
<p class="control">
|
overflow-x: hidden;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<table class="table table-hover border-success">
|
||||||
|
<tbody>
|
||||||
|
<div class="card-subtitle" x-show="isLoading">
|
||||||
|
<h4>Fetching SMS...</h4>
|
||||||
|
</div>
|
||||||
|
<!-- Only show template if isLoading is False -->
|
||||||
|
<template x-if="messages.length === 0 && isLoading === false" >
|
||||||
|
<div>
|
||||||
|
<p>Message Empty</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
x-for="(message, index) in messages"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<tr class="">
|
||||||
|
<td>
|
||||||
|
<div class="row column-gap-1 mb-2">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<p x-text="'Sender: ' + senders[index]"></p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<p
|
||||||
|
x-text="'Date and Time: ' + dates[index]"
|
||||||
|
></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<p x-text="message"></p>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form>
|
||||||
|
<div class="col-md-4 my-4">
|
||||||
|
<label for="PhoneNumber" class="form-label"
|
||||||
|
>Send SMS</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="Phone Number"
|
||||||
|
aria-label="Phone Number"
|
||||||
|
x-model="phoneNumber"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-8 mb-3">
|
||||||
|
<!-- Text Area Here for SMS Input -->
|
||||||
|
<textarea
|
||||||
|
class="form-control"
|
||||||
|
id="smsInputBox"
|
||||||
|
rows="5"
|
||||||
|
placeholder="Enter SMS here (!!!CURRENTLY UNDER DEVELOPMENT!!!)"
|
||||||
|
x-model="messageToSend"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="d-grid gap-2 d-md-flex justify-content-md-start"
|
||||||
|
>
|
||||||
|
<button class="btn btn-primary me-md-2" type="button" @click="sendSMS()" :disabled="true" >
|
||||||
|
Send SMS
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
class="button is-success"
|
class="btn btn-success"
|
||||||
@click="sendAtCommand()"
|
type="button"
|
||||||
:disabled="isLoading"
|
@click="init()"
|
||||||
>
|
>
|
||||||
Refresh
|
Refresh
|
||||||
</button>
|
</button>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<p class="control">
|
|
||||||
<button
|
<button
|
||||||
class="button is-danger"
|
class="btn btn-danger"
|
||||||
@click="sendAtCommand()"
|
type="button"
|
||||||
:disabled="isLoading"
|
@click="deleteAllSMS()"
|
||||||
>
|
>
|
||||||
Delete
|
Delete All SMS
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="content">
|
|
||||||
<textarea
|
|
||||||
class="textarea"
|
|
||||||
placeholder="SMS Viewer (Make sure to run: AT+CMGF=1 first)"
|
|
||||||
readonly
|
|
||||||
rows="10"
|
|
||||||
cols="50"
|
|
||||||
x-model="atCommandResponse"
|
|
||||||
:disabled="isLoading"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
|
<script src="/js/dark-mode.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function atCommands() {
|
function fetchSMS() {
|
||||||
return {
|
return {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
atcmd: 'AT+CMGL="ALL"',
|
atCommandResponse: "",
|
||||||
atCommandResponse: null,
|
messageToSend: "",
|
||||||
sendAtCommand() {
|
phoneNumber: "",
|
||||||
this.isLoading = true; // Set loading state to true before fetching data
|
messages: [],
|
||||||
|
senders: [],
|
||||||
|
dates: [],
|
||||||
|
requestSMS() {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.atCommandResponse = "Loading...";
|
||||||
|
// Expect a text response from the server
|
||||||
|
fetch("/cgi-bin/get_sms")
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((data) => {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.atCommandResponse = data;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.parseSMSData(this.atCommandResponse);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
parseSMSData(data) {
|
||||||
|
const cmglRegex =
|
||||||
|
/^\s*\+CMGL:\s*(\d+),"[^"]*","([^"]*)"[^"]*,"([^"]*)"/gm;
|
||||||
|
|
||||||
|
let match;
|
||||||
|
while ((match = cmglRegex.exec(data)) !== null) {
|
||||||
|
const index = parseInt(match[1]);
|
||||||
|
const sender = match[2];
|
||||||
|
let date = match[3];
|
||||||
|
|
||||||
|
// remove +32 from the date
|
||||||
|
date = date.replace("+32", "");
|
||||||
|
|
||||||
|
// Find the start and end positions of the message
|
||||||
|
const startIndex = cmglRegex.lastIndex;
|
||||||
|
let endIndex = data.indexOf("+CMGL:", startIndex + 1);
|
||||||
|
if (endIndex === -1) {
|
||||||
|
// If no more +CMGL lines, set end index to end of string
|
||||||
|
endIndex = data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the message from start to end index
|
||||||
|
const message = data.substring(startIndex, endIndex).trim();
|
||||||
|
|
||||||
|
this.messages.push(message);
|
||||||
|
this.senders.push(sender);
|
||||||
|
this.dates.push(date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteAllSMS() {
|
||||||
|
const atcmd = "AT+CMGD=,4";
|
||||||
fetch(
|
fetch(
|
||||||
"/cgi-bin/get_atcommand?" +
|
"/cgi-bin/get_atcommand?" +
|
||||||
new URLSearchParams({
|
new URLSearchParams({
|
||||||
atcmd: this.atcmd,
|
atcmd: atcmd,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.then((res) => {
|
.then((response) => response.text())
|
||||||
return res.text();
|
|
||||||
})
|
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.atCommandResponse = data;
|
console.log(data);
|
||||||
// Split the response into individual messages
|
|
||||||
const messages = data.trim().split("\n\n");
|
|
||||||
|
|
||||||
// Parse each message and construct an array of objects
|
|
||||||
const parsedMessages = messages.map((message) => {
|
|
||||||
const lines = message.split("\n");
|
|
||||||
const sender = decodeHexString(
|
|
||||||
lines[1].split(",")[2].slice(1, -1)
|
|
||||||
);
|
|
||||||
const time = lines[2].split(',"')[1];
|
|
||||||
const messageText = decodeHexString(lines[3]);
|
|
||||||
return {
|
|
||||||
"Người gửi": sender,
|
|
||||||
"Thời gian": time,
|
|
||||||
"Tin nhắn": messageText,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Log the parsed messages array as JSON to the console
|
|
||||||
console.log(JSON.stringify(parsedMessages, null, 2));
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Không thể tìm thấy dữ liệu:", error);
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.isLoading = false; // Set loading state to false after fetching data
|
this.requestSMS();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
sendSMS() {
|
||||||
|
this.isLoading = true;
|
||||||
|
fetch(
|
||||||
|
"/cgi-bin/send_sms?" +
|
||||||
|
new URLSearchParams({
|
||||||
|
phone_number: this.phoneNumber,
|
||||||
|
message: this.messageToSend,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error:", error);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.requestSMS();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
init() {
|
||||||
|
// Send AT+CMGF=1 once to set the modem to text mode
|
||||||
|
const atcmd = "AT+CMGF=1";
|
||||||
|
fetch(
|
||||||
|
"/cgi-bin/get_atcommand?" +
|
||||||
|
new URLSearchParams({
|
||||||
|
atcmd: atcmd,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.requestSMS();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Hàm giải mã chuỗi hex sang văn bản
|
|
||||||
function decodeHexString(hexString) {
|
|
||||||
let decodedString = "";
|
|
||||||
for (let i = 0; i < hexString.length; i += 4) {
|
|
||||||
let hex = hexString.substr(i, 4);
|
|
||||||
let intValue = parseInt(hex, 16);
|
|
||||||
decodedString += String.fromCharCode(intValue);
|
|
||||||
}
|
|
||||||
return decodedString;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,128 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<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>RM5xxx TTL Changer</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">
|
|
||||||
</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"> AT Commands </a>
|
|
||||||
<a class="navbar-item" href="/sms.html"> SMS </a>
|
|
||||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<!-- END NAV -->
|
|
||||||
<div class="container" x-data="ttlCommands()" x-init="init">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-12">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-8">
|
|
||||||
<div class="card">
|
|
||||||
<header class="card-header">
|
|
||||||
<p class="card-header-title">
|
|
||||||
TTL Enabler
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="content">
|
|
||||||
<p>
|
|
||||||
<h2>TTL Status</h2> <br>
|
|
||||||
TTL is <span class="tag is-large" :class="ttldata.isEnabled ? 'is-success' : 'is-danger'" x-text="ttldata.isEnabled == true ? 'ON' : 'OFF'"></span>
|
|
||||||
<br />
|
|
||||||
TTL Set to <span x-text="ttldata.ttl"></span>
|
|
||||||
</p>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label">Set TTL</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" type="number" placeholder="64"
|
|
||||||
x-model="newTTL">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-link" @click="setTTL()">Set TTL</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="card">
|
|
||||||
<header class="card-header">
|
|
||||||
<p class="card-header-title">
|
|
||||||
Common TTL For Providers
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="content">
|
|
||||||
<ul>
|
|
||||||
<li>Magenta: 65</li>
|
|
||||||
<li>Red: 88</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
function ttlCommands() {
|
|
||||||
return {
|
|
||||||
isLoading: false,
|
|
||||||
ttldata: null,
|
|
||||||
newTTL: 0,
|
|
||||||
init() {
|
|
||||||
fetch('/cgi-bin/get_ttl_status')
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
this.ttldata = data
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setTTL() {
|
|
||||||
fetch('/cgi-bin/set_ttl?' + new URLSearchParams({
|
|
||||||
ttlvalue: this.newTTL,
|
|
||||||
}))
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
this.ttldata = data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
1
simplefirewall/.rev
Normal file
1
simplefirewall/.rev
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Define the ports you want to block
|
# Define the ports you want to block
|
||||||
PORTS=("80" "8080" "8088" "443") # Default ports, will be modified by the install script
|
PORTS=("80" "443") # Default ports, will be modified by the install script
|
||||||
|
|
||||||
# First, allow specified ports on bridge0, eth0, and tailscale0
|
# First, allow specified ports on bridge0, eth0, and tailscale0
|
||||||
for port in "${PORTS[@]}"; do
|
for port in "${PORTS[@]}"; do
|
||||||
|
|||||||
1
simpleupdates/.rev
Normal file
1
simpleupdates/.rev
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
202
simpleupdates/scripts/update_simpleadmin.sh
Normal file
202
simpleupdates/scripts/update_simpleadmin.sh
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define constants
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
DIR_NAME="simpleadmin"
|
||||||
|
SERVICE_FILE="/lib/systemd/system/install_simpleadmin.service"
|
||||||
|
SERVICE_NAME="install_simpleadmin"
|
||||||
|
TMP_SCRIPT="/tmp/install_simpleadmin.sh"
|
||||||
|
LOG_FILE="/tmp/install_simpleadmin.log"
|
||||||
|
|
||||||
|
# Tmp Script dependent constants
|
||||||
|
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||||
|
# Function to remount file system as read-write
|
||||||
|
remount_rw() {
|
||||||
|
mount -o remount,rw /
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to remount file system as read-only
|
||||||
|
remount_ro() {
|
||||||
|
mount -o remount,ro /
|
||||||
|
}
|
||||||
|
remount_rw
|
||||||
|
# Create the systemd service file
|
||||||
|
cat <<EOF > "$SERVICE_FILE"
|
||||||
|
[Unit]
|
||||||
|
Description=Update $DIR_NAME temporary service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create and populate the temporary shell script for installation
|
||||||
|
cat <<EOF > "$TMP_SCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||||
|
|
||||||
|
# Function to remount file system as read-write
|
||||||
|
remount_rw() {
|
||||||
|
mount -o remount,rw /
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to remount file system as read-only
|
||||||
|
remount_ro() {
|
||||||
|
mount -o remount,ro /
|
||||||
|
}
|
||||||
|
remount_rw
|
||||||
|
uninstall_simpleadmin() {
|
||||||
|
echo "Uninstalling Simpleadmin..."
|
||||||
|
|
||||||
|
# Check if Lighttpd service is installed and remove it if present
|
||||||
|
if [ -f "/lib/systemd/system/lighttpd.service" ]; then
|
||||||
|
echo "Lighttpd detected, uninstalling Lighttpd webserver and its modules..."
|
||||||
|
systemctl stop lighttpd
|
||||||
|
rm -f /lib/systemd/system/lighttpd.service
|
||||||
|
opkg --force-remove --force-removal-of-dependent-packages remove lighttpd-mod-authn_file lighttpd-mod-auth lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy lighttpd
|
||||||
|
fi
|
||||||
|
echo -e "\e[1;34mUninstalling simpleadmin content...\e[0m"
|
||||||
|
systemctl stop simpleadmin_generate_status
|
||||||
|
systemctl stop simpleadmin_httpd
|
||||||
|
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||||
|
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
echo -e "\e[1;34mUninstalling ttyd...\e[0m"
|
||||||
|
systemctl stop ttyd
|
||||||
|
rm -rf /usrdata/ttyd
|
||||||
|
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||||
|
rm -f /lib/systemd/system/ttyd.service
|
||||||
|
rm -f /lib/systemd/system/multi-user.target.wants/ttyd.service
|
||||||
|
rm -rf /bin/ttyd
|
||||||
|
echo -e "\e[1;32mttyd has been uninstalled.\e[0m"
|
||||||
|
|
||||||
|
echo "Uninstallation process completed."
|
||||||
|
}
|
||||||
|
|
||||||
|
install_lighttpd() {
|
||||||
|
# Check for simpleadmin_httpd service and remove if exists
|
||||||
|
if [ -f "/lib/systemd/system/simpleadmin_httpd.service" ]; then
|
||||||
|
systemctl stop simpleadmin_httpd
|
||||||
|
rm /lib/systemd/system/simpleadmin_httpd.service
|
||||||
|
rm /lib/systemd/system/multi-user.target.wants/simpleadmin_httpd.service
|
||||||
|
fi
|
||||||
|
|
||||||
|
/opt/bin/opkg install sudo lighttpd lighttpd-mod-auth lighttpd-mod-authn_file lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy
|
||||||
|
# Ensure rc.unslung doesn't try to start it
|
||||||
|
# Dynamically find and remove any Lighttpd-related init script
|
||||||
|
for script in /opt/etc/init.d/*lighttpd*; do
|
||||||
|
if [ -f "$script" ]; then
|
||||||
|
echo "Removing existing Lighttpd init script: $script"
|
||||||
|
rm "$script" # Remove the script if it contains 'lighttpd' in its name
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
systemctl stop lighttpd
|
||||||
|
echo -e "\033[0;32mInstalling/Updating Lighttpd...\033[0m"
|
||||||
|
mkdir -p "$SIMPLE_ADMIN_DIR"
|
||||||
|
wget -O "$SIMPLE_ADMIN_DIR/lighttpd.conf" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/lighttpd.conf
|
||||||
|
wget -O "/lib/systemd/system/lighttpd.service" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/systemd/lighttpd.service
|
||||||
|
ln -sf "/lib/systemd/system/lighttpd.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||||
|
echo "www-data ALL = (root) NOPASSWD: /usr/sbin/iptables, /usr/sbin/ip6tables, /usrdata/simplefirewall/ttl-override, /bin/echo, /bin/cat" > /opt/etc/sudoers.d/www-data
|
||||||
|
|
||||||
|
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
|
||||||
|
-subj "/C=US/ST=MI/L=Romulus/O=RMIITools/CN=localhost" \
|
||||||
|
-keyout $SIMPLE_ADMIN_DIR/server.key -out $SIMPLE_ADMIN_DIR/server.crt
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start lighttpd
|
||||||
|
|
||||||
|
echo -e "\033[0;32mLighttpd installation/update complete.\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_simpleadmin() {
|
||||||
|
remount_rw
|
||||||
|
echo -e "\e[1;31m2) Installing simpleadmin from the $GITTREE branch\e[0m"
|
||||||
|
mkdir $SIMPLE_ADMIN_DIR
|
||||||
|
mkdir $SIMPLE_ADMIN_DIR/systemd
|
||||||
|
mkdir $SIMPLE_ADMIN_DIR/console
|
||||||
|
mkdir $SIMPLE_ADMIN_DIR/console/menu
|
||||||
|
mkdir $SIMPLE_ADMIN_DIR/console/services
|
||||||
|
mkdir $SIMPLE_ADMIN_DIR/console/services/systemd
|
||||||
|
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/$GITTREE/simpleadmin/systemd/lighttpd.service
|
||||||
|
sleep 1
|
||||||
|
cd $SIMPLE_ADMIN_DIR/www
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/deviceinfo.html
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/index.html
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/network.html
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/settings.html
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/sms.html
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/logout.html
|
||||||
|
sleep 1
|
||||||
|
cd $SIMPLE_ADMIN_DIR/www/js
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/js/alpinejs.min.js
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/js/bootstrap.bundle.min.js
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/js/dark-mode.js
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/js/generate-freq-box.js
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/js/parse-settings.js
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/js/populate-checkbox.js
|
||||||
|
sleep 1
|
||||||
|
cd $SIMPLE_ADMIN_DIR/www/css
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/css/bootstrap.min.css
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/css/styles.css
|
||||||
|
sleep 1
|
||||||
|
cd $SIMPLE_ADMIN_DIR/www/cgi-bin
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/cgi-bin/get_atcommand
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/cgi-bin/get_ping
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/cgi-bin/get_sms
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/cgi-bin/get_ttl_status
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/cgi-bin/set_ttl
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/www/cgi-bin/send_sms
|
||||||
|
sleep 1
|
||||||
|
cd /
|
||||||
|
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
||||||
|
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
||||||
|
sleep 1
|
||||||
|
systemctl daemon-reload
|
||||||
|
sleep 1
|
||||||
|
}
|
||||||
|
install_ttyd() {
|
||||||
|
echo -e "\e[1;34mStarting ttyd installation process...\e[0m"
|
||||||
|
cd $SIMPLE_ADMIN_DIR
|
||||||
|
wget -O ttyd https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.armhf && chmod +x ttyd
|
||||||
|
wget -O $SIMPLE_ADMIN_DIR/console/ttyd.bash "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/console/ttyd.bash" && chmod +x console/ttyd.bash
|
||||||
|
wget -O $SIMPLE_ADMIN_DIR/systemd/ttyd.service "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simpleadmin/systemd/ttyd.service"
|
||||||
|
cp -f $SIMPLE_ADMIN_DIR/systemd/ttyd.service /lib/systemd/system/
|
||||||
|
ln -sf /usrdata/simpleadmin/ttyd /bin
|
||||||
|
|
||||||
|
# Enabling and starting ttyd service
|
||||||
|
systemctl daemon-reload
|
||||||
|
ln -sf /lib/systemd/system/ttyd.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
systemctl start ttyd
|
||||||
|
if [ "$?" -ne 0 ]; then
|
||||||
|
echo -e "\e[1;31mFailed to start ttyd service. Please check the systemd service file and ttyd binary.\e[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\e[1;32mInstallation Complete! ttyd server is up.\e[0m"
|
||||||
|
}
|
||||||
|
uninstall_simpleadmin
|
||||||
|
install_lighttpd
|
||||||
|
install_simpleadmin
|
||||||
|
install_ttyd
|
||||||
|
remount_ro
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make the temporary script executable
|
||||||
|
chmod +x "$TMP_SCRIPT"
|
||||||
|
|
||||||
|
# Reload systemd to recognize the new service and start the update
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start $SERVICE_NAME
|
||||||
106
simpleupdates/scripts/update_simplefirewall.sh
Normal file
106
simpleupdates/scripts/update_simplefirewall.sh
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define constants
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
DIR_NAME="simplefirewall"
|
||||||
|
SERVICE_FILE="/lib/systemd/system/install_simplefirewall.service"
|
||||||
|
SERVICE_NAME="install_simplefirewall"
|
||||||
|
TMP_SCRIPT="/tmp/install_simple_firewall.sh"
|
||||||
|
LOG_FILE="/tmp/install_simplefirewall.log"
|
||||||
|
|
||||||
|
# Tmp Script dependent constants
|
||||||
|
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||||
|
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||||
|
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||||
|
|
||||||
|
# Function to remount file system as read-write
|
||||||
|
remount_rw() {
|
||||||
|
mount -o remount,rw /
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to remount file system as read-only
|
||||||
|
remount_ro() {
|
||||||
|
mount -o remount,ro /
|
||||||
|
}
|
||||||
|
remount_rw
|
||||||
|
# Create the systemd service file
|
||||||
|
cat <<EOF > "$SERVICE_FILE"
|
||||||
|
[Unit]
|
||||||
|
Description=Update $DIR_NAME temporary service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create and populate the temporary shell script for installation
|
||||||
|
cat <<EOF > "$TMP_SCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||||
|
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||||
|
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||||
|
|
||||||
|
# Function to remount file system as read-write
|
||||||
|
remount_rw() {
|
||||||
|
mount -o remount,rw /
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to remount file system as read-only
|
||||||
|
remount_ro() {
|
||||||
|
mount -o remount,ro /
|
||||||
|
}
|
||||||
|
remount_rw
|
||||||
|
# Function to remove Simple Firewall
|
||||||
|
uninstall_simple_firewall() {
|
||||||
|
echo "Uninstalling Simplefirewall..."
|
||||||
|
systemctl stop simplefirewall
|
||||||
|
systemctl stop ttl-override
|
||||||
|
rm -f /lib/systemd/system/simplefirewall.service
|
||||||
|
rm -f /lib/systemd/system/ttl-override.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
rm -rf "$SIMPLE_FIREWALL_DIR"
|
||||||
|
echo "Simplefirewall uninstalled."
|
||||||
|
}
|
||||||
|
# Function to install Simple Firewall
|
||||||
|
install_simple_firewall() {
|
||||||
|
systemctl stop simplefirewall
|
||||||
|
systemctl stop ttl-override
|
||||||
|
echo -e "\033[0;32mInstalling/Updating Simple Firewall...\033[0m"
|
||||||
|
mount -o remount,rw /
|
||||||
|
mkdir -p "$SIMPLE_FIREWALL_DIR"
|
||||||
|
mkdir -p "$SIMPLE_FIREWALL_SYSTEMD_DIR"
|
||||||
|
wget -O "$SIMPLE_FIREWALL_DIR/simplefirewall.sh" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/simplefirewall.sh
|
||||||
|
wget -O "$SIMPLE_FIREWALL_DIR/ttl-override" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttl-override
|
||||||
|
wget -O "$SIMPLE_FIREWALL_DIR/ttlvalue" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttlvalue
|
||||||
|
chmod 666 $SIMPLE_FIREWALL_DIR/ttlvalue
|
||||||
|
chmod +x "$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||||
|
chmod +x "$SIMPLE_FIREWALL_DIR/ttl-override"
|
||||||
|
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/simplefirewall.service
|
||||||
|
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/ttl-override.service" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/ttl-override.service
|
||||||
|
cp -rf $SIMPLE_FIREWALL_SYSTEMD_DIR/* /lib/systemd/system
|
||||||
|
ln -sf "/lib/systemd/system/simplefirewall.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||||
|
ln -sf "/lib/systemd/system/ttl-override.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start simplefirewall
|
||||||
|
systemctl start ttl-override
|
||||||
|
echo -e "\033[0;32mSimple Firewall installation/update complete.\033[0m"
|
||||||
|
}
|
||||||
|
uninstall_simple_firewall
|
||||||
|
install_simple_firewall
|
||||||
|
remount_ro
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make the temporary script executable
|
||||||
|
chmod +x "$TMP_SCRIPT"
|
||||||
|
|
||||||
|
# Reload systemd to recognize the new service and start the update
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start $SERVICE_NAME
|
||||||
46
simpleupdates/scripts/update_simpleupdates.sh
Normal file
46
simpleupdates/scripts/update_simpleupdates.sh
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# WORK IN PROGRESS
|
||||||
|
|
||||||
|
# Define constants
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
DIR_NAME="simpleupdates"
|
||||||
|
SERVICE_FILE="/lib/systemd/system/install_simpleupdates.service"
|
||||||
|
SERVICE_NAME="install_simpleupdates"
|
||||||
|
TMP_SCRIPT="/tmp/install_simpleupdates.sh"
|
||||||
|
LOG_FILE="/tmp/install_simpleupdates.log"
|
||||||
|
|
||||||
|
# Tmp Script dependent constants
|
||||||
|
|
||||||
|
|
||||||
|
# Create the systemd service file
|
||||||
|
cat <<EOF > "$SERVICE_FILE"
|
||||||
|
[Unit]
|
||||||
|
Description=Update $DIR_NAME temporary service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create and populate the temporary shell script for installation
|
||||||
|
cat <<EOF > "$TMP_SCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
install_simpleupdates() {
|
||||||
|
# CONTENT
|
||||||
|
}
|
||||||
|
install_simpleupdates
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make the temporary script executable
|
||||||
|
chmod +x "$TMP_SCRIPT"
|
||||||
|
|
||||||
|
# Reload systemd to recognize the new service and start the update
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start $SERVICE_NAME
|
||||||
147
simpleupdates/scripts/update_socat-at-bridge.sh
Normal file
147
simpleupdates/scripts/update_socat-at-bridge.sh
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define constants
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
DIR_NAME="socat-at-bridge"
|
||||||
|
SERVICE_FILE="/lib/systemd/system/install_socat-at-bridge.service"
|
||||||
|
SERVICE_NAME="install_socat-at-bridge"
|
||||||
|
TMP_SCRIPT="/tmp/install_socat-at-bridge.sh"
|
||||||
|
LOG_FILE="/tmp/install_socat-at-bridge.log"
|
||||||
|
|
||||||
|
# Tmp Script dependent constants
|
||||||
|
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||||
|
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||||
|
# Function to remount file system as read-write
|
||||||
|
remount_rw() {
|
||||||
|
mount -o remount,rw /
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to remount file system as read-only
|
||||||
|
remount_ro() {
|
||||||
|
mount -o remount,ro /
|
||||||
|
}
|
||||||
|
remount_rw
|
||||||
|
# Create the systemd service file
|
||||||
|
cat <<EOF > "$SERVICE_FILE"
|
||||||
|
[Unit]
|
||||||
|
Description=Update $DIR_NAME temporary service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create and populate the temporary shell script for installation
|
||||||
|
cat <<EOF > "$TMP_SCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||||
|
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||||
|
|
||||||
|
# Function to remount file system as read-write
|
||||||
|
remount_rw() {
|
||||||
|
mount -o remount,rw /
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to remount file system as read-only
|
||||||
|
remount_ro() {
|
||||||
|
mount -o remount,ro /
|
||||||
|
}
|
||||||
|
remount_rw
|
||||||
|
uninstall_at_socat() {
|
||||||
|
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||||
|
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||||
|
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||||
|
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||||
|
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||||
|
systemctl daemon-reload > /dev/null 2>&1
|
||||||
|
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
install_at_socat() {
|
||||||
|
# Install service units
|
||||||
|
echo -e "\033[0;32mInstalling AT Socat Bridge services...\033[0m"
|
||||||
|
mkdir $SOCAT_AT_DIR
|
||||||
|
cd $SOCAT_AT_DIR
|
||||||
|
mkdir $SOCAT_AT_SYSD_DIR
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/socat-armel-static
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/killsmd7bridge
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/atcmd
|
||||||
|
cd $SOCAT_AT_SYSD_DIR
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11.service
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11-from-ttyIN.service
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11-to-ttyIN.service
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-killsmd7bridge.service
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7-from-ttyIN2.service
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7-to-ttyIN2.service
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7.service
|
||||||
|
|
||||||
|
# Set execute permissions
|
||||||
|
cd $SOCAT_AT_DIR
|
||||||
|
chmod +x socat-armel-static
|
||||||
|
chmod +x killsmd7bridge
|
||||||
|
chmod +x atcmd
|
||||||
|
|
||||||
|
# Link new command for AT Commands from the shell
|
||||||
|
ln -sf $SOCAT_AT_DIR/atcmd /bin
|
||||||
|
|
||||||
|
# Install service units
|
||||||
|
echo -e "\033[0;32mAdding AT Socat Bridge systemd service units...\033[0m"
|
||||||
|
cp -rf $SOCAT_AT_SYSD_DIR/*.service /lib/systemd/system
|
||||||
|
ln -sf /lib/systemd/system/socat-killsmd7bridge.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
ln -sf /lib/systemd/system/socat-smd11.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
ln -sf /lib/systemd/system/socat-smd11-to-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
ln -sf /lib/systemd/system/socat-smd11-from-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
ln -sf /lib/systemd/system/socat-smd7.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
ln -sf /lib/systemd/system/socat-smd7-to-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
ln -sf /lib/systemd/system/socat-smd7-from-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start socat-smd11
|
||||||
|
sleep 2s
|
||||||
|
systemctl start socat-smd11-to-ttyIN
|
||||||
|
systemctl start socat-smd11-from-ttyIN
|
||||||
|
echo -e "\033[0;32mAT Socat Bridge service online: smd11 to ttyOUT\033[0m"
|
||||||
|
systemctl start socat-killsmd7bridge
|
||||||
|
sleep 1s
|
||||||
|
systemctl start socat-smd7
|
||||||
|
sleep 2s
|
||||||
|
systemctl start socat-smd7-to-ttyIN2
|
||||||
|
systemctl start socat-smd7-from-ttyIN2
|
||||||
|
echo -e "\033[0;32mAT Socat Bridge service online: smd7 to ttyOUT2\033[0m"
|
||||||
|
remount_ro
|
||||||
|
cd /
|
||||||
|
echo -e "\033[0;32mAT Socat Bridge services Installed!\033[0m"
|
||||||
|
}
|
||||||
|
uninstall_at_socat
|
||||||
|
install_at_socat
|
||||||
|
remount_ro
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make the temporary script executable
|
||||||
|
chmod +x "$TMP_SCRIPT"
|
||||||
|
|
||||||
|
# Reload systemd to recognize the new service and start the update
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start $SERVICE_NAME
|
||||||
73
simpleupdates/scripts/update_sshd.sh
Normal file
73
simpleupdates/scripts/update_sshd.sh
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define constants
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
DIR_NAME="simpleupdates"
|
||||||
|
SERVICE_FILE="/lib/systemd/system/install_sshd.service"
|
||||||
|
SERVICE_NAME="install_sshd"
|
||||||
|
TMP_SCRIPT="/tmp/install_sshd.sh"
|
||||||
|
LOG_FILE="/tmp/install_sshd.log"
|
||||||
|
|
||||||
|
# Tmp Script dependent constants
|
||||||
|
|
||||||
|
|
||||||
|
# Create the systemd service file
|
||||||
|
cat <<EOF > "$SERVICE_FILE"
|
||||||
|
[Unit]
|
||||||
|
Description=Update $DIR_NAME temporary service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create and populate the temporary shell script for installation
|
||||||
|
cat <<EOF > "$TMP_SCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
|
||||||
|
install_sshd() {
|
||||||
|
echo -e "\e[1;32mOpenSSH Server\e[0m"
|
||||||
|
remount_rw
|
||||||
|
|
||||||
|
mkdir /usrdata/sshd
|
||||||
|
wget -O /lib/systemd/system/sshd.service "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/sshd/sshd.service"
|
||||||
|
ln -sf "/lib/systemd/system/sshd.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||||
|
|
||||||
|
opkg install openssh-server-pam
|
||||||
|
for script in /opt/etc/init.d/*sshd*; do
|
||||||
|
if [ -f "$script" ]; then
|
||||||
|
echo "Removing existing sshd init script: $script"
|
||||||
|
rm "$script" # Remove the script if it contains 'sshd' in its name
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
/opt/bin/ssh-keygen -A
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable sshd
|
||||||
|
|
||||||
|
# Enable PAM and PermitRootLogin
|
||||||
|
sed -i "s/^.*UsePAM .*/UsePAM yes/" "/opt/etc/ssh/sshd_config"
|
||||||
|
sed -i "s/^.*PermitRootLogin .*/PermitRootLogin yes/" "/opt/etc/ssh/sshd_config"
|
||||||
|
|
||||||
|
# Ensure the sshd user exists in the /opt/etc/passwd file
|
||||||
|
grep "sshd:x:106" /opt/etc/passwd || echo "sshd:x:106:65534:Linux User,,,:/opt/run/sshd:/bin/nologin" >> /opt/etc/passwd
|
||||||
|
systemctl start sshd
|
||||||
|
|
||||||
|
echo -e "\e[1;32mOpenSSH installed!!\e[0m"
|
||||||
|
}
|
||||||
|
install_sshd
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make the temporary script executable
|
||||||
|
chmod +x "$TMP_SCRIPT"
|
||||||
|
|
||||||
|
# Reload systemd to recognize the new service and start the update
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start $SERVICE_NAME
|
||||||
87
simpleupdates/scripts/update_tailscale.sh
Normal file
87
simpleupdates/scripts/update_tailscale.sh
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define constants
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
DIR_NAME="tailscale"
|
||||||
|
SERVICE_FILE="/lib/systemd/system/install_tailscale.service"
|
||||||
|
SERVICE_NAME="install_tailscale"
|
||||||
|
TMP_SCRIPT="/tmp/install_tailscale.sh"
|
||||||
|
LOG_FILE="/tmp/install_sshd.log"
|
||||||
|
|
||||||
|
# Tmp Script dependent constants
|
||||||
|
TAILSCALE_DIR="/usrdata/tailscale/"
|
||||||
|
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||||
|
|
||||||
|
# Create the systemd service file
|
||||||
|
cat <<EOF > "$SERVICE_FILE"
|
||||||
|
[Unit]
|
||||||
|
Description=Update $DIR_NAME temporary service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create and populate the temporary shell script for installation
|
||||||
|
cat <<EOF > "$TMP_SCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="development"
|
||||||
|
TAILSCALE_DIR="/usrdata/tailscale/"
|
||||||
|
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||||
|
|
||||||
|
install_update_tailscale() {
|
||||||
|
echo "Checking if Tailscale is already installed..."
|
||||||
|
if [ -f "$TAILSCALE_DIR/tailscale" ]; then
|
||||||
|
echo "Tailscale binary found. Updating Tailscale..."
|
||||||
|
ln -sf "$TAILSCALE_DIR/tailscale" "/usrdata/root/bin/tailscale"
|
||||||
|
echo y | $TAILSCALE_DIR/tailscale update
|
||||||
|
echo -e "\e[32mTailscale updated!\e[0m"
|
||||||
|
remount_ro
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Installing Tailscale..."
|
||||||
|
mkdir -p "$TAILSCALE_DIR" "$TAILSCALE_SYSD_DIR"
|
||||||
|
echo "Downloading binary files..."
|
||||||
|
cd /usrdata
|
||||||
|
wget https://pkgs.tailscale.com/stable/tailscale_1.64.0_arm.tgz
|
||||||
|
tar -xzf tailscale_1.64.0_arm.tgz
|
||||||
|
cd tailscale_1.64.0_arm
|
||||||
|
mv tailscale tailscaled "$TAILSCALE_DIR/"
|
||||||
|
rm -rf /usrdata/tailscale_1.64.0_arm
|
||||||
|
echo "Downloading systemd files..."
|
||||||
|
cd "$TAILSCALE_SYSD_DIR"
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.service
|
||||||
|
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.defaults
|
||||||
|
sleep 2s
|
||||||
|
echo "Setting Permissions..."
|
||||||
|
chmod +x "$TAILSCALE_DIR/tailscaled" "$TAILSCALE_DIR/tailscale"
|
||||||
|
echo "Copying systemd units..."
|
||||||
|
cp -rf "$TAILSCALE_SYSD_DIR"/* /lib/systemd/system/
|
||||||
|
ln -sf /lib/systemd/system/tailscaled.service /lib/systemd/system/multi-user.target.wants/
|
||||||
|
systemctl daemon-reload
|
||||||
|
echo "Starting Tailscaled..."
|
||||||
|
systemctl start tailscaled
|
||||||
|
cd /
|
||||||
|
remount_ro
|
||||||
|
echo -e "\e[32mTailscale installed successfully.\e[0m"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute the function
|
||||||
|
install_update_tailscale
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make the temporary script executable
|
||||||
|
chmod +x "$TMP_SCRIPT"
|
||||||
|
|
||||||
|
# Reload systemd to recognize the new service and start the update
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start $SERVICE_NAME
|
||||||
12
simpleupdates/simpleadmin.conf
Normal file
12
simpleupdates/simpleadmin.conf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Enable or disable update checks
|
||||||
|
CONF_ENABLED=no
|
||||||
|
# Check for updates at boot
|
||||||
|
CHECK_AT_BOOT=no
|
||||||
|
# Update frequency: daily, weekly, monthly, or none
|
||||||
|
UPDATE_FREQUENCY=none
|
||||||
|
# Scheduled time for updates (24-hour UTC format)
|
||||||
|
SCHEDULED_TIME=00:00
|
||||||
|
# Day for weekly updates (e.g., Mon, Tues, Wed, Thurs, Fri)
|
||||||
|
WEEKLY_DAY=
|
||||||
|
# Date for monthly updates (e.g., 15 for the 15th of the month)
|
||||||
|
MONTHLY_DATE=
|
||||||
255
simpleupdates/simpleupdate
Normal file
255
simpleupdates/simpleupdate
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Configuration and directories
|
||||||
|
CONFIG_FILE="/usrdata/simpleupdates/simpleupdate.conf"
|
||||||
|
GITUSER="iamromulan"
|
||||||
|
GITTREE="main"
|
||||||
|
DIRECTORIES=("simpleadmin" "socat-at-bridge" "simplefirewall" "tailscale" "ttyd")
|
||||||
|
BASE_URL="https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE"
|
||||||
|
LOG_FILE="/tmp/simpleupdate.log"
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
load_config() {
|
||||||
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
else
|
||||||
|
echo "Configuration file ($CONFIG_FILE) not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to trim the log file to the last 100 lines
|
||||||
|
trim_log_file() {
|
||||||
|
tail -n 100 "$LOG_FILE" > "$LOG_FILE.tmp" && mv "$LOG_FILE.tmp" "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check for updates
|
||||||
|
check_for_updates() {
|
||||||
|
echo "$(date): Checking for updates..."
|
||||||
|
for dir in "${DIRECTORIES[@]}"; do
|
||||||
|
local remote_rev=$(wget -qO- "$BASE_URL/$dir/.rev")
|
||||||
|
local local_rev_file="/usrdata/$dir/.rev"
|
||||||
|
|
||||||
|
if [[ ! -f "$local_rev_file" ]]; then
|
||||||
|
echo "No local revision file found for $dir, skipping."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
local local_rev=$(cat "$local_rev_file")
|
||||||
|
|
||||||
|
if [[ "$remote_rev" -gt "$local_rev" ]]; then
|
||||||
|
echo "Update available for $dir, updating..."
|
||||||
|
wget -qO "/tmp/update_${dir}.sh" "$BASE_URL/simpleupdates/scripts/update_${dir}.sh"
|
||||||
|
chmod +x "/tmp/update_${dir}.sh"
|
||||||
|
"/tmp/update_${dir}.sh"
|
||||||
|
else
|
||||||
|
echo "$dir is up to date."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
trim_log_file
|
||||||
|
wait_to_update
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to wait and trigger updates based on scheduling
|
||||||
|
wait_to_update() {
|
||||||
|
echo "Waiting for the next update check according to schedule..."
|
||||||
|
while true; do
|
||||||
|
local current_time=$(date "+%H:%M")
|
||||||
|
local current_day=$(date "+%a")
|
||||||
|
local current_date=$(date "+%d")
|
||||||
|
|
||||||
|
case $UPDATE_FREQUENCY in
|
||||||
|
daily)
|
||||||
|
if [[ "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||||
|
check_for_updates
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
weekly)
|
||||||
|
if [[ "$current_day" == "$WEEKLY_DAY" && "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||||
|
check_for_updates
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
monthly)
|
||||||
|
if [[ "$current_date" == "$MONTHLY_DATE" && "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||||
|
check_for_updates
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
none)
|
||||||
|
echo "Update checking is disabled by frequency setting."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
sleep 30 # Sleep for 30 seconds for more granular checks
|
||||||
|
trim_log_file
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Daemon mode to wait and trigger updates based on scheduling
|
||||||
|
daemon_mode() {
|
||||||
|
load_config
|
||||||
|
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||||
|
echo "Daemon mode started."
|
||||||
|
# Validate only one update frequency is defined
|
||||||
|
frequency_count=0
|
||||||
|
[[ "$UPDATE_FREQUENCY" == "daily" ]] && ((frequency_count++))
|
||||||
|
[[ "$UPDATE_FREQUENCY" == "weekly" ]] && ((frequency_count++))
|
||||||
|
[[ "$UPDATE_FREQUENCY" == "monthly" ]] && ((frequency_count++))
|
||||||
|
|
||||||
|
if [[ $frequency_count -gt 1 ]]; then
|
||||||
|
echo "Error: More than one update frequency is defined. Exiting."
|
||||||
|
exit 1
|
||||||
|
elif [[ $frequency_count -eq 0 && "$UPDATE_FREQUENCY" != "none" ]]; then
|
||||||
|
echo "Error: No valid update frequency defined. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ "$CONF_ENABLED" == "no" ]]; then
|
||||||
|
echo "Updates are disabled in the configuration."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$CHECK_AT_BOOT" == "yes" ]]; then
|
||||||
|
check_for_updates
|
||||||
|
else
|
||||||
|
wait_to_update
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check for updates
|
||||||
|
force_check_for_updates() {
|
||||||
|
echo "$(date): Checking for updates..."
|
||||||
|
for dir in "${DIRECTORIES[@]}"; do
|
||||||
|
local remote_rev=$(wget -qO- "$BASE_URL/$dir/.rev")
|
||||||
|
local local_rev_file="/usrdata/$dir/.rev"
|
||||||
|
|
||||||
|
if [[ ! -f "$local_rev_file" ]]; then
|
||||||
|
echo "No local revision file found for $dir, skipping."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
local local_rev=$(cat "$local_rev_file")
|
||||||
|
|
||||||
|
if [[ "$remote_rev" -gt "$local_rev" ]]; then
|
||||||
|
echo "Update available for $dir, updating..."
|
||||||
|
wget -qO "/tmp/update_${dir}.sh" "$BASE_URL/simpleupdates/scripts/update_${dir}.sh"
|
||||||
|
chmod +x "/tmp/update_${dir}.sh"
|
||||||
|
"/tmp/update_${dir}.sh"
|
||||||
|
else
|
||||||
|
echo "$dir is up to date."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper function to load and update the configuration
|
||||||
|
update_config() {
|
||||||
|
local key="$1"
|
||||||
|
local value="$2"
|
||||||
|
if grep -q "^$key=" "$CONFIG_FILE"; then
|
||||||
|
sed -i "s|^$key=.*|$key=$value|" "$CONFIG_FILE"
|
||||||
|
else
|
||||||
|
echo "$key=$value" >> "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display the current configuration status
|
||||||
|
status() {
|
||||||
|
echo "Current Configuration Status:"
|
||||||
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
|
while IFS= read -r line; do
|
||||||
|
echo "$line"
|
||||||
|
done < "$CONFIG_FILE"
|
||||||
|
else
|
||||||
|
echo "Configuration file not found."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enable automatic updates
|
||||||
|
enable_updates() {
|
||||||
|
update_config "CONF_ENABLED" "yes"
|
||||||
|
echo "Automatic updates have been enabled."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Disable automatic updates
|
||||||
|
disable_updates() {
|
||||||
|
update_config "CONF_ENABLED" "no"
|
||||||
|
echo "Automatic updates have been disabled."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Interactive setup for the update configuration
|
||||||
|
setup() {
|
||||||
|
read -p "Enable automatic updates? [yes/no]: " enable_updates
|
||||||
|
if [[ "$enable_updates" == "yes" ]]; then
|
||||||
|
enable_updates
|
||||||
|
else
|
||||||
|
disable_updates
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -p "Check for updates at boot? [yes/no]: " check_boot
|
||||||
|
update_config "CHECK_AT_BOOT" "$check_boot"
|
||||||
|
|
||||||
|
read -p "Update frequency (none, daily, weekly, monthly): " frequency
|
||||||
|
update_config "UPDATE_FREQUENCY" "$frequency"
|
||||||
|
|
||||||
|
case $frequency in
|
||||||
|
daily)
|
||||||
|
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||||
|
update_config "SCHEDULED_TIME" "$time"
|
||||||
|
;;
|
||||||
|
weekly)
|
||||||
|
echo "Please enter the day of the week."
|
||||||
|
read -p "Day (full name or abbreviation, e.g., Monday or Mon): " day_input
|
||||||
|
# Normalize input to abbreviated form
|
||||||
|
day_abbr=$(date -d "$day_input" +%a 2>/dev/null)
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "Invalid day of the week. Please try again."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
update_config "WEEKLY_DAY" "$day_abbr"
|
||||||
|
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||||
|
update_config "SCHEDULED_TIME" "$time"
|
||||||
|
;;
|
||||||
|
monthly)
|
||||||
|
read -p "Date of the month (1-31): " date
|
||||||
|
update_config "MONTHLY_DATE" "$date"
|
||||||
|
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||||
|
update_config "SCHEDULED_TIME" "$time"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "No scheduling will be set."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "Update configuration has been set."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Command operations: status, enable, disable, update, setup
|
||||||
|
case "$1" in
|
||||||
|
d)
|
||||||
|
daemon_mode
|
||||||
|
;;
|
||||||
|
update)
|
||||||
|
load_config
|
||||||
|
force_check_for_updates
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
enable)
|
||||||
|
enable_updates
|
||||||
|
;;
|
||||||
|
disable)
|
||||||
|
disable_updates
|
||||||
|
;;
|
||||||
|
setup)
|
||||||
|
setup
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage:"
|
||||||
|
echo "d: Run as a background check daemon"
|
||||||
|
echo "update: Force check for and install updates"
|
||||||
|
echo "status: Display current set update schedule"
|
||||||
|
echo "enable: Enable automatic updates"
|
||||||
|
echo "disable: Disable automatic updates"
|
||||||
|
echo "setup: Set up an automatic update schedule"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
10
simpleupdates/systemd/simpleupdated.service
Normal file
10
simpleupdates/systemd/simpleupdated.service
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Simple Update Daemon
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usrdata/simpleupdates/simpleupdate d
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
1
socat-at-bridge/.rev
Normal file
1
socat-at-bridge/.rev
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
@@ -10,24 +10,15 @@ setup_device() {
|
|||||||
-echoctl -echoke noflsh -ixon -crtscts
|
-echoctl -echoke noflsh -ixon -crtscts
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prepare the device for communication
|
# Function to send AT command and capture the output
|
||||||
setup_device
|
send_at_command() {
|
||||||
|
local command="$1"
|
||||||
echo -e "\033[0;36mType 'exit' to end the session.\033[0m"
|
|
||||||
while true; do
|
|
||||||
echo -en "\033[0;36mEnter AT Command: \033[0m"
|
|
||||||
read user_input
|
|
||||||
|
|
||||||
if [[ "$user_input" == "exit" ]]; then
|
|
||||||
echo -e "\033[0;32mExiting...\033[0m"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clear the device buffer before sending a new command
|
# Clear the device buffer before sending a new command
|
||||||
echo -n > $DEVICE
|
echo -n > $DEVICE
|
||||||
|
|
||||||
# Send the AT command
|
# Send the AT command, preserving the integrity of the input
|
||||||
echo -e "$user_input\r" > $DEVICE
|
echo -e "$command\r" > $DEVICE
|
||||||
|
|
||||||
# Use a temporary file to capture the command output
|
# Use a temporary file to capture the command output
|
||||||
tmpfile=$(mktemp)
|
tmpfile=$(mktemp)
|
||||||
@@ -52,4 +43,27 @@ while true; do
|
|||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
rm "$tmpfile"
|
rm "$tmpfile"
|
||||||
done
|
}
|
||||||
|
|
||||||
|
# Prepare the device for communication
|
||||||
|
setup_device
|
||||||
|
|
||||||
|
# Check if an AT command is provided as an argument
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
# Concatenate all arguments to handle commands with spaces and/or quotes correctly
|
||||||
|
FULL_CMD="$*"
|
||||||
|
send_at_command "$FULL_CMD"
|
||||||
|
else
|
||||||
|
echo -e "\033[0;36mType 'exit' to end the session.\033[0m"
|
||||||
|
while true; do
|
||||||
|
echo -en "\033[0;36mEnter AT Command: \033[0m"
|
||||||
|
read user_input
|
||||||
|
|
||||||
|
if [[ "$user_input" == "exit" ]]; then
|
||||||
|
echo -e "\033[0;32mExiting...\033[0m"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
send_at_command "$user_input"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Description=Socat Serial Emulation for smd11
|
|||||||
After=ql-netd.service
|
After=ql-netd.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN,raw,echo=0 pty,link=/dev/ttyOUT,raw,echo=1
|
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN,raw,echo=0,group=20,perm=660 pty,link=/dev/ttyOUT,raw,echo=1,group=20,perm=660
|
||||||
# Add a delay to prevent the clients from starting too early
|
# Add a delay to prevent the clients from starting too early
|
||||||
ExecStartPost=/bin/sleep 2s
|
ExecStartPost=/bin/sleep 2s
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Description=Socat Serial Emulation for smd7
|
|||||||
After=ql-netd.service
|
After=ql-netd.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN2,raw,echo=0 pty,link=/dev/ttyOUT2,raw,echo=1
|
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN2,raw,echo=0,group=20,perm=660 pty,link=/dev/ttyOUT2,raw,echo=1,group=20,perm=660
|
||||||
# Add a delay to prevent the clients from starting too early
|
# Add a delay to prevent the clients from starting too early
|
||||||
ExecStartPost=/bin/sleep 2s
|
ExecStartPost=/bin/sleep 2s
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|||||||
17
sshd/sshd.service
Normal file
17
sshd/sshd.service
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=OpenBSD Secure Shell server
|
||||||
|
Documentation=man:sshd(8) man:sshd_config(5)
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
PIDFile=/opt/var/run/sshd.pid
|
||||||
|
ExecStartPre=/opt/sbin/sshd -t
|
||||||
|
ExecStart=/opt/sbin/sshd -D
|
||||||
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
|
KillMode=process
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
Alias=sshd.service
|
||||||
1
tailscale/.rev
Normal file
1
tailscale/.rev
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,101 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
DEVICE_FILE="/dev/smd7"
|
|
||||||
ICCID_FILE="/path/to/iccid_master_file" # Path to the ICCID-APN-IPType master file
|
|
||||||
TMP_DIR="/tmp"
|
|
||||||
TIMEOUT=4
|
|
||||||
|
|
||||||
# Start listening to device file
|
|
||||||
start_listening() {
|
|
||||||
cat "$DEVICE_FILE" > "$TMP_DIR/device_readout" &
|
|
||||||
CAT_PID=$!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Send AT command
|
|
||||||
send_at_command() {
|
|
||||||
local command=$1
|
|
||||||
echo -e "${command}\r" > "$DEVICE_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Wait for and process response
|
|
||||||
wait_for_response() {
|
|
||||||
local start_time=$(date +%s)
|
|
||||||
local current_time
|
|
||||||
local elapsed_time
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
if grep -q "OK" "$TMP_DIR/device_readout" || grep -q "ERROR" "$TMP_DIR/device_readout"; then
|
|
||||||
RESPONSE=$(cat "$TMP_DIR/device_readout")
|
|
||||||
echo "Response received: $RESPONSE"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
current_time=$(date +%s)
|
|
||||||
elapsed_time=$((current_time - start_time))
|
|
||||||
if [ "$elapsed_time" -ge "$TIMEOUT" ]; then
|
|
||||||
echo "Error: Response timed out."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cleanup function
|
|
||||||
cleanup() {
|
|
||||||
kill "$CAT_PID"
|
|
||||||
wait "$CAT_PID" 2>/dev/null
|
|
||||||
rm -f "$TMP_DIR/device_readout"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to send AT command and wait for response
|
|
||||||
send_and_wait() {
|
|
||||||
send_at_command "$1"
|
|
||||||
wait_for_response
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to update the APN
|
|
||||||
update_apn() {
|
|
||||||
local slot=$1
|
|
||||||
local apn=$2
|
|
||||||
local iptype=$3
|
|
||||||
send_and_wait "AT+CGDCONT=$slot,\"$iptype\",\"$apn\""
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "APN updated successfully."
|
|
||||||
else
|
|
||||||
echo "Failed to update APN."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main Execution
|
|
||||||
if [ -c "$DEVICE_FILE" ]; then
|
|
||||||
start_listening
|
|
||||||
|
|
||||||
# Get ICCID
|
|
||||||
send_and_wait "AT+CCID"
|
|
||||||
ICCID=$(echo "$RESPONSE" | grep "+CCID" | cut -d ':' -f2 | tr -d '[:space:]')
|
|
||||||
echo "ICCID: $ICCID"
|
|
||||||
|
|
||||||
# Check ICCID in master file
|
|
||||||
if grep -q "$ICCID" "$ICCID_FILE"; then
|
|
||||||
APN=$(grep "$ICCID" "$ICCID_FILE" | cut -d ',' -f2)
|
|
||||||
IP_TYPE=$(grep "$ICCID" "$ICCID_FILE" | cut -d ',' -f3)
|
|
||||||
IP_TYPE=${IP_TYPE:-"IPV4V6"} # Default to IPV4V6 if not specified
|
|
||||||
|
|
||||||
# Get current APN settings
|
|
||||||
send_and_wait "AT+CGDCONT?"
|
|
||||||
CURRENT_APN=$(echo "$RESPONSE" | grep "+CGDCONT: 1" | cut -d ',' -f3 | tr -d '"')
|
|
||||||
|
|
||||||
# Compare and update APN if necessary
|
|
||||||
if [ "$APN" != "$CURRENT_APN" ]; then
|
|
||||||
update_apn 1 "$APN" "$IP_TYPE"
|
|
||||||
else
|
|
||||||
echo "No APN update needed."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "ICCID not found in the master file."
|
|
||||||
fi
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
echo "Error: Device $DEVICE_FILE does not exist or is not a character special file."
|
|
||||||
fi
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
edit_iccid_file() {
|
|
||||||
local iccid_file="/path/to/iccid_master_file" # Path to the ICCID-APN-IPType master file
|
|
||||||
|
|
||||||
echo "Enter ICCID to add or edit:"
|
|
||||||
read iccid
|
|
||||||
echo "Enter APN for $iccid:"
|
|
||||||
read apn
|
|
||||||
echo "Enter IP Type (IPV4, IPV6, IPV4V6) for $iccid [Default: IPV4V6]:"
|
|
||||||
read iptype
|
|
||||||
iptype=${iptype:-"IPV4V6"} # Default to IPV4V6 if not specified
|
|
||||||
|
|
||||||
# Check if ICCID already exists
|
|
||||||
if grep -q "$iccid" "$iccid_file"; then
|
|
||||||
# Update existing ICCID's APN and IP Type
|
|
||||||
sed -i "/$iccid/c\\$iccid,$apn,$iptype" "$iccid_file"
|
|
||||||
else
|
|
||||||
# Add new ICCID, APN, and IP Type
|
|
||||||
echo "$iccid,$apn,$iptype" >> "$iccid_file"
|
|
||||||
fi
|
|
||||||
echo "ICCID file updated."
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=TTYD Service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
ExecStartPre=/bin/sleep 5
|
|
||||||
ExecStart=/usrdata/ttyd/ttyd -p 443 -t 'theme={"foreground":"white","background":"black"}' -t fontSize=25 --writable /usrdata/ttyd/scripts/ttyd.bash
|
|
||||||
Restart=on-failure
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
Reference in New Issue
Block a user