Archive Simpleadmin 1.0
This commit is contained in:
141
old/original_main_repo/README.md
Normal file
141
old/original_main_repo/README.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# ORIGINAL PROJECT PRESERVED HERE
|
||||
|
||||
# RGMII Toolkit
|
||||
## Software deployment Toolkit for Quectel RM5xxx series 5G modems utilizing an m.2 to RJ45 adapter (RGMII)
|
||||
|
||||
Current Branch: **Main**
|
||||
|
||||
Please Fork and PR with/to [Development](https://github.com/iamromulan/quectel-rgmii-toolkit/tree/development) instead of main, it has the latest changes and is meant to be commits ahead of main for testing. :)
|
||||
|
||||
"Don't push to production 😂"
|
||||
|
||||
Fork development, and PR development to development :)
|
||||
|
||||
|
||||
|
||||
|
||||
#### [JUMP TO HOW TO USE](#how-to-use)
|
||||
**Currently:** This will allow you to install or if already installed, update, remove, or modify:
|
||||
- Simple Admin: A simple web interface for managing your Quectel m.2 modem through it's gateway address
|
||||
- It will install socat-at-bridge: sets up ttyOUT and ttyOUT2 for AT commands. You'll be able to use the `atcmd` command as well for an interactive at command session from adb, ssh, or ttyd
|
||||
- It will install simplefirewall: A simple firewall that blocks definable incoming ports and a TTL mangle option/modifier. As of now only the TTL is controllable through Simple Admin. You can edit port block options and TTL from the 3rd option in the toolkit
|
||||
- Tailscale: A magic VPN for accessing Simple Admin, SSH, and ttyd on the go. The Toolkit installs the Tailscale client directly to the modem and allows you to login and configure other settings. Head over to tailscale.com to sign up for a free account and learn more.
|
||||
- Schedule a Daily Reboot at a specified time
|
||||
- A fix for certain modems that don't start in CFUN=1 mode
|
||||
- Entware/OPKG: A package installer/manager/repo
|
||||
- Run `opkg help` to see how to use it
|
||||
- These packages are installable: https://bin.entware.net/armv7sf-k3.2/Packages.html
|
||||
- TTYd: A shell session right from your browser
|
||||
- Currently this uses port 443 but SSL/TLS is not in use (http only for now)
|
||||
- Entware/OPKG is required so it will install it if it isn't installed
|
||||
- This will replace the stock Quectel login and passwd binaries with ones from entware
|
||||
|
||||
|
||||
|
||||
**My goal** is for this to also include any new useful scripts or software for this modem and others that support RGMII mode.
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## How to Use
|
||||
**To run the Toolkit:**
|
||||
- Open ADB & Fastboot++ covered in [Using ADB](https://github.com/iamromulan/quectel-rgmii-configuration-notes?tab=readme-ov-file#unlocking-and-using-adb) or just use adb
|
||||
- Make sure your modem is connected by USB to your computer
|
||||
- Run `adb devices` to make sure your modem is detected by adb
|
||||
- Run `adb shell ping 8.8.8.8` to make sure the shell can access the internet. If you get an error, make sure the modem is connected to a cellular network and make sure `AT+QMAPWAC=1` as covered in the troubleshooting section: [I Can't get internet access from the Ethernet port (Common)](https://github.com/iamromulan/quectel-rgmii-configuration-notes/tree/main?tab=readme-ov-file#i-cant-get-internet-access-from-the-ethernet-port-common)
|
||||
- If you don't get an error you should be getting replies back endlessly, press `CTRL-C` to stop it.
|
||||
- Simply Copy/Paste this into your Command Prompt/Shell
|
||||
```bash
|
||||
adb shell "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 /
|
||||
```
|
||||
|
||||
**Or, if you want to stay in the modems shell when you are done**
|
||||
|
||||
```
|
||||
adb shell
|
||||
```
|
||||
Then run
|
||||
```
|
||||
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 /
|
||||
```
|
||||
**You should see:**
|
||||
|
||||
|
||||

|
||||
|
||||
## Tailscale Installation and Config
|
||||
|
||||
> :warning: Your modem must already be connected to the internet for this to install
|
||||
### Installation:
|
||||
Open up the toolkit main menu and **press 4** to enter the Tailscale menu
|
||||
|
||||

|
||||
|
||||
**Press 1, wait for it to install. This is a very large file for the system so give it some time.**
|
||||
|
||||
**Once done and it says Tailscale installed successfully press 2/enter to configure it.**
|
||||
|
||||

|
||||
|
||||
If you want to, enable the Tailscale Web UI on port 8088 for configuration from the browser later by **pressing 1/enter**.
|
||||
|
||||
To do it in the toolkit:
|
||||
First time connecting you'll be given a link to login with
|
||||
- Press 3 to just connect only.
|
||||
- Press 4 to connect and enable SSH access (remote command line) over tailscale.
|
||||
- Press 5 to reconnect with SSH off while connected with SSH on
|
||||
- Press 6 to disconnect
|
||||
- Press 7 to Logout
|
||||
|
||||
That's it! From another device running tailscale you should be able to access your modem through the IP assigned to it by your tailnet. To access SSH from another device on the tailnet, open a terminal/command prompt and type
|
||||
|
||||
tailscale ssh root@(IP or Hostname)
|
||||
IP or Hostname being the IP or hostname assigned to it in your tailnet
|
||||
|
||||
- Note that your SSH client must be able to give you a link to sign in with upon connecting. That's how the session is authorized. Works fine in Windows CMD or on Android use JuiceSSH.
|
||||
### Entware/OPKG installation
|
||||
|
||||
- After installing, the `opkg` command will work
|
||||
- You can run `opkg list` to see a list of installable packages, or head over to https://bin.entware.net/armv7sf-k3.2/Packages.html
|
||||
- Everything opkg does is installed to /opt
|
||||
- `/opt` is actually located at `/usrdata/opt` to save space but is
|
||||
mounted at `/opt`
|
||||
- To properly use entware/opkg run the `login` command first if using adb to use stufff installed by entware/opkg
|
||||
- Be aware of space and CPU limits, run `dfc` to see what the available space in `/opt` is. Run `htop` to see CPU usage and memory usage
|
||||
|
||||
### TTYd installation
|
||||
|
||||
- This listens on port 443 for http requests (no SSL/TLS yet)
|
||||
- This will automaticly install entware and patch the login and passwd binaries with ones from entware\so you can login
|
||||
- It will ask you to set a password for the `root` user account
|
||||
- TTYd doesn't seem to be too mobile friendly for now but I optimized it the best i could for now so it is at least usable through a smartphone browser. Hopefully the startup script can be improved even more later. Some people have a better experience depending on mobile browser
|
||||
|
||||
## Acknowledgements
|
||||
### GitHub Users/Individuals:
|
||||
Thank You to:
|
||||
|
||||
[Nate Carlson](https://github.com/natecarlson) for the Original Telnet Deamon/socat bridge usage and the Original RGMII Notes
|
||||
|
||||
[aesthernr](https://github.com/aesthernr) for creating the Original Simple Admin
|
||||
|
||||
[rbflurry](https://github.com/rbflurry/) for inital Simple Admin fixes
|
||||
|
||||
[dr-dolomite](https://github.com/dr-dolomite) for some major stat page improvements and this repos first approved external PR!
|
||||
|
||||
### Existing projects:
|
||||
Simpleadmin heavily uses the AT Command Parsing Scripts (Basically a copy with new changes and tweaks) of Dairyman's Rooter Source https://github.com/ofmodemsandmen/ROOterSource2203
|
||||
|
||||
Tailscale was obtained through Tailscale's static build page. Since these modems have a 32-bit ARM processor on-board I used the arm package. https://pkgs.tailscale.com/stable/#static
|
||||
|
||||
Entware/opkg was obtained through [Entware's wiki](https://github.com/Entware/Entware/wiki/Alternative-install-vs-standard) and the installer heavily modified by [iamromulan](https://github.com/iamromulan) for use with Quectel modems
|
||||
|
||||
TTYd was obtained from the [TTYd Project](https://github.com/tsl0922/ttyd)
|
||||
1083
old/original_main_repo/RMxxx_rgmii_toolkit.sh
Normal file
1083
old/original_main_repo/RMxxx_rgmii_toolkit.sh
Normal file
File diff suppressed because it is too large
Load Diff
250
old/original_main_repo/installentware.sh
Normal file
250
old/original_main_repo/installentware.sh
Normal file
@@ -0,0 +1,250 @@
|
||||
#!/bin/sh
|
||||
# Modified by iamromlan to set up a proper entware environment for Quectel RM5xx series m.2 modems
|
||||
TYPE='generic'
|
||||
#|---------|-----------------|
|
||||
#| TARGET | Quectel Modem |
|
||||
#| ARCH | armv7sf-k3.2 |
|
||||
#| LOADER | ld-linux.so.3 |
|
||||
#| GLIBC | 2.27 |
|
||||
#|---------|-----------------|
|
||||
unset LD_LIBRARY_PATH
|
||||
unset LD_PRELOAD
|
||||
ARCH=armv7sf-k3.2
|
||||
LOADER=ld-linux.so.3
|
||||
GLIBC=2.27
|
||||
PRE_OPKG_PATH=$(which opkg)
|
||||
|
||||
# Remount filesystem as read-write
|
||||
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
|
||||
# Restore original link to login binary compiled by Quectel
|
||||
rm /bin/login
|
||||
ln /bin/login.shadow /bin/login
|
||||
|
||||
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[32mThis will also resore your login process to Quectel Stock\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() {
|
||||
# Bind /usrdata/opt to /opt
|
||||
echo -e '\033[32mInfo: Setting up /opt mount to /usrdata/opt...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/opt.mount
|
||||
[Unit]
|
||||
Description=Bind /usrdata/opt to /opt
|
||||
|
||||
[Mount]
|
||||
What=/usrdata/opt
|
||||
Where=/opt
|
||||
Type=none
|
||||
Options=bind
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl start opt.mount
|
||||
|
||||
# Additional systemd service to ensure opt.mount starts at boot
|
||||
echo -e '\033[32mInfo: Creating service to start opt.mount at boot...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/start-opt-mount.service
|
||||
[Unit]
|
||||
Description=Ensure opt.mount is started at boot
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/systemctl start opt.mount
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
ln -s /lib/systemd/system/start-opt-mount.service /lib/systemd/system/multi-user.target.wants/start-opt-mount.service
|
||||
}
|
||||
|
||||
if [ -n "$PRE_OPKG_PATH" ]; then
|
||||
while true; do
|
||||
echo -e "\033[32mopkg already exists at: $PRE_OPKG_PATH\033[0m"
|
||||
echo -e "\033[32mDo you want to rename it 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
|
||||
echo "Info: no existing opkg binary detected, proceeding with installation"
|
||||
fi
|
||||
echo -e '\033[32mInfo: Creating /opt mount pointed to /usrdata/opt ...\033[0m'
|
||||
create_opt_mount
|
||||
echo -e '\033[32mInfo: Proceeding with main installation ...\033[0m'
|
||||
# no need to create many folders. entware-opt package creates most
|
||||
for folder in bin etc lib/opkg tmp var/lock
|
||||
do
|
||||
if [ -d "/opt/$folder" ]; then
|
||||
echo -e '\033[31mWarning: Folder /opt/$folder exists!\033[0m'
|
||||
echo -e '\033[31mWarning: If something goes wrong please clean /opt folder and try again.\033[0m'
|
||||
else
|
||||
mkdir -p /opt/$folder
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e '\033[32mInfo: Opkg package manager deployment...\033[0m'
|
||||
URL=http://bin.entware.net/${ARCH}/installer
|
||||
wget $URL/opkg -O /opt/bin/opkg
|
||||
chmod 755 /opt/bin/opkg
|
||||
wget $URL/opkg.conf -O /opt/etc/opkg.conf
|
||||
|
||||
echo -e '\033[32mInfo: Basic packages installation...\033[0m'
|
||||
/opt/bin/opkg update
|
||||
/opt/bin/opkg install entware-opt
|
||||
|
||||
# Fix for multiuser environment
|
||||
chmod 777 /opt/tmp
|
||||
|
||||
for file in passwd group shells shadow gshadow; do
|
||||
if [ $TYPE = 'generic' ]; then
|
||||
if [ -f /etc/$file ]; then
|
||||
ln -sf /etc/$file /opt/etc/$file
|
||||
else
|
||||
[ -f /opt/etc/$file.1 ] && cp /opt/etc/$file.1 /opt/etc/$file
|
||||
fi
|
||||
else
|
||||
if [ -f /opt/etc/$file.1 ]; then
|
||||
cp /opt/etc/$file.1 /opt/etc/$file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[ -f /etc/localtime ] && ln -sf /etc/localtime /opt/etc/localtime
|
||||
|
||||
# Create and enable rc.unslung service
|
||||
echo -e '\033[32mInfo: Creating rc.unslung (Entware init.d service)...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/rc.unslung.service
|
||||
[Unit]
|
||||
Description=Start Entware services
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# Add a delay to give /opt time to mount
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/opt/etc/init.d/rc.unslung start
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
ln -s /lib/systemd/system/rc.unslung.service /lib/systemd/system/multi-user.target.wants/rc.unslung.service
|
||||
systemctl start rc.unslung.service
|
||||
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: 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
|
||||
opkg update && opkg install shadow-login shadow-passwd
|
||||
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/
|
||||
echo -e "\e[1;31mPlease set your system login password.\e[0m"
|
||||
/usr/bin/passwd
|
||||
|
||||
# Install basic and useful utilites
|
||||
opkg install mc
|
||||
ln -sf /opt/bin/mc /bin
|
||||
opkg install htop
|
||||
ln -sf /opt/bin/htop /bin
|
||||
opkg install dfc
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
opkg install lsof
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
# Remount filesystem as read-only
|
||||
mount -o remount,ro /
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/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
|
||||
540
old/original_main_repo/simpleadmin/scripts/modemstatus_parse.sh
Normal file
540
old/original_main_repo/simpleadmin/scripts/modemstatus_parse.sh
Normal file
@@ -0,0 +1,540 @@
|
||||
#!/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
|
||||
get_secondary_bands_lte() {
|
||||
# Extract the LTE BANDs from SCC lines from /tmp/modemstatus.txt.
|
||||
# If there are multiple bands, they will be concatenated with <br/> tags.
|
||||
SC_BANDS=$(grep -o '"LTE BAND [0-9]\+"' /tmp/modemstatus.txt | tr -d '"' | sed '1d' | sed ':a;N;$!ba;s/\n/<br\/>/g')
|
||||
|
||||
# If there are no LTE bands or NR5G bands, set SC_BANDS to empty
|
||||
if [ -z "$SC_BANDS" ]; then
|
||||
SC_BANDS="-"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# Function to get the secondary NR5G bands for NR5G NSA
|
||||
get_secondary_bands_nsa() {
|
||||
# Extract the NR5G NSA BANDs from SCC lines from /tmp/modemstatus.txt.
|
||||
# If there are multiple bands, they will be concatenated with <br/> tags.
|
||||
SC_BANDS_NSA=$(grep -o '"NR5G BAND [0-9]\+"' /tmp/modemstatus.txt | tr -d '"' | sed ':a;N;$!ba;s/\n/<br\/>/g')
|
||||
echo $SC_BANDS_NSA > /tmp/scbands.txt
|
||||
|
||||
# If there are no NR5G NSA bands, set SC_BANDS_NSA to empty
|
||||
if [ -z "$SC_BANDS_NSA" ]; then
|
||||
SC_BANDS_NSA="-"
|
||||
fi
|
||||
}
|
||||
|
||||
get_secondary_bands_sa() {
|
||||
# Extract the NR5G SA BANDs from SCC lines from /tmp/modemstatus.txt.
|
||||
# If there are multiple bands, they will be concatenated with <br/> tags.
|
||||
SC_BANDS=$(grep -o '"NR5G BAND [0-9]\+"' /tmp/modemstatus.txt | tr -d '"' | sed '1d' | sed ':a;N;$!ba;s/\n/<br\/>/g')
|
||||
|
||||
# If there are no NR5G SA bands, set SC_BANDS to empty
|
||||
if [ -z "$SC_BANDS" ]; then
|
||||
SC_BANDS="-"
|
||||
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_lte
|
||||
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",,"
|
||||
get_secondary_bands_nsa
|
||||
# Append the SC_BANDS_NSA to SC_BANDS with <br /> tags
|
||||
SC_BANDS=$SC_BANDS"<br />"$SC_BANDS_NSA
|
||||
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_sa
|
||||
# Apply | sed '1d' to NR_BAND
|
||||
# Temporarily removed the sed command for testing
|
||||
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
|
||||
48
old/original_main_repo/simpleadmin/scripts/tojson.sh
Normal file
48
old/original_main_repo/simpleadmin/scripts/tojson.sh
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/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 "}"
|
||||
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Simpleadmin service to generate status from modem
|
||||
|
||||
[Service]
|
||||
ExecStart=/usrdata/simpleadmin/scripts/build_modem_status
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,11 @@
|
||||
[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
|
||||
352
old/original_main_repo/simpleadmin/www/atcommander.html
Normal file
352
old/original_main_repo/simpleadmin/www/atcommander.html
Normal file
@@ -0,0 +1,352 @@
|
||||
<!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>Simple Settings</title>
|
||||
|
||||
<script src="/js/alpinejs.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/css/bulma.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</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="/bandlock.html"> Simple Network </a>
|
||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
||||
<a class="navbar-item" href="/speedtest.html"> OpenSpeedtest </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"
|
||||
x-ref="atCmdInput"
|
||||
@keydown.enter="sendAtCommand()"
|
||||
/>
|
||||
</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">AT Command Response</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<textarea
|
||||
class="textarea"
|
||||
placeholder="Multiple commands should be separated by a semicolon. Example: AT+CGMR;+GSN"
|
||||
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" x-data="atCommands()">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Useful One Click Commands</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<div style="display: flex; flex-direction: row; flex-wrap: wrap; margin-top: 1rem; justify-content: space-between;">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button
|
||||
class="button is-danger"
|
||||
@click="sendRebootCommand()"
|
||||
:disabled="isRebooting"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="field">
|
||||
<div class="control">
|
||||
<button
|
||||
class="button is-danger"
|
||||
@click="sendRebootCommand()"
|
||||
:disabled="isRebooting"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<p>Here are some useful commands:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<!-- Open to another tab -->
|
||||
See <a href="https://github.com/iamromulan/RM520N-GL#at-commands" target="_blank" style="cursor: pointer;">https://github.com/iamromulan/RM520N-GL#at-commands</a> for
|
||||
more
|
||||
</li>
|
||||
<li>AT+CFUN=1,1 (reboot)</li>
|
||||
<li>
|
||||
AT+QMAPWAC? (get current status of auto connect, 0=disabled
|
||||
1=enabled)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAPWAC=1 (enable auto connect internet for ethernet)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAPWAC=0 (disable auto connect for ethernet; use when
|
||||
you want internet over usb to work; IPPT must be disabled)
|
||||
</li>
|
||||
<li>
|
||||
AT+QUIMSLOT? (get active sim slot; 1=Slot 1; 2=Slot 2)
|
||||
</li>
|
||||
<li>AT+QUIMSLOT=1 (switch to sim slot 1)</li>
|
||||
<li>AT+QUIMSLOT=2 (switch to sim slot 2)</li>
|
||||
<li>AT+CGDCONT? (Get active APN profle list 1 through 8)</li>
|
||||
<li>
|
||||
AT+CGDCONT=1,"IPV4V6","APNHERE" (Sets APN profle 1 to
|
||||
APNHERE using both IPV4 and IPV6)
|
||||
</li>
|
||||
<li>AT+GSN (Show current IMEI)</li>
|
||||
<li>AT+EGMR=1,7,"IMEIGOESHERE" (sets/repairs IMEI)</li>
|
||||
<li>AT+QCAINFO (Show all connected bands/CA info)</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="mode_pref" (Check what the current network
|
||||
search mode is set to)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="mode_pref",AUTO (Set network search mode to
|
||||
automatic)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="mode_pref",NR5G:LTE (Set network search mode
|
||||
to 5G/NR and 4G/LTE only)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="mode_pref",NR5G (Set network search mode to
|
||||
5G/NR only)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="mode_pref",LTE (Set network search mode to
|
||||
4G/LTE only)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="nr5g_disable_mode" (Check to see if SA or NSA
|
||||
NR5G is disabled)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="nr5g_disable_mode",0 (Enable Both SA and NSA
|
||||
5G/NR)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="nr5g_disable_mode",1 (Disable SA 5G/NR only)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="nr5g_disable_mode",2 (Disable NSA 5G/NR only)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="nr5g_band" (Get current 5G/NR bandlock
|
||||
settings)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="nr5g_band",1:2:3:4:5:6 (Example: Lock to
|
||||
5G/NR bands n1,n2,n3,n4,n5, and n6)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="lte_band" (Get current 4G/LTE bandlock
|
||||
settings)
|
||||
</li>
|
||||
<li>
|
||||
AT+QNWPREFCFG="lte_band",1:2:3:4:5:6 (Example: Lock to
|
||||
4G/LTE bands 1,2,3,4,5, and 6)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAP="WWAN" (Show currently assigned IPv4 and IPv6 from
|
||||
the provider)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAP="LANIP" (Show current DHCP range and Gateway address
|
||||
for VLAN0)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAP="LANIP",IP_start_range,IP_end_range,Gateway_IP (Set
|
||||
IPv4 Start/End range and Gateway IP of DHCP for VLAN0)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAP="DHCPV4DNS","disable" (disable the onboard DNS
|
||||
proxy; recommended for IPPT)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAP="MPDN_rule",0,1,0,1,1,"FF:FF:FF:FF:FF:FF" (Turn on
|
||||
IP Passthrough for Ethernet)
|
||||
</li>
|
||||
<li>
|
||||
AT+QMAP="MPDN_rule",0 (turn off IPPT/clear MPDN rule 0;
|
||||
Remember to run AT+QMAPWAC=1 and reboot after)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Loading modal -->
|
||||
<div x-show="isRebooting" class="modal-overlay">
|
||||
<div class="loading-modal">
|
||||
<div class="spinner"></div>
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>Rebooting...</h3>
|
||||
<p style="margin-top: 0.5rem">
|
||||
Please wait for
|
||||
<span x-text="countdown" style="font-weight: 500"></span> seconds
|
||||
before refreshing the page.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function atCommands() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isRebooting: false,
|
||||
countdown: 40, // Total waiting time in seconds
|
||||
atcmd: null,
|
||||
defaultAtCommand: "ATI",
|
||||
atCommandResponse: "",
|
||||
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;
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
clearResponses() {
|
||||
this.atCommandResponse = "";
|
||||
},
|
||||
sendRebootCommand() {
|
||||
this.atcmd = "AT+CFUN=1,1";
|
||||
this.isRebooting = true;
|
||||
console.log("Reboot command sent: ", this.atcmd);
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse =
|
||||
"Rebooting... Please wait a few seconds before refreshing the page.";
|
||||
})
|
||||
.finally(() => {
|
||||
let timer = setInterval(() => {
|
||||
this.countdown--;
|
||||
if (this.countdown <= 0) {
|
||||
clearInterval(timer);
|
||||
this.isRebooting = false;
|
||||
}
|
||||
}, 1000); // Update countdown every second
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
875
old/original_main_repo/simpleadmin/www/bandlock.html
Normal file
875
old/original_main_repo/simpleadmin/www/bandlock.html
Normal file
@@ -0,0 +1,875 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Network</title>
|
||||
|
||||
<script src="/js/alpinejs.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/css/bulma.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.card-column {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- START NAV -->
|
||||
<nav class="navbar is-black" x-data="{ isOpen: false }">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item brand-text" href="/"> Simple Admin </a>
|
||||
<a
|
||||
role="button"
|
||||
class="navbar-burger burger"
|
||||
@click="isOpen = !isOpen"
|
||||
>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
id="navMenu"
|
||||
class="navbar-menu"
|
||||
:class="isOpen ? 'is-active' : ''"
|
||||
>
|
||||
<div class="navbar-start">
|
||||
<a class="navbar-item" href="/"> Connection Info </a>
|
||||
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
|
||||
<a class="navbar-item" href="/bandlock.html"> Simple Network </a>
|
||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
||||
<a class="navbar-item" href="/speedtest.html"> OpenSpeedtest </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- END NAV -->
|
||||
<div
|
||||
class="container"
|
||||
style="margin: auto"
|
||||
x-data="atCommands()"
|
||||
x-init="atCommands()"
|
||||
>
|
||||
<div class="columns is-multiline">
|
||||
<!-- First Box -->
|
||||
<div class="column is-8-tablet is-6-desktop card-column">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Band Locking</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<!-- Create a drop down -->
|
||||
<div class="select is-primary">
|
||||
<select id="networkMode" x-model="networkMode">
|
||||
<option>Select Network Mode</option>
|
||||
<option>LTE</option>
|
||||
<option>NR5G-NSA</option>
|
||||
<option>NR5G-SA</option>
|
||||
</select>
|
||||
</div>
|
||||
<input
|
||||
class="input is-primary"
|
||||
type="text"
|
||||
placeholder="Example: 1,3,41"
|
||||
style="margin-top: 1rem"
|
||||
x-model="bandNumbers"
|
||||
/>
|
||||
|
||||
<div style="margin-top: 1rem; display: flex; flex-direction: row">
|
||||
<button
|
||||
class="button is-primary"
|
||||
@click="lockBands()"
|
||||
:disabled="isLocking"
|
||||
>
|
||||
Lock Bands
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-warning"
|
||||
style="margin-left: 1rem"
|
||||
@click="restoreBands()"
|
||||
:disabled="isLocking"
|
||||
>
|
||||
Restore Bands
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer" style="padding: 0.25rem">
|
||||
<p class="card-footer-item">
|
||||
Please first select your desired network band from the dropdown
|
||||
menu. To lock onto specific bands, please type the band numbers
|
||||
separated by commas (,) and then click the lock button.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Second Box -->
|
||||
<div class="column is-8-tablet is-6-desktop card-column">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">LTE and NR5G Cell Locking</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<div class="select is-info">
|
||||
<select id="networkModeSelect" x-model="networkMode2">
|
||||
<option>Select Network Mode</option>
|
||||
<option>LTE</option>
|
||||
<option>NR5G-SA</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="numFreqContainer"
|
||||
style="margin-left: 1rem"
|
||||
x-show="networkMode2 == 'LTE'"
|
||||
>
|
||||
<input
|
||||
class="input is-info"
|
||||
type="number"
|
||||
id="numFreqInput"
|
||||
min="1"
|
||||
max="10"
|
||||
placeholder="1-10"
|
||||
x-model="cellNum"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="freqNumbersContainer"></div>
|
||||
|
||||
<!-- For NR5G-SA -->
|
||||
<div style="margin-top: 1rem" x-show="networkMode2 == 'NR5G-SA'">
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<input
|
||||
class="input is-info"
|
||||
type="text"
|
||||
placeholder="EARFCN"
|
||||
x-model="earfcn1"
|
||||
/>
|
||||
<input
|
||||
class="input is-info"
|
||||
type="text"
|
||||
placeholder="PCI"
|
||||
x-model="pci1"
|
||||
style="margin-left: 1rem"
|
||||
/>
|
||||
<input
|
||||
class="input is-info"
|
||||
type="text"
|
||||
placeholder="SCS"
|
||||
x-model="scs"
|
||||
style="margin-left: 1rem"
|
||||
/>
|
||||
<input
|
||||
class="input is-info"
|
||||
type="text"
|
||||
placeholder="BAND"
|
||||
x-model="band"
|
||||
style="margin-left: 1rem"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 1rem; display: flex; flex-direction: row">
|
||||
<button
|
||||
class="button is-info"
|
||||
@click="cellLock()"
|
||||
:disabled="isLocking"
|
||||
>
|
||||
Lock Cell
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-warning"
|
||||
style="margin-left: 1rem"
|
||||
@click="restoreCell()"
|
||||
:disabled="isLocking"
|
||||
>
|
||||
Restore Cell
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer" style="padding: 0.25rem">
|
||||
<p class="card-footer-item">
|
||||
To utilize cell locking, first, select the network mode, then
|
||||
specify the number of cells you wish to lock onto (max 10) if
|
||||
you are using LTE. Next, input the EARFCN and PCI values for
|
||||
each cell number. If you are locking through NR5G-SA instead,
|
||||
simply fill up all the required parameters.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Third Box -->
|
||||
|
||||
<div class="column is-8-tablet is-6-desktop card-column">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Network Utilities</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<div>
|
||||
<p>Set Network APN</p>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 0.5rem;
|
||||
"
|
||||
>
|
||||
<input
|
||||
class="input is-link"
|
||||
type="text"
|
||||
placeholder="APN"
|
||||
x-model="apnInput"
|
||||
/>
|
||||
<button
|
||||
class="button is-link"
|
||||
style="margin-left: 1rem"
|
||||
@click="setAPN()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Set APN
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 1rem">
|
||||
<p>Set Preferred Network Mode</p>
|
||||
<div
|
||||
style="display: flex; flex-direction: row; margin-top: 0.5rem"
|
||||
>
|
||||
<div class="select is-info">
|
||||
<select id="prefNetworkMode" x-model="prefNetworkMode">
|
||||
<option>Select Network</option>
|
||||
<option>AUTO</option>
|
||||
<option>WCDMA</option>
|
||||
<option>LTE ONLY</option>
|
||||
<option>NR5G-NSA</option>
|
||||
<option>NR5G-SA</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
style="margin-left: 1rem"
|
||||
@click="setPrefNetwork()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Set Network
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 1rem">
|
||||
<p>Set Sim Slot</p>
|
||||
<div
|
||||
style="display: flex; flex-direction: row; margin-top: 0.5rem"
|
||||
>
|
||||
<div class="select is-info">
|
||||
<select id="simSlot" x-model="simSlot">
|
||||
<option>Select Sim</option>
|
||||
<option>1</option>
|
||||
<option>2</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
style="margin-left: 1rem"
|
||||
@click="setSimSlot()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Set Sim
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 1rem">
|
||||
<p>NR5G Mode Control</p>
|
||||
<div
|
||||
style="display: flex; flex-direction: row; margin-top: 0.5rem"
|
||||
>
|
||||
<div class="select is-info">
|
||||
<select id="nrMode" x-model="nrMode">
|
||||
<option>Select NR5G Mode</option>
|
||||
<option>Enable All</option>
|
||||
<option>Disable NSA</option>
|
||||
<option>Disable SA</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
style="margin-left: 1rem"
|
||||
@click="nr5GMode()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Set Mode
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer" style="padding: 0.25rem">
|
||||
<p class="card-footer-item">
|
||||
This section allows you to set the APN, preferred network mode,
|
||||
and sim slot. Simply input the desired values and click the
|
||||
respective buttons to apply the changes. (Sim slot is only
|
||||
applicable for dual sim devices.)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Fourth Box -->
|
||||
<div class="column is-8-tablet is-6-desktop card-column">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Query Network Parameters</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<textarea
|
||||
class="textarea"
|
||||
rows="5"
|
||||
placeholder="Query Response"
|
||||
x-text=" isLoading ? 'Getting Response...' : queryCommandResponse"
|
||||
></textarea>
|
||||
|
||||
<div style="margin-top: 1.5rem">
|
||||
<p>Check Locked Bands</p>
|
||||
<div class="select is-info" style="margin-top: 0.5rem">
|
||||
<select id="lockedBands" x-model="lockedBands">
|
||||
<option>Locked Bands</option>
|
||||
<option>LTE</option>
|
||||
<option>NSA</option>
|
||||
<option>SA</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
style="margin-left: 1rem; margin-top: 0.5rem"
|
||||
@click="showLockedBands()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Check Bands
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 1rem">
|
||||
<p>Check Cell Lock</p>
|
||||
<div class="select is-info" style="margin-top: 0.5rem">
|
||||
<select id="cellState" x-model="cellState">
|
||||
<option>Cell Lock</option>
|
||||
<option>LTE</option>
|
||||
<option>NR5G-SA</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
style="margin-left: 1rem; margin-top: 0.5rem"
|
||||
@click="showCellState()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Check Cell
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 2rem">
|
||||
<p>Other Network Query</p>
|
||||
</div>
|
||||
<div class="buttons" style="margin-top: 0.5rem">
|
||||
<button
|
||||
class="button is-link mr-2"
|
||||
@click="showSupportedBands()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Show Supported Bands
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-link mr-2"
|
||||
@click="showCurrentSim()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Show Current Sim
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
@click="showPrefNetwork()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Show Pref Network
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
@click="showCaInfo()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Carrier Aggregation Info
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
@click="servingCellInfo()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Serving Cell Info
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
@click="scanNeighbourCells()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Scan Neighbour Cells
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
@click="scanNsaCells()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Scan NSA Cells
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="button is-link"
|
||||
@click="fullNetworkScan()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Full Network Scan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer" style="padding: 0.25rem">
|
||||
<p class="card-footer-item">
|
||||
This section allows you to query the network parameters. Simply
|
||||
click the respective buttons to view the network parameters.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading Modal for Locking Band -->
|
||||
<div x-show="isLocking" class="modal-overlay">
|
||||
<div class="loading-modal">
|
||||
<div class="spinner"></div>
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>Initializing Network...</h3>
|
||||
<p style="margin-top: 0.5rem">
|
||||
Please wait for
|
||||
<span x-text="countdown" style="font-weight: 500"></span> seconds.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="isError" class="modal-overlay">
|
||||
<div class="loading-modal">
|
||||
<div class="spinner"></div>
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>Request Error</h3>
|
||||
<p style="margin-top: 0.5rem">
|
||||
Please follow the instructions properly. Exiting in
|
||||
<span x-text="countdown" style="font-weight: 500"></span> seconds.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function atCommands() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isQuerying: false,
|
||||
isLocking: false,
|
||||
isError: false,
|
||||
countdown: 5, // Initial countdown value
|
||||
networkMode: null,
|
||||
networkMode2: null,
|
||||
bandNumbers: null,
|
||||
cellNum: null,
|
||||
earfcn1: null,
|
||||
pci1: null,
|
||||
earfcn2: null,
|
||||
pci2: null,
|
||||
earfcn3: null,
|
||||
pci3: null,
|
||||
earfcn4: null,
|
||||
pci4: null,
|
||||
earfcn5: null,
|
||||
pci5: null,
|
||||
earfcn6: null,
|
||||
pci6: null,
|
||||
earfcn7: null,
|
||||
pci7: null,
|
||||
earfcn8: null,
|
||||
pci8: null,
|
||||
earfcn9: null,
|
||||
pci9: null,
|
||||
earfcn10: null,
|
||||
pci10: null,
|
||||
band: null,
|
||||
scs: null,
|
||||
apnInput: null,
|
||||
prefNetworkMode: null,
|
||||
simSlot: null,
|
||||
nrMode: null,
|
||||
lockedBands: null,
|
||||
cellState: null,
|
||||
invalidCellNum: "",
|
||||
atCommandResponse: "",
|
||||
queryCommandResponse: "",
|
||||
lockBands() {
|
||||
if (!this.networkMode || !this.bandNumbers) {
|
||||
this.isError = true;
|
||||
this.startCountdown();
|
||||
console.error("Network mode and band numbers are required.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove commas and replace with colons
|
||||
const parsedBandNumbers = this.bandNumbers.replace(/,/g, ":");
|
||||
|
||||
// Construct the atcmd based on the selected network mode
|
||||
let atcmd;
|
||||
switch (this.networkMode) {
|
||||
case "LTE":
|
||||
atcmd = `AT+QNWPREFCFG="lte_band",${parsedBandNumbers}`;
|
||||
console.log(atcmd);
|
||||
break;
|
||||
case "NR5G-NSA":
|
||||
atcmd = `AT+QNWPREFCFG="nsa_nr5g_band",${parsedBandNumbers}`;
|
||||
console.log(atcmd);
|
||||
break;
|
||||
case "NR5G-SA":
|
||||
atcmd = `AT+QNWPREFCFG="nr5g_band",${parsedBandNumbers}`;
|
||||
console.log(atcmd);
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid network mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => res.text())
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.isLocking = true;
|
||||
this.startCountdown();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.isError = true;
|
||||
this.startCountdown();
|
||||
console.error("Error sending AT command:", error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
cellLock() {
|
||||
// Error handlers
|
||||
if (!this.networkMode2) {
|
||||
this.isError = true;
|
||||
this.startCountdown();
|
||||
console.error("Network mode is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct the AT command based on the selected network mode
|
||||
let atcmd;
|
||||
|
||||
if (this.networkMode2 === "LTE") {
|
||||
if (parseInt(this.cellNum) > 10) {
|
||||
this.invalidCellNum = "Invalid";
|
||||
this.isError = true;
|
||||
this.startCountdown();
|
||||
console.error("Invalid frequency number.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLocking = true;
|
||||
atcmd = `AT+QNWLOCK="common/4g",${this.cellNum}`;
|
||||
for (let i = 1; i <= parseInt(this.cellNum); i++) {
|
||||
atcmd += `,${this["earfcn" + i]},${this["pci" + i]}`;
|
||||
}
|
||||
console.log(atcmd);
|
||||
} else if (this.networkMode2 === "NR5G-SA") {
|
||||
this.isLocking = true;
|
||||
atcmd = `AT+QNWLOCK="common/5g",${this.pci1},${this.earfcn1},${this.scs},${this.band}`;
|
||||
console.log(atcmd);
|
||||
}
|
||||
|
||||
this.sendAtCommand(atcmd);
|
||||
},
|
||||
restoreBands() {
|
||||
const restoreCmd = 'AT+QNWPREFCFG="restore_band"';
|
||||
this.sendAtCommand(restoreCmd);
|
||||
},
|
||||
restoreCell() {
|
||||
const restoreCmd = 'AT+QNWLOCK="common/4g",0';
|
||||
this.sendAtCommand(restoreCmd);
|
||||
},
|
||||
setAPN() {
|
||||
const apnCmd = `AT+CGDCONT=1,"IPV4V6","${this.apnInput}"`;
|
||||
this.sendAtCommand(apnCmd);
|
||||
},
|
||||
setPrefNetwork() {
|
||||
// AT+QNWPREFCFG="mode_pref",<mode>
|
||||
let prefCmd;
|
||||
switch (this.prefNetworkMode) {
|
||||
case "AUTO":
|
||||
prefCmd = 'AT+QNWPREFCFG="mode_pref",AUTO';
|
||||
break;
|
||||
case "WCDMA":
|
||||
prefCmd = 'AT+QNWPREFCFG="mode_pref",WCDMA';
|
||||
break;
|
||||
case "LTE ONLY":
|
||||
prefCmd = 'AT+QNWPREFCFG="mode_pref",LTE';
|
||||
break;
|
||||
case "NR5G-NSA":
|
||||
prefCmd = 'AT+QNWPREFCFG="mode_pref",LTE:NR5G';
|
||||
break;
|
||||
case "NR5G-SA":
|
||||
prefCmd = 'AT+QNWPREFCFG="mode_pref",NR5G';
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid network mode.");
|
||||
return;
|
||||
}
|
||||
this.sendAtCommand(prefCmd);
|
||||
},
|
||||
setSimSlot() {
|
||||
const simCmd = `AT+QUIMSLOT=${this.simSlot}`;
|
||||
this.sendAtCommand(simCmd);
|
||||
},
|
||||
nr5GMode() {
|
||||
let nrCmd;
|
||||
switch (this.nrMode) {
|
||||
case "Enable All":
|
||||
nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",0';
|
||||
break;
|
||||
case "Disable NSA":
|
||||
nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",2';
|
||||
break;
|
||||
case "Disable SA":
|
||||
nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",1';
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid NR5G mode.");
|
||||
return;
|
||||
}
|
||||
this.queryATCommand(nrCmd);
|
||||
},
|
||||
showLockedBands() {
|
||||
let lockedCmd;
|
||||
switch (this.lockedBands) {
|
||||
case "LTE":
|
||||
lockedCmd = 'AT+QNWPREFCFG="lte_band"';
|
||||
break;
|
||||
case "NSA":
|
||||
lockedCmd = 'AT+QNWPREFCFG="nsa_nr5g_band"';
|
||||
break;
|
||||
case "SA":
|
||||
lockedCmd = 'AT+QNWPREFCFG="nr5g_band"';
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid network mode.");
|
||||
return;
|
||||
}
|
||||
this.queryATCommand(lockedCmd);
|
||||
},
|
||||
|
||||
showCellState() {
|
||||
let cellCmd;
|
||||
switch (this.cellState) {
|
||||
case "LTE":
|
||||
cellCmd = 'AT+QNWLOCK="common/4g"';
|
||||
break;
|
||||
case "NR5G-SA":
|
||||
cellCmd = 'AT+QNWLOCK="common/5g"';
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid network mode.");
|
||||
return;
|
||||
}
|
||||
this.queryATCommand(cellCmd);
|
||||
},
|
||||
showSupportedBands() {
|
||||
const supportedCmd = 'AT+QNWPREFCFG="policy_band"';
|
||||
this.queryATCommand(supportedCmd);
|
||||
},
|
||||
showCurrentSim() {
|
||||
const simCmd = "AT+QUIMSLOT?";
|
||||
this.queryATCommand(simCmd);
|
||||
},
|
||||
showPrefNetwork() {
|
||||
const prefCmd = 'AT+QNWPREFCFG="mode_pref"';
|
||||
this.queryATCommand(prefCmd);
|
||||
},
|
||||
showCaInfo() {
|
||||
const caCmd = "AT+QCAINFO";
|
||||
this.queryATCommand(caCmd);
|
||||
},
|
||||
servingCellInfo() {
|
||||
const servingCmd = 'AT+QENG="servingcell"';
|
||||
this.queryATCommand(servingCmd);
|
||||
},
|
||||
scanNeighbourCells() {
|
||||
const scanCmd = 'AT+QENG="neighbourcell"';
|
||||
this.queryATCommand(scanCmd);
|
||||
},
|
||||
scanNsaCells() {
|
||||
const enableCmd = 'AT+QNWCFG="nr5g_meas_info",1';
|
||||
const queryScanCmd = 'AT+QNWCFG="nr5g_meas_info"';
|
||||
// Send the enable command first without getting the response
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: enableCmd,
|
||||
})
|
||||
)
|
||||
.then(() => {
|
||||
console.log("Enable Success.");
|
||||
// Show a temporary loading query message
|
||||
this.queryCommandResponse =
|
||||
"Enabling NSA cell scan. Please wait...";
|
||||
this.queryATCommand(queryScanCmd);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.isError = true;
|
||||
this.startCountdown();
|
||||
console.error("Error sending AT command:", error);
|
||||
});
|
||||
},
|
||||
fullNetworkScan() {
|
||||
const scanCmd = "AT+QSCAN=3,1";
|
||||
// Show a temporary loading query message
|
||||
this.queryCommandResponse =
|
||||
"Full network scan initiated. This takes about a minute. Please wait...";
|
||||
this.queryATCommand(scanCmd);
|
||||
},
|
||||
queryATCommand(atcmd) {
|
||||
this.isQuerying = true;
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => res.text())
|
||||
.then((data) => {
|
||||
this.queryCommandResponse = data;
|
||||
console.log(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.isError = true;
|
||||
this.startCountdown();
|
||||
console.error("Error sending AT command:", error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isQuerying = false;
|
||||
});
|
||||
},
|
||||
sendAtCommand(atcmd) {
|
||||
this.isLoading = true;
|
||||
this.startCountdown();
|
||||
console.log(atcmd);
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => res.text())
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
console.log(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.isError = true;
|
||||
this.startCountdown();
|
||||
console.error("Error sending AT command:", error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
startCountdown() {
|
||||
// Decrease countdown every second
|
||||
const interval = setInterval(() => {
|
||||
this.countdown--;
|
||||
if (this.countdown <= 0) {
|
||||
clearInterval(interval);
|
||||
// Reset values
|
||||
this.isLocking = false;
|
||||
this.isError = false;
|
||||
this.isLoading = false;
|
||||
this.isQuerying = false;
|
||||
this.countdown = 5;
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const freqNumbersContainer = document.getElementById(
|
||||
"freqNumbersContainer"
|
||||
);
|
||||
|
||||
function generateFreqNumberInputs(num) {
|
||||
let html = "";
|
||||
const maxFields = Math.min(num, 10); // Limit to a maximum of 10 fields
|
||||
for (let i = 1; i <= maxFields; i++) {
|
||||
html += `
|
||||
<div style="margin-top: 1rem" x-show="cellNum >= ${i} && networkMode2 == 'LTE'">
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<input class="input is-info" type="text" placeholder="EARFCN" x-model="earfcn${i}" />
|
||||
<input class="input is-info" type="text" placeholder="PCI" x-model="pci${i}" style="margin-left: 1rem" />
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("numFreqInput")
|
||||
.addEventListener("input", function () {
|
||||
const cellNum = parseInt(this.value);
|
||||
freqNumbersContainer.innerHTML = generateFreqNumberInputs(cellNum);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
35
old/original_main_repo/simpleadmin/www/cgi-bin/get_atcommand
Normal file
35
old/original_main_repo/simpleadmin/www/cgi-bin/get_atcommand
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/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
|
||||
|
||||
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
|
||||
if [ -n "${MYATCMD}" ]; then
|
||||
x=$(urldecode "$atcmd")
|
||||
# Initialize wait time to 1 second
|
||||
wait_time=1000
|
||||
while true; do
|
||||
runcmd=$(echo -en "$x\r\n" | microcom -t $wait_time /dev/ttyOUT2)
|
||||
# Check if "OK" or "ERROR" is present in the response
|
||||
if [[ $runcmd =~ "OK" ]] || [[ $runcmd =~ "ERROR" ]]; then
|
||||
break # Exit the loop if "OK" or "ERROR" is found
|
||||
fi
|
||||
# If neither "OK" nor "ERROR" is found, increment wait time by 1 second
|
||||
((wait_time++))
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Content-type: text/plain"
|
||||
echo $x
|
||||
echo ""
|
||||
echo $runcmd
|
||||
13
old/original_main_repo/simpleadmin/www/cgi-bin/get_csq
Normal file
13
old/original_main_repo/simpleadmin/www/cgi-bin/get_csq
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check iptables for ttlvalue
|
||||
ttlvalue=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||
ttlenabled=true;
|
||||
|
||||
# Set Variables
|
||||
if [ -z "${ttlvalue}" ]; then
|
||||
ttlvalue=0
|
||||
ttlenabled=false
|
||||
fi
|
||||
|
||||
echo "Content-type: text/json"
|
||||
echo ""
|
||||
cat <<EOT
|
||||
{
|
||||
"isEnabled": $ttlenabled,
|
||||
"ttl": $ttlvalue
|
||||
}
|
||||
61
old/original_main_repo/simpleadmin/www/cgi-bin/set_ttl
Normal file
61
old/original_main_repo/simpleadmin/www/cgi-bin/set_ttl
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Get query
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
|
||||
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
|
||||
|
||||
setTTL=$(printf '%b\n' "${ttlvalue//%/\\x}")
|
||||
|
||||
if [ -n "${setTTL}" ]; then
|
||||
# Stop Service To Remove Rules
|
||||
/usrdata/simplefirewall/ttl-override stop
|
||||
|
||||
# Check iptables is still set
|
||||
ttlcheck=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||
|
||||
# If TTL is still set manually remove values
|
||||
if [ !-z "${ttlcheck}" ]; then
|
||||
iptables -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
|
||||
fi
|
||||
|
||||
# Echo TTL to file
|
||||
echo $setTTL > /usrdata/simplefirewall/ttlvalue
|
||||
|
||||
# Set Start Service
|
||||
/usrdata/simplefirewall/ttl-override start
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check iptables for ttlvalue
|
||||
ttlvalue=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||
ttlenabled=true;
|
||||
|
||||
# Set Variables
|
||||
if [ -z "${ttlvalue}" ]; then
|
||||
ttlvalue=0
|
||||
ttlenabled=false
|
||||
fi
|
||||
|
||||
echo "Content-type: text/json"
|
||||
echo ""
|
||||
cat <<EOT
|
||||
{
|
||||
"isEnabled": $ttlenabled,
|
||||
"ttl": $ttlvalue
|
||||
}
|
||||
86
old/original_main_repo/simpleadmin/www/css/admin.css
Normal file
86
old/original_main_repo/simpleadmin/www/css/admin.css
Normal file
@@ -0,0 +1,86 @@
|
||||
: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;
|
||||
}
|
||||
|
||||
1
old/original_main_repo/simpleadmin/www/css/bulma.css
vendored
Normal file
1
old/original_main_repo/simpleadmin/www/css/bulma.css
vendored
Normal file
File diff suppressed because one or more lines are too long
284
old/original_main_repo/simpleadmin/www/index.html
Normal file
284
old/original_main_repo/simpleadmin/www/index.html
Normal file
@@ -0,0 +1,284 @@
|
||||
<!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>
|
||||
|
||||
<script src="/js/alpinejs.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/css/bulma.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- 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="/bandlock.html"> Simple Network </a>
|
||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
||||
<a class="navbar-item" href="/speedtest.html"> OpenSpeedtest </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- END NAV -->
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column is-12" x-data="getSignalData()" x-init="init()">
|
||||
<section class="hero is-info welcome is-small">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<!-- Fetches the correct Model Name -->
|
||||
<h1 class="title">
|
||||
<span x-text="csqData.MODEM_MODEL"></span> Connection
|
||||
Info
|
||||
</h1>
|
||||
<h2 class="subtitle">
|
||||
Data Updated: <span x-text="lastUpdate"></span>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="info-tiles">
|
||||
<div class="tile is-ancestor has-text-centered">
|
||||
<div class="tile is-parent">
|
||||
<article class="tile is-child box">
|
||||
<!-- added APN -->
|
||||
<p class="title" x-text="csqData.APN"></p>
|
||||
<p class="subtitle">Current APN</p>
|
||||
<p
|
||||
class="title"
|
||||
style="margin-top: 1rem"
|
||||
x-html="csqData.SIMSLOT"
|
||||
></p>
|
||||
<p class="subtitle">Current SIM</p>
|
||||
</article>
|
||||
</div>
|
||||
<div class="tile is-parent">
|
||||
<article class="tile is-child box">
|
||||
<!-- added APN -->
|
||||
<p class="title" x-text="csqData.MODE"></p>
|
||||
<p class="subtitle">Network</p>
|
||||
<p
|
||||
class="title"
|
||||
x-text="csqData.PC_BAND"
|
||||
style="margin-top: 1rem"
|
||||
></p>
|
||||
<p class="subtitle">Primary Band</p>
|
||||
</article>
|
||||
</div>
|
||||
<!-- added primary band and secondary bands value -->
|
||||
<div class="tile is-parent">
|
||||
<article class="tile is-child box">
|
||||
<p class="title" x-html="csqData.SC_BANDS"></p>
|
||||
<p class="subtitle">Aggregated Bands</p>
|
||||
</article>
|
||||
</div>
|
||||
<div class="tile is-parent">
|
||||
<article class="tile is-child box">
|
||||
<p class="title" x-text="csqData.CSQ_PER"></p>
|
||||
<p class="subtitle">Signal Strength</p>
|
||||
<p
|
||||
class="title"
|
||||
x-text="csqData.TEMP"
|
||||
style="margin-top: 1rem"
|
||||
></p>
|
||||
<p class="subtitle">Modem Temperature</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="columns">
|
||||
<div class="column is-6">
|
||||
<div class="card events-card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Signal Information</p>
|
||||
</header>
|
||||
<div class="card-table">
|
||||
<div class="content">
|
||||
<table class="table is-fullwidth is-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Provider</th>
|
||||
<td x-text="csqData.PROVIDER"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>CSQ</th>
|
||||
<td x-text="csqData.CSQ"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Signal Strength</th>
|
||||
<td x-text="csqData.CSQ_PER"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>RSSI</th>
|
||||
<td x-text="csqData.CSQ_RSSI"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
ECIO<sup>3G</sup>/RSRQ<sup>4G</sup>/SS_RSRQ<sup
|
||||
>5G</sup
|
||||
>
|
||||
</th>
|
||||
<td x-html="csqData.ECIO"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
RSCP<sup>3G</sup>/RSRP<sup>4G</sup>/SS_RSRP<sup
|
||||
>5G</sup
|
||||
>
|
||||
</th>
|
||||
<td x-html="csqData.RSCP"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>SINR</th>
|
||||
<td x-html="csqData.SINR"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<div class="card events-card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Cell Information</p>
|
||||
</header>
|
||||
<div class="card-table">
|
||||
<div class="content">
|
||||
<table class="table is-fullwidth is-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>MCC MNC</th>
|
||||
<td>
|
||||
<span x-text="csqData.MCCMNC"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>RNC<sup>3G</sup>/eNB ID<sup>4G/5G</sup></th>
|
||||
<td>
|
||||
<span x-text="csqData.RNC"></span>
|
||||
<span x-text="csqData.RNC_NUM"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Lag<sup>3G</sup>/TAC<sup>4G/5G</sup></th>
|
||||
<td>
|
||||
<span x-text="csqData.LAC"></span>
|
||||
<span x-text="csqData.LAC_NUM"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Cell ID</th>
|
||||
<td x-text="csqData.CID"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Band</th>
|
||||
<td x-html="csqData.LBAND"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Channel</th>
|
||||
<td x-text="csqData.CHANNEL"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>PCI</th>
|
||||
<td x-text="csqData.PCI"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function signalInfo() {
|
||||
return {
|
||||
isLoading: false,
|
||||
atcmd: 'AT+QSPN;+CEREG=2;+CEREG?;+CEREG=0;+C5GREG=2;+C5GREG?;+C5GREG=0;+CSQ;+QENG=\"servingcell\";+QRSRP;+QCAINFO;+QNWPREFCFG=\"mode_pref\";+QTEMP\r\n',
|
||||
atCommandResponse: null,
|
||||
refreshSignal() {
|
||||
this.isLoading = true; // Set loading state to true before fetching data
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
// Split the response into individual messages
|
||||
const messages = data.trim().split("\n\n");
|
||||
|
||||
// Convert the messages into a JSON file
|
||||
//TODO: Add the JSON conversion here
|
||||
|
||||
|
||||
// Log the parsed messages array as JSON to the console
|
||||
console.log(JSON.stringify(parsedMessages, null, 2));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Something went wrong", error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false; // Set loading state to false after fetching data
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
function getSignalData() {
|
||||
return {
|
||||
csqData: {},
|
||||
lastUpdate: new Date().toLocaleString(),
|
||||
getcsq() {
|
||||
fetch("/cgi-bin/get_csq")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.csqData = data;
|
||||
this.lastUpdate = new Date(
|
||||
data.LASTUPDATE * 1000
|
||||
).toLocaleString();
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.getcsq();
|
||||
setInterval(() => {
|
||||
this.getcsq();
|
||||
}, 30000);
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
5
old/original_main_repo/simpleadmin/www/js/alpinejs.min.js
vendored
Normal file
5
old/original_main_repo/simpleadmin/www/js/alpinejs.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
81
old/original_main_repo/simpleadmin/www/speedtest.html
Normal file
81
old/original_main_repo/simpleadmin/www/speedtest.html
Normal file
@@ -0,0 +1,81 @@
|
||||
<!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>Speedtest</title>
|
||||
|
||||
<script src="/js/alpinejs.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/css/bulma.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</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="/bandlock.html"> Simple Network </a>
|
||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
||||
<a class="navbar-item" href="/speedtest.html"> OpenSpeedtest </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- END NAV -->
|
||||
<div class="container">
|
||||
<!--OST Widget code start-->
|
||||
<div style="text-align: right">
|
||||
<div style="min-height: 360px">
|
||||
<div
|
||||
style="
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 50%;
|
||||
position: relative;
|
||||
"
|
||||
>
|
||||
<iframe
|
||||
style="
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 360px;
|
||||
border: none;
|
||||
overflow: hidden !important;
|
||||
"
|
||||
src="//openspeedtest.com/speedtest"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- OST Widget code end -->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
48
old/original_main_repo/simpleadmin/www/styles.css
Normal file
48
old/original_main_repo/simpleadmin/www/styles.css
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Google Poppins */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
|
||||
|
||||
*{
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
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: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
border: 4px solid rgba(0, 0, 0, 0.1);
|
||||
border-left-color: #333;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 10px auto;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
132
old/original_main_repo/simpleadmin/www/ttl.html
Normal file
132
old/original_main_repo/simpleadmin/www/ttl.html
Normal file
@@ -0,0 +1,132 @@
|
||||
<!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>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">
|
||||
<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">
|
||||
<a class="navbar-item" href="/"> Connection Info </a>
|
||||
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
|
||||
<a class="navbar-item" href="/bandlock.html"> Simple Network </a>
|
||||
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
|
||||
<a class="navbar-item" href="/speedtest.html"> OpenSpeedtest </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>
|
||||
16
old/original_main_repo/simplefirewall/simplefirewall.sh
Normal file
16
old/original_main_repo/simplefirewall/simplefirewall.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the ports you want to block
|
||||
PORTS=("80" "8080" "8088" "443") # Default ports, will be modified by the install script
|
||||
|
||||
# First, allow specified ports on bridge0, eth0, and tailscale0
|
||||
for port in "${PORTS[@]}"; do
|
||||
iptables -A INPUT -i bridge0 -p tcp --dport $port -j ACCEPT
|
||||
iptables -A INPUT -i eth0 -p tcp --dport $port -j ACCEPT
|
||||
iptables -A INPUT -i tailscale0 -p tcp --dport $port -j ACCEPT
|
||||
done
|
||||
|
||||
# Then, block specified ports on all other interfaces
|
||||
for port in "${PORTS[@]}"; do
|
||||
iptables -A INPUT -p tcp --dport $port -j DROP
|
||||
done
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Simple Firewall Setup
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash /usrdata/simplefirewall/simplefirewall.sh
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=TTL Override
|
||||
After=ql-netd.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usrdata/simplefirewall/ttl-override start
|
||||
User=root
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
53
old/original_main_repo/simplefirewall/ttl-override
Normal file
53
old/original_main_repo/simplefirewall/ttl-override
Normal file
@@ -0,0 +1,53 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Adapted from https://github.com/natecarlson/quectel-rgmii-configuration-notes/blob/main/files/ttl-override
|
||||
# Uses ttlvalue file to read what ttl should be set to
|
||||
|
||||
|
||||
if [ -f /usrdata/simplefirewall/ttlvalue ];
|
||||
then
|
||||
ttlfile=$(</usrdata/simplefirewall/ttlvalue)
|
||||
TTLVALUE=$(echo $ttlfile | grep -o "[0-9]\{1,3\}")
|
||||
|
||||
if [ -z "${TTLVALUE}" ]; then
|
||||
echo "Couldnt get proper ttl value from file" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Couldnt find ttlvalue file, lets generate one with 0 ttlvalue (0 = disabled)
|
||||
touch /usrdata/simplefirewall/ttlvalue && echo '0' > /usrdata/simplefirewall/ttlvalue
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
if (( $TTLVALUE > 0 )); then
|
||||
echo "Adding TTL override rules: "
|
||||
iptables -t mangle -I POSTROUTING -o rmnet+ -j TTL --ttl-set ${TTLVALUE}
|
||||
ip6tables -t mangle -I POSTROUTING -o rmnet+ -j HL --hl-set ${TTLVALUE}
|
||||
else
|
||||
echo "TTLVALUE set to 0, nothing to do..."
|
||||
fi
|
||||
echo "done"
|
||||
;;
|
||||
stop)
|
||||
if (( $TTLVALUE > 0 )); then
|
||||
echo "Removing TTL override rules: "
|
||||
iptables -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set ${TTLVALUE} &>/dev/null || true
|
||||
ip6tables -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set ${TTLVALUE} &>/dev/null || true
|
||||
else
|
||||
echo "TTLVALUE set to 0, nothing to do..."
|
||||
fi
|
||||
echo "done"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage ttl-override { start | stop | restart }" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
1
old/original_main_repo/simplefirewall/ttlvalue
Normal file
1
old/original_main_repo/simplefirewall/ttlvalue
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
69
old/original_main_repo/socat-at-bridge/atcmd
Normal file
69
old/original_main_repo/socat-at-bridge/atcmd
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEVICE=/dev/ttyOUT2
|
||||
BAUD=115200
|
||||
|
||||
# Function to setup device communication parameters
|
||||
setup_device() {
|
||||
stty -F $DEVICE cs8 $BAUD ignbrk -brkint -icrnl -imaxbel \
|
||||
-opost -onlcr -isig -icanon -iexten -echo -echoe -echok \
|
||||
-echoctl -echoke noflsh -ixon -crtscts
|
||||
}
|
||||
|
||||
# Function to send AT command and capture the output
|
||||
send_at_command() {
|
||||
local command="$1"
|
||||
|
||||
# Clear the device buffer before sending a new command
|
||||
echo -n > $DEVICE
|
||||
|
||||
# Send the AT command, preserving the integrity of the input
|
||||
echo -e "$command\r" > $DEVICE
|
||||
|
||||
# Use a temporary file to capture the command output
|
||||
tmpfile=$(mktemp)
|
||||
|
||||
# Start reading the device output to the temporary file
|
||||
cat $DEVICE > "$tmpfile" &
|
||||
CAT_PID=$!
|
||||
|
||||
# Monitor the output file for "OK" or "ERROR"
|
||||
while ! grep -qe "OK" -e "ERROR" "$tmpfile"; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Kill the `cat` process after capturing the response
|
||||
kill $CAT_PID
|
||||
wait $CAT_PID 2>/dev/null
|
||||
|
||||
# Display the response
|
||||
cat "$tmpfile" | while IFS= read -r line; do
|
||||
echo -e "\033[0;32m$line\033[0m"
|
||||
done
|
||||
|
||||
# Clean up
|
||||
rm "$tmpfile"
|
||||
}
|
||||
|
||||
# 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
|
||||
4
old/original_main_repo/socat-at-bridge/killsmd7bridge
Normal file
4
old/original_main_repo/socat-at-bridge/killsmd7bridge
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Look for the process by its command and kill it so socat can have smd7 instead
|
||||
pkill -f "/usr/bin/port_bridge smd7 at_usb2 1"
|
||||
BIN
old/original_main_repo/socat-at-bridge/socat-armel-static
Normal file
BIN
old/original_main_repo/socat-at-bridge/socat-armel-static
Normal file
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Kill port_bridge process on boot
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usrdata/socat-at-bridge/killsmd7bridge
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/ttyIN and write to smd11
|
||||
BindsTo=socat-smd11.service
|
||||
After=socat-smd11.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/ttyIN > /dev/smd11"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/smd11 and write to ttyIN
|
||||
BindsTo=socat-smd11.service
|
||||
After=socat-smd11.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/smd11 > /dev/ttyIN"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Socat Serial Emulation for smd11
|
||||
After=ql-netd.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
|
||||
# Add a delay to prevent the clients from starting too early
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/ttyIN2 and write to smd7
|
||||
BindsTo=socat-smd7.service
|
||||
After=socat-smd7.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/ttyIN2 > /dev/smd7"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/smd7 and write to ttyIN2
|
||||
BindsTo=socat-smd7.service
|
||||
After=socat-smd7.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/smd7 > /dev/ttyIN2"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Socat Serial Emulation for smd7
|
||||
After=ql-netd.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
|
||||
# Add a delay to prevent the clients from starting too early
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Trigger the Tailscale Web UI
|
||||
After=tailscaled.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/systemctl start tailscale-webui
|
||||
RemainAfterExit=yes
|
||||
@@ -0,0 +1,12 @@
|
||||
Description=Tailscale Web Interface
|
||||
After=tailscaled.service
|
||||
Requires=tailscaled.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usrdata/tailscale/tailscale web --listen 0.0.0.0:8088
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,8 @@
|
||||
# Set the port to listen on for incoming VPN packets.
|
||||
# Remote nodes will automatically be informed about the new port number,
|
||||
# but you might want to configure this in order to set external firewall
|
||||
# settings.
|
||||
PORT="41641"
|
||||
|
||||
# Extra flags you might want to pass to tailscaled.
|
||||
FLAGS=""
|
||||
16
old/original_main_repo/tailscale/systemd/tailscaled.service
Normal file
16
old/original_main_repo/tailscale/systemd/tailscaled.service
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Tailscale node agent
|
||||
Documentation=https://tailscale.com/kb/
|
||||
Wants=network-pre.target
|
||||
After=network-pre.target NetworkManager.service systemd-resolved.service
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/usrdata/tailscale/systemd/tailscaled.defaults
|
||||
ExecStartPre=/usrdata/tailscale/tailscaled --cleanup
|
||||
ExecStart=/usrdata/tailscale/tailscaled --statedir=/usrdata/tailscale/ --port=${PORT} $FLAGS
|
||||
ExecStopPost=/usrdata/tailscale/tailscaled --cleanup
|
||||
Restart=on-failure
|
||||
Type=notify
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
101
old/original_main_repo/ttyd/scripts/ICCID_APN.sh
Normal file
101
old/original_main_repo/ttyd/scripts/ICCID_APN.sh
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/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
|
||||
21
old/original_main_repo/ttyd/scripts/ICCIDfun.sh
Normal file
21
old/original_main_repo/ttyd/scripts/ICCIDfun.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
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."
|
||||
}
|
||||
93
old/original_main_repo/ttyd/scripts/ttyd.bash
Normal file
93
old/original_main_repo/ttyd/scripts/ttyd.bash
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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)
|
||||
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
# Start your Actual echo output here, 17 lines omitted for mobile compatibility. ttyd font needs to be size 25.
|
||||
# Echo "Logo"
|
||||
echo " .%+: "
|
||||
echo " .*@@@-. "
|
||||
echo " :@@@@- "
|
||||
echo " @@@@#. "
|
||||
echo " -@@@@#. "
|
||||
echo " :. %@@@@: -# "
|
||||
echo " .+- #@@@@%.+@- "
|
||||
echo " .#- . +@@@@# #@- "
|
||||
echo " -@*@*@% @@@@@::@@= "
|
||||
echo ".+%@@@@@@@@@%=. =@@@@# #@@- .. "
|
||||
echo " .@@@@@: :@@@@@ =@@@..%= "
|
||||
echo " -::@-.+. @@@@@.=@@@- =@- "
|
||||
echo " .@- .@@@@@:.@@@* @@. "
|
||||
echo " .%- -@@@@@:=@@@@ @@# "
|
||||
echo " .#- .%@@@@@@#. +@@@@@.#@@@@ @@@."
|
||||
echo " .*- .@@@@@@@@@@=. @@@@@@ @@@@@ @@@:"
|
||||
echo " :. .%@@@@@@@@@@@%. .@@@@@+:@@@@@ @@@-"
|
||||
echo " -@@@@@@@@@@@@@@@..@@@@@@.-@@@@@ .@@@-"
|
||||
echo " -@@@@@@@@@@%. .@@@@@@. @@@@@+ =@@@="
|
||||
echo " =@@@@@@@@* .@@@@@@. @@@@@@..@@@@-"
|
||||
echo " #@@@@@@@@-*@@@@@%..@@@@@@+ #@@@@-"
|
||||
echo " @@@@@@:.-@@@@@@. @@@@@@= %@@@@@."
|
||||
echo " .@@@@. *@@@@@@- .+@@@@@@-.@@@@@@+ "
|
||||
echo " %@@. =@@@@@*. +@@@@@@%.-@@@@@@% "
|
||||
echo " .@@ .@@@@@= :@@@@@@@@..@@@@@@@= "
|
||||
echo " =@.+@@@@@. -@@@@@@@*.:@@@@@@@*. "
|
||||
echo " %.*@@@@= .@@@@@@@-.:@@@@@@@+. "
|
||||
echo " ..@@@@= .@@@@@@: #@@@@@@@: "
|
||||
echo " .@@@@ +@@@@..%@@@@@+. "
|
||||
echo " .@@@. @@@@.:@@@@+. "
|
||||
echo " @@@. @@@. @@@* .@. "
|
||||
echo " :@@@ %@@..@@#. *@ "
|
||||
echo " -*: .@@* :@@. @@. -..@@ "
|
||||
echo " =@@@@@@.*@- :@% @* =@:=@# "
|
||||
echo " .@@@-+@@@@:%@..%- ...@%:@@: "
|
||||
echo " .@@. @@-%@: .%@@*@@%. "
|
||||
echo " :@@ :+ *@ *@@#*@@@. "
|
||||
echo " =@@@.@@@@ "
|
||||
echo " .*@@@:=@@@@: "
|
||||
echo " .@@@@:.@@@@@: "
|
||||
echo " .@@@@#.-@@@@@. "
|
||||
echo " #@@@@: =@@@@@- "
|
||||
echo " .@@@@@..@@@@@@* "
|
||||
echo " -@@@@@. @@@@@@#. "
|
||||
echo " -@@@@@ @@@@@@% "
|
||||
echo " @@@@@. #@@@@@@. "
|
||||
echo " :@@@@# =@@@@@@% "
|
||||
echo " @@@@@: @@@@@@@: "
|
||||
echo " *@@@@ @@@@@@@. "
|
||||
echo " .@@@@ @@@@@@@ "
|
||||
echo " #@@@. @@@@@@* "
|
||||
echo " @@@# @@@@@@@ "
|
||||
echo " .@@+=@@@@@@. "
|
||||
echo " *@@@@@@ "
|
||||
echo " :@@@@@= "
|
||||
echo " .@@@@@@. "
|
||||
echo " :@@@@@*. "
|
||||
echo " .=@@@@@- "
|
||||
echo " :+##+. "
|
||||
echo "=============================================================="
|
||||
echo "TTYd session file by iamromulan v1.0"
|
||||
echo "Firmware Revision: $firmware_revision"
|
||||
echo "Serial Number: $serial_number"
|
||||
echo "=============================================================="
|
||||
|
||||
# Start a login session
|
||||
exec /bin/login
|
||||
12
old/original_main_repo/ttyd/systemd/ttyd.service
Normal file
12
old/original_main_repo/ttyd/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/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