Compare commits
415 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e970703a11 | |||
| 6b1d2dcca0 | |||
| de3c77ded7 | |||
| b79f0435b7 | |||
| fedca206e8 | |||
| 36915e3e8f | |||
| 1d57cbbca8 | |||
| c413a02fc7 | |||
|
|
909918c538 | ||
|
|
47aaea465b | ||
|
|
a48cb19db8 | ||
|
|
630b897cd5 | ||
|
|
2bc2ae3844 | ||
|
|
5ea71c3ccb | ||
|
|
179c9fa702 | ||
|
|
6dd3eb8ea2 | ||
|
|
5030f2c0bd | ||
|
|
94053b777e | ||
|
|
b4cd059b76 | ||
|
|
696cbf3054 | ||
|
|
6e9acd8c87 | ||
|
|
23038054bd | ||
|
|
90d53cfe1d | ||
|
|
2ef3ea4cb7 | ||
|
|
8c80eb7c0f | ||
|
|
72845b4360 | ||
|
|
6c7ed50953 | ||
|
|
5996be64f4 | ||
|
|
2cbe8b76ab | ||
|
|
f021311c93 | ||
|
|
71f7dacf72 | ||
|
|
517f41c590 | ||
|
|
69800c0608 | ||
|
|
8d7b02ca92 | ||
|
|
7ee03707e3 | ||
|
|
4a76a5d032 | ||
|
|
6c3cf93ffd | ||
|
|
924e06a153 | ||
|
|
a6fbc35f18 | ||
|
|
ec07fb07ac | ||
|
|
d52f2c1b0f | ||
|
|
370eb276a0 | ||
|
|
550552d1a1 | ||
|
|
b2758616cc | ||
|
|
6f72fb4568 | ||
|
|
3235bd2c46 | ||
|
|
d48f2f9c59 | ||
|
|
4b9785ceff | ||
|
|
64ff33c056 | ||
|
|
fffa77f106 | ||
|
|
0673ed1020 | ||
|
|
acddaf7b08 | ||
|
|
3117d70408 | ||
|
|
0e93104d53 | ||
|
|
b4646a6875 | ||
|
|
96158cf859 | ||
|
|
2b961a40ef | ||
|
|
780e3b4cc8 | ||
|
|
c32e90a436 | ||
|
|
c3931dd009 | ||
|
|
643412f4ae | ||
|
|
00ca424ae6 | ||
|
|
949863c70e | ||
|
|
44f3a7aeed | ||
|
|
ca190cebd1 | ||
|
|
435c472b16 | ||
|
|
9c2870eb61 | ||
|
|
a061212ff4 | ||
|
|
91d1ade6a4 | ||
|
|
f872efca51 | ||
|
|
1cd14a2225 | ||
|
|
39907e983a | ||
|
|
0e3497b8f4 | ||
|
|
5fffcfd80d | ||
|
|
f7780a589e | ||
|
|
f2592a3dbb | ||
|
|
865adc2fcd | ||
|
|
3f32d4001b | ||
|
|
dfce6c2b4f | ||
|
|
41b2c6a4f9 | ||
|
|
157f0d61c3 | ||
|
|
b8cd5b3a2a | ||
|
|
08889533f4 | ||
|
|
88d300303c | ||
|
|
f0377e5f9d | ||
|
|
65ceb39c1f | ||
|
|
28536d1d06 | ||
|
|
4de5a1d5df | ||
|
|
14b45941b0 | ||
|
|
14f1c228e1 | ||
|
|
6b9c912a24 | ||
|
|
f6290708bf | ||
|
|
a1598a7206 | ||
|
|
96566daeea | ||
|
|
0e5785cb79 | ||
|
|
4a3a7775dd | ||
|
|
61cdfebc8a | ||
|
|
7c413fe5a0 | ||
|
|
70e9af1273 | ||
|
|
155e8dd9bb | ||
|
|
99a7084594 | ||
|
|
9f800af0fd | ||
|
|
b1cd03ec72 | ||
|
|
3965081d97 | ||
|
|
9ea53d593d | ||
|
|
b4bc15f8ef | ||
|
|
e6a0c00ce8 | ||
|
|
f6739360ee | ||
|
|
0ada4e6f64 | ||
|
|
e7eb32479c | ||
|
|
3c56c295e0 | ||
|
|
f1b08de405 | ||
|
|
b642d1e283 | ||
|
|
9ca4451ef4 | ||
|
|
08b799a906 | ||
|
|
46696cdf28 | ||
|
|
744871a90b | ||
|
|
79f835fd0f | ||
|
|
5e8bcd1d3f | ||
|
|
bf6637996c | ||
|
|
9783d7ac3c | ||
|
|
12cebf6900 | ||
|
|
5f387e7b17 | ||
|
|
bf0c2028b1 | ||
|
|
0858b03da2 | ||
|
|
408cf583dd | ||
|
|
b30daf8ce7 | ||
|
|
b260cf369e | ||
|
|
43ed2669f6 | ||
|
|
6f96491273 | ||
|
|
06b84b48a4 | ||
|
|
acc37fd937 | ||
|
|
9bd4049ace | ||
|
|
49af87089b | ||
|
|
38b6b7ab00 | ||
|
|
51ec7e4a78 | ||
|
|
ff23e5cfac | ||
|
|
345cdf27a7 | ||
|
|
2c062c51ff | ||
|
|
892371adc9 | ||
|
|
969602cfdc | ||
|
|
b300f024b6 | ||
|
|
e93970e679 | ||
|
|
c4fd0d6c7d | ||
|
|
603096ce81 | ||
|
|
dc58ec1792 | ||
|
|
67cc67641b | ||
|
|
eb05cfad0b | ||
|
|
cb0d9e776d | ||
|
|
b89145e9e4 | ||
|
|
a671c2e4c0 | ||
|
|
43e680697f | ||
|
|
af05f087c7 | ||
|
|
30937e20ba | ||
|
|
faae115732 | ||
|
|
365925b210 | ||
|
|
97be66cfe7 | ||
|
|
d9879a4d4e | ||
|
|
b4dac716de | ||
|
|
19cd8c6948 | ||
|
|
e08fdbe279 | ||
|
|
ffbea70a7d | ||
|
|
60cee73a24 | ||
|
|
b56c5c5652 | ||
|
|
10d93c733e | ||
|
|
562a8594da | ||
|
|
bf156b9181 | ||
|
|
0b26f94d82 | ||
|
|
f934c84140 | ||
|
|
41b6caf5db | ||
|
|
bb9da92136 | ||
|
|
e56d521435 | ||
|
|
06668284a6 | ||
|
|
5de91eae55 | ||
|
|
6d6a9ae091 | ||
|
|
0d4e19daf2 | ||
|
|
387f86ed31 | ||
|
|
b8ae6fc95f | ||
|
|
d176d8d251 | ||
|
|
2534045ef5 | ||
|
|
685f666ee5 | ||
|
|
e07d5b8bc4 | ||
|
|
a6203a585d | ||
|
|
5b30e2d3d1 | ||
|
|
31a82aed6a | ||
|
|
79a4439fbf | ||
|
|
25daa60b62 | ||
|
|
d84b8dd3c3 | ||
|
|
5369e15a84 | ||
|
|
2bea6efdf1 | ||
|
|
88afb00cb7 | ||
|
|
12439f73eb | ||
|
|
db4ee5cc46 | ||
|
|
0543a18a40 | ||
|
|
d916c987b5 | ||
|
|
41ee583c8d | ||
|
|
4680237d49 | ||
|
|
17a846fb12 | ||
|
|
f37a22ef5b | ||
|
|
3ab9751fef | ||
|
|
0567bf9984 | ||
|
|
d043c14f5a | ||
|
|
ba8c278eca | ||
|
|
2fb14c315e | ||
|
|
21affeb5e4 | ||
|
|
ad288d4bd4 | ||
|
|
36329df218 | ||
|
|
26728698ac | ||
|
|
88f76ae642 | ||
|
|
2cc65b7dba | ||
|
|
f81c7318e5 | ||
|
|
070f348062 | ||
|
|
75a539df2d | ||
|
|
8f0655b040 | ||
|
|
0ba950f9fa | ||
|
|
d94fe733e1 | ||
|
|
926b0d3415 | ||
|
|
54ddb6a0a3 | ||
|
|
2192f11b50 | ||
|
|
16c455eb69 | ||
|
|
5b0e5ef051 | ||
|
|
c9d0e45aa3 | ||
|
|
906688f458 | ||
|
|
631ab97a9c | ||
|
|
c395467364 | ||
|
|
4a7aac1464 | ||
|
|
516ca5cd1b | ||
|
|
0458890c89 | ||
|
|
222e45a0f4 | ||
|
|
b785e259ea | ||
|
|
752ba5d51a | ||
|
|
61d1cd64b0 | ||
|
|
9a2493cbfe | ||
|
|
c646ce8945 | ||
|
|
10d291151f | ||
|
|
a85a0b17f2 | ||
|
|
1be4607d5d | ||
|
|
1c0d097d82 | ||
|
|
0fe6326e2c | ||
|
|
b1e5a40085 | ||
|
|
5ba4c6b713 | ||
|
|
5c79a22795 | ||
|
|
1f42134cdf | ||
|
|
4bf1d8a9a9 | ||
|
|
e18ec1764c | ||
|
|
fea72c96c4 | ||
|
|
47063d7e8d | ||
|
|
5cc0c08225 | ||
|
|
cbdf13fce5 | ||
|
|
82c2abd1b1 | ||
|
|
e11075edd4 | ||
|
|
0f4be98c07 | ||
|
|
01608d47b5 | ||
|
|
7ddfe0b627 | ||
|
|
003a903d97 | ||
|
|
8f61488e23 | ||
|
|
c2e7727bfe | ||
|
|
0c62275c95 | ||
|
|
db98e44aae | ||
|
|
62146117fe | ||
|
|
dd98716a44 | ||
|
|
221178abb0 | ||
|
|
ec2853878e | ||
|
|
de8ca3eacb | ||
|
|
87f1733830 | ||
|
|
7f17818a9c | ||
|
|
406e586702 | ||
|
|
723b69f662 | ||
|
|
817970bb71 | ||
|
|
e612482dc4 | ||
|
|
78e07160e2 | ||
|
|
df93948f23 | ||
|
|
89f22e1524 | ||
|
|
22a319d0c8 | ||
|
|
9579e75ab3 | ||
|
|
47ebc2a5ab | ||
|
|
a76fb0dcb0 | ||
|
|
9f90a3bbab | ||
|
|
1c41a857a0 | ||
|
|
818505e706 | ||
|
|
a9c2e9c152 | ||
|
|
3fae1fcf61 | ||
|
|
16eafeea42 | ||
|
|
1663b34e1d | ||
|
|
315b937e8f | ||
|
|
dc7f3f17d2 | ||
|
|
91fbff193d | ||
|
|
99716d722c | ||
|
|
fd6e528500 | ||
|
|
d12672c5ff | ||
|
|
ff56fbf190 | ||
|
|
0b3cce7a1f | ||
|
|
b5166a969e | ||
|
|
b63b4d4cea | ||
|
|
ce5e328bae | ||
|
|
ddd553f40e | ||
|
|
59b3bfa6ba | ||
|
|
c081b5c63f | ||
|
|
65a8dadbb6 | ||
|
|
2024ec569c | ||
|
|
223e704adc | ||
|
|
74790da711 | ||
|
|
c82d9496a7 | ||
|
|
05c387d539 | ||
|
|
22cd4be6c8 | ||
|
|
0eb07f75ef | ||
|
|
c528e33876 | ||
|
|
369b877e41 | ||
|
|
9b9052843e | ||
|
|
86da9f8412 | ||
|
|
ed7f22c0ba | ||
|
|
664b7b6bed | ||
|
|
ca895cab0d | ||
|
|
618f978018 | ||
|
|
802c90e7b4 | ||
|
|
6ad0f026e6 | ||
|
|
21c9099606 | ||
|
|
b0545018f2 | ||
|
|
19c233e02b | ||
|
|
8de5015d46 | ||
|
|
bb2921c8fe | ||
|
|
dfbbfe9ba5 | ||
|
|
4458b582d6 | ||
|
|
da10c7b300 | ||
|
|
33f81954d7 | ||
|
|
8ad7da63f1 | ||
|
|
d387d5417b | ||
|
|
5bd84a7fb1 | ||
|
|
039c3d0855 | ||
|
|
0b33a3991e | ||
|
|
968e003fa5 | ||
|
|
6eff6d28cb | ||
|
|
3a506a5eb2 | ||
|
|
cadf231422 | ||
|
|
6e3ccb63d7 | ||
|
|
ea86c78d73 | ||
|
|
a42e85bcf2 | ||
|
|
31b58c431c | ||
|
|
f8c84d2779 | ||
|
|
81b0a9e0ba | ||
|
|
fb108bd043 | ||
|
|
013ce81c09 | ||
|
|
488486bcdc | ||
|
|
93621b3f64 | ||
|
|
e1fb14118b | ||
|
|
2d6067799d | ||
|
|
f9c9f97e95 | ||
|
|
f58ccff0bf | ||
|
|
b423866d0d | ||
|
|
4a3307f683 | ||
|
|
4b92fdbaf0 | ||
|
|
a3b4e40027 | ||
|
|
e19dc87405 | ||
|
|
bc2a2500ad | ||
|
|
f2e4f26b81 | ||
|
|
43827d835c | ||
|
|
de954c1ec4 | ||
|
|
3b739faf66 | ||
|
|
9fae1763e4 | ||
|
|
35993bf722 | ||
|
|
24559dc6f2 | ||
|
|
871708de51 | ||
|
|
9591200848 | ||
|
|
71fb0b2245 | ||
|
|
e82218e264 | ||
|
|
81260a5289 | ||
|
|
7007844977 | ||
|
|
19a10334cb | ||
|
|
d553d6d55a | ||
|
|
93450eb399 | ||
|
|
fdb488f478 | ||
|
|
bce789a5b9 | ||
|
|
182159fe71 | ||
|
|
0ce9b05ef3 | ||
|
|
d8c1799789 | ||
|
|
80b34719a5 | ||
|
|
b450fd2813 | ||
|
|
28c4430ca5 | ||
|
|
2970209753 | ||
|
|
92fb8ab335 | ||
|
|
911df02bd8 | ||
|
|
95b10ece14 | ||
|
|
b7a28b0598 | ||
|
|
dc8149ad67 | ||
|
|
8c69205582 | ||
|
|
2bdbf613e8 | ||
|
|
3eeb641309 | ||
|
|
91b8dde145 | ||
|
|
2f01f9cacc | ||
|
|
efd859e302 | ||
|
|
df20fbeca3 | ||
|
|
b9916a4c1d | ||
|
|
cf39a48263 | ||
|
|
127db81532 | ||
|
|
eb1ae610a0 | ||
|
|
ff887444f7 | ||
|
|
87dab7a813 | ||
|
|
b16f76b9bc | ||
|
|
3dff54a90d | ||
|
|
415ee31bbf | ||
|
|
cef714f755 | ||
|
|
9cd62ec422 | ||
|
|
369e3ad673 | ||
|
|
26a74b1e24 | ||
|
|
07e4e797b7 | ||
|
|
17c8b1f901 | ||
|
|
b1f001b066 | ||
|
|
f320f94e4c | ||
|
|
c543a1e9ab | ||
|
|
1ebd61b7cb | ||
|
|
68a84397b0 | ||
|
|
c724d64d04 | ||
|
|
edee6c61ca | ||
|
|
2c40cacc18 | ||
|
|
a175d0597a |
27
README.md
27
README.md
@@ -1,5 +1,13 @@
|
||||
# RGMII Toolkit
|
||||
Software deployment Toolkit for Quectel RM5xxx series 5G modems utilizing an m.2 to RJ45 adapter (RGMII)
|
||||
|
||||
Current Branch: **SDXLEMUR**
|
||||
|
||||
Please PR to [development-SDXLEMUR](https://github.com/iamromulan/quectel-rgmii-toolkit/tree/development-SDXLEMUR) instead of the main one :)
|
||||
|
||||
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
|
||||
@@ -21,11 +29,16 @@ Software deployment Toolkit for Quectel RM5xxx series 5G modems utilizing an m.2
|
||||
**My goal** is for this to also include any new useful scripts or software for this modem and others that support RGMII mode.
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
# Devleopment Branch: the below commands will download the beta/work in progress toolkit
|
||||
|
||||
## How to Use
|
||||
**To run the Toolkit:**
|
||||
@@ -36,7 +49,7 @@ Software deployment Toolkit for Quectel RM5xxx series 5G modems utilizing an m.2
|
||||
- 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 /
|
||||
adb shell "cd /tmp && wget -O RMxxx_rgmii_toolkit.sh http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR/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**
|
||||
@@ -46,7 +59,7 @@ 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 /
|
||||
cd /tmp && wget -O RMxxx_rgmii_toolkit.sh http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd /
|
||||
```
|
||||
**You should see:**
|
||||

|
||||
@@ -137,6 +150,8 @@ Thank You to:
|
||||
|
||||
[dr-dolomite](https://github.com/dr-dolomite) for some major stat page improvements and this repos first approved external PR!
|
||||
|
||||
[tarunVreddy](https://github.com/tarunVreddy) for helping with the SA band aggregation parse
|
||||
|
||||
### 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
|
||||
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Define toolkit paths
|
||||
GITUSER="iamromulan"
|
||||
GITTREE="main"
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
GITUSER="tyk"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="http://git.ievo.top/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="http://git.ievo.top/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
TMP_DIR="/tmp"
|
||||
USRDATA_DIR="/usrdata"
|
||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||
@@ -11,13 +18,7 @@ SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
SIMPLE_FIREWALL_SERVICE="/lib/systemd/system/simplefirewall.service"
|
||||
GITHUB_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/$GITTREE.zip"
|
||||
GITHUB_SIMPADMIN_FULL_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadminfull.zip"
|
||||
GITHUB_SIMPADMIN_NOCMD_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadminnoatcmds.zip"
|
||||
GITHUB_SIMPADMIN_TTL_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadminttlonly.zip"
|
||||
GITHUB_SIMPADMIN_TEST_URL="https://github.com/$GITUSER/quectel-rgmii-toolkit/archive/refs/heads/simpleadmintest.zip"
|
||||
TAILSCALE_DIR="/usrdata/tailscale/"
|
||||
TAILSCALE_DIR="/usrdata/tailscale"
|
||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||
# AT Command Script Variables and Functions
|
||||
DEVICE_FILE="/dev/smd7"
|
||||
@@ -103,118 +104,115 @@ send_at_commands() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if Simple Admin is installed
|
||||
is_simple_admin_installed() {
|
||||
[ -d "$SIMPLE_ADMIN_DIR" ] && return 0 || return 1
|
||||
}
|
||||
# Check for existing Entware/opkg installation, install if not installed
|
||||
ensure_entware_installed() {
|
||||
remount_rw
|
||||
if [ ! -f "/opt/bin/opkg" ]; then
|
||||
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
|
||||
cd /tmp && wget -O installentware.sh "$GITROOT/installentware.sh" && chmod +x installentware.sh && ./installentware.sh
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mEntware/OPKG installation failed. Please check your internet connection or the repository URL.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
cd /
|
||||
else
|
||||
echo -e "\e[1;32mEntware/OPKG is already installed.\e[0m"
|
||||
if [ "$(readlink /bin/login)" != "/opt/bin/login" ]; then
|
||||
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to install/update AT Socat Bridge
|
||||
install_update_at_socat() {
|
||||
remount_rw
|
||||
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||
rm /opt/etc/shadow
|
||||
rm /opt/etc/passwd
|
||||
cp /etc/shadow /opt/etc/
|
||||
cp /etc/passwd /opt/etc
|
||||
mkdir -p /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
ln -sf /opt/bin/useradd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||
/opt/bin/passwd
|
||||
|
||||
# Install basic and useful utilities
|
||||
opkg install mc htop dfc lsof
|
||||
ln -sf /opt/bin/mc /bin
|
||||
ln -sf /opt/bin/htop /bin
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
fi
|
||||
|
||||
if [ ! -f "/usrdata/root/.profile" ]; then
|
||||
opkg update && opkg install shadow-useradd
|
||||
mkdir -p /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
fi
|
||||
fi
|
||||
if [ ! -f "/opt/sbin/useradd" ]; then
|
||||
echo "useradd does not exist. Installing shadow-useradd..."
|
||||
opkg install shadow-useradd
|
||||
else
|
||||
echo "useradd already exists. Continuing..."
|
||||
fi
|
||||
|
||||
# Stop and disable existing services/files before installing new ones
|
||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||
systemctl daemon-reload > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
|
||||
# Install service units
|
||||
echo -e "\033[0;32mInstalling AT Socat Bridge services...\033[0m"
|
||||
mkdir $SOCAT_AT_DIR
|
||||
cd $SOCAT_AT_DIR
|
||||
mkdir $SOCAT_AT_SYSD_DIR
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/socat-armel-static
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/killsmd7bridge
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/atcmd
|
||||
cd $SOCAT_AT_SYSD_DIR
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11.service
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11-from-ttyIN.service
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd11-to-ttyIN.service
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-killsmd7bridge.service
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7-from-ttyIN2.service
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7-to-ttyIN2.service
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/socat-at-bridge/systemd_units/socat-smd7.service
|
||||
|
||||
# Set execute permissions
|
||||
cd $SOCAT_AT_DIR
|
||||
chmod +x socat-armel-static
|
||||
chmod +x killsmd7bridge
|
||||
chmod +x atcmd
|
||||
|
||||
# Link new command for AT Commands from the shell
|
||||
ln -sf $SOCAT_AT_DIR/atcmd /bin
|
||||
|
||||
# Install service units
|
||||
echo -e "\033[0;32mAdding AT Socat Bridge systemd service units...\033[0m"
|
||||
cp -rf $SOCAT_AT_SYSD_DIR/*.service /lib/systemd/system
|
||||
ln -sf /lib/systemd/system/socat-killsmd7bridge.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11-to-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11-from-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7-to-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7-from-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
systemctl start socat-smd11
|
||||
sleep 2s
|
||||
systemctl start socat-smd11-to-ttyIN
|
||||
systemctl start socat-smd11-from-ttyIN
|
||||
echo -e "\033[0;32mAT Socat Bridge service online: smd11 to ttyOUT\033[0m"
|
||||
systemctl start socat-killsmd7bridge
|
||||
sleep 1s
|
||||
systemctl start socat-smd7
|
||||
sleep 2s
|
||||
systemctl start socat-smd7-to-ttyIN2
|
||||
systemctl start socat-smd7-from-ttyIN2
|
||||
echo -e "\033[0;32mAT Socat Bridge service online: smd7 to ttyOUT2\033[0m"
|
||||
remount_ro
|
||||
cd /
|
||||
echo -e "\033[0;32mAT Socat Bridge services Installed!\033[0m"
|
||||
if [ ! -f "/usr/bin/curl" ] && [ ! -f "/opt/bin/curl" ]; then
|
||||
echo "curl does not exist. Installing curl..."
|
||||
opkg update && opkg install curl
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mFailed to install curl. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "curl already exists. Continuing..."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install Simple Firewall
|
||||
install_simple_firewall() {
|
||||
systemctl stop simplefirewall
|
||||
systemctl stop ttl-override
|
||||
echo -e "\033[0;32mInstalling/Updating Simple Firewall...\033[0m"
|
||||
mount -o remount,rw /
|
||||
mkdir -p "$SIMPLE_FIREWALL_DIR"
|
||||
mkdir -p "$SIMPLE_FIREWALL_SYSTEMD_DIR"
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/simplefirewall.sh" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/simplefirewall.sh
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/ttl-override" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttl-override
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/ttlvalue" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttlvalue
|
||||
chmod +x "$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
chmod +x "$SIMPLE_FIREWALL_DIR/ttl-override"
|
||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/simplefirewall.service
|
||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/ttl-override.service" https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/ttl-override.service
|
||||
cp -rf $SIMPLE_FIREWALL_SYSTEMD_DIR/* /lib/systemd/system
|
||||
ln -sf "/lib/systemd/system/simplefirewall.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
ln -sf "/lib/systemd/system/ttl-override.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
#Uninstall Entware if the Users chooses
|
||||
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
|
||||
systemctl start simplefirewall
|
||||
systemctl start ttl-override
|
||||
remount_ro
|
||||
echo -e "\033[0;32mSimple Firewall installation/update complete.\033[0m"
|
||||
|
||||
# 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'
|
||||
}
|
||||
|
||||
# function to configure the fetures of simplefirewall
|
||||
configure_simple_firewall() {
|
||||
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
||||
echo -e "\033[0;31mSimplefirewall is not installed, would you like to install it?\033[0m"
|
||||
@@ -306,116 +304,56 @@ configure_simple_firewall() {
|
||||
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
||||
}
|
||||
|
||||
set_simpleadmin_passwd(){
|
||||
ensure_entware_installed
|
||||
opkg update
|
||||
opkg install libaprutil
|
||||
wget -O /usrdata/root/bin/htpasswd $GITROOT/simpleadmin/htpasswd && chmod +x /usrdata/root/bin/htpasswd
|
||||
wget -O /usrdata/root/bin/simplepasswd $GITROOT/simpleadmin/simplepasswd && chmod +x /usrdata/root/bin/simplepasswd
|
||||
echo -e "\e[1;32mTo change your simpleadmin (admin) password in the future...\e[0m"
|
||||
echo -e "\e[1;32mIn the console type simplepasswd and press enter\e[0m"
|
||||
/usrdata/root/bin/simplepasswd
|
||||
|
||||
}
|
||||
|
||||
set_root_passwd() {
|
||||
echo -e "\e[1;31mPlease set the root/console password.\e[0m"
|
||||
/opt/bin/passwd
|
||||
}
|
||||
|
||||
# Function to install/update Simple Admin
|
||||
install_simple_admin() {
|
||||
while true; do
|
||||
echo -e "\e[1;32mWhat version of Simple Admin do you want to install? This will start a webserver on port 8080\e[0m"
|
||||
echo -e "\e[1;32m1) Full Install\e[0m"
|
||||
echo -e "\e[1;34m2) No AT Commands, List only\e[0m"
|
||||
echo -e "\e[1;33m3) TTL Only\e[0m"
|
||||
echo -e "\e[1;31m4) Install Test Build (work in progress/not ready yet)\e[0m"
|
||||
echo -e "\e[0;33m5) Return to Main Menu\e[0m"
|
||||
echo -e "\e[1;32mSelect your choice: \e[0m"
|
||||
read choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
install_update_at_socat
|
||||
install_simple_firewall
|
||||
remount_rw
|
||||
cd $TMP_DIR
|
||||
wget $GITHUB_SIMPADMIN_FULL_URL -O simpleadminfull.zip
|
||||
unzip -o simpleadminfull.zip
|
||||
cp -Rf quectel-rgmii-toolkit-simpleadminfull/simpleadmin/ $USRDATA_DIR
|
||||
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
||||
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
||||
systemctl daemon-reload
|
||||
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/simpleadmin_generate_status.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl start simpleadmin_generate_status
|
||||
systemctl start simpleadmin_httpd
|
||||
remount_ro
|
||||
echo "Cleaning up..."
|
||||
rm /tmp/simpleadminfull.zip
|
||||
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminfull/
|
||||
break
|
||||
;;
|
||||
2)
|
||||
install_update_at_socat
|
||||
install_simple_firewall
|
||||
remount_rw
|
||||
cd $TMP_DIR
|
||||
wget $GITHUB_SIMPADMIN_NOCMD_URL -O simpleadminnoatcmds.zip
|
||||
unzip -o simpleadminnoatcmds.zip
|
||||
cp -Rf quectel-rgmii-toolkit-simpleadminnoatcmds/simpleadmin/ $USRDATA_DIR
|
||||
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
||||
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
||||
systemctl daemon-reload
|
||||
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/simpleadmin_generate_status.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl start simpleadmin_generate_status
|
||||
systemctl start simpleadmin_httpd
|
||||
remount_ro
|
||||
echo "Cleaning up..."
|
||||
rm /tmp/simpleadminnoatcmds.zip
|
||||
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminnoatcmds/
|
||||
break
|
||||
;;
|
||||
3)
|
||||
install_simple_firewall
|
||||
remount_rw
|
||||
cd $TMP_DIR
|
||||
wget $GITHUB_SIMPADMIN_TTL_URL -O simpleadminttlonly.zip
|
||||
unzip -o simpleadminttlonly.zip
|
||||
cp -Rf quectel-rgmii-toolkit-simpleadminttlonly/simpleadmin/ $USRDATA_DIR
|
||||
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
||||
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
||||
systemctl daemon-reload
|
||||
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl start simpleadmin_httpd
|
||||
remount_ro
|
||||
echo "Cleaning up..."
|
||||
rm /tmp/simpleadminttlonly.zip
|
||||
rm -rf /tmp/quectel-rgmii-toolkit-simpleadminttlonly/
|
||||
break
|
||||
;;
|
||||
4)
|
||||
install_update_at_socat
|
||||
install_simple_firewall
|
||||
remount_rw
|
||||
cd $TMP_DIR
|
||||
wget $GITHUB_SIMPADMIN_TEST_URL -O simpleadmintest.zip
|
||||
unzip -o simpleadmintest.zip
|
||||
cp -Rf quectel-rgmii-toolkit-simpleadmintest/simpleadmin/ $USRDATA_DIR
|
||||
chmod +x $SIMPLE_ADMIN_DIR/scripts/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
||||
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
||||
systemctl daemon-reload
|
||||
ln -sf /lib/systemd/system/simpleadmin_httpd.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/simpleadmin_generate_status.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl start simpleadmin_generate_status
|
||||
systemctl start simpleadmin_httpd
|
||||
remount_ro
|
||||
break
|
||||
;;
|
||||
5)
|
||||
echo "Returning to main menu..."
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Invalid choice. Please try again."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo -e "\e[1;32mInstalling Simpleadmin 2.0\e[0m"
|
||||
ensure_entware_installed
|
||||
echo -e "\e[1;31m2) Installing Simpleadmin 2.0\e[0m"
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh $GITROOT/simpleupdates/scripts/update_socat-at-bridge.sh && chmod +x /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||
echo -e "\e[1;32mInstalling/updating dependency: socat-at-bridge\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||
echo -e "\e[1;32m Dependency: socat-at-bridge has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_simplefirewall.sh $GITROOT/simpleupdates/scripts/update_simplefirewall.sh && chmod +x /usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||
echo -e "\e[1;32mInstalling/updating dependency: simplefirewall\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||
echo -e "\e[1;32m Dependency: simplefirewall has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
set_simpleadmin_passwd
|
||||
wget -O /usrdata/simpleupdates/scripts/update_simpleadmin.sh $GITROOT/simpleupdates/scripts/update_simpleadmin.sh && chmod +x /usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||
echo -e "\e[1;32mInstalling/updating: Simpleadmin content\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||
echo -e "\e[1;32mSimpleadmin content has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
break
|
||||
}
|
||||
|
||||
# Function to Uninstall Simpleadmin and dependencies
|
||||
uninstall_simpleadmin_components() {
|
||||
echo -e "\e[1;32mStarting the uninstallation process for Simpleadmin components.\e[0m"
|
||||
echo -e "\e[1;32mNote: Uninstalling certain components may affect the functionality of others.\e[0m"
|
||||
echo -e "\e[1;36mIf you are upgrading from an older version of the toolkit uninstall/say yes to all everything.\e[0m"
|
||||
remount_rw
|
||||
|
||||
# Uninstall Simple Firewall
|
||||
@@ -443,49 +381,67 @@ uninstall_simpleadmin_components() {
|
||||
read -p "Enter your choice (1 or 2): " choice_socat_at_bridge
|
||||
if [ "$choice_socat_at_bridge" -eq 1 ]; then
|
||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||
systemctl daemon-reload > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/micropython" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/at-telnet" > /dev/null 2>&1
|
||||
echo -e "\033[0;32mAT Socat Bridge services removed!...\033[0m"
|
||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||
systemctl daemon-reload > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/micropython" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/at-telnet" > /dev/null 2>&1
|
||||
echo -e "\033[0;32mAT Socat Bridge services removed!...\033[0m"
|
||||
fi
|
||||
|
||||
# Uninstall the rest of Simpleadmin
|
||||
echo -e "\e[1;32mDo you want to uninstall the rest of Simpleadmin?\e[0m"
|
||||
# Uninstall ttyd
|
||||
echo -e "\e[1;32mDo you want to uninstall ttyd (simpleadmin console)?\e[0m"
|
||||
echo -e "\e[1;31mWarning: Do not uninstall if you are currently using ttyd to do this!!!\e[0m"
|
||||
echo -e "\e[1;32m1) Yes\e[0m"
|
||||
echo -e "\e[1;31m2) No\e[0m"
|
||||
read -p "Enter your choice (1 or 2): " choice_simpleadmin
|
||||
if [ "$choice_simpleadmin" -eq 1 ]; then
|
||||
echo "Uninstalling the rest of Simpleadmin..."
|
||||
systemctl stop simpleadmin_httpd
|
||||
systemctl stop simpleadmin_generate_status
|
||||
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||
echo "The rest of Simpleadmin uninstalled."
|
||||
echo -e "\e[1;34mUninstalling ttyd...\e[0m"
|
||||
systemctl stop ttyd
|
||||
rm -rf /usrdata/ttyd
|
||||
rm /lib/systemd/system/ttyd.service
|
||||
rm /lib/systemd/system/multi-user.target.wants/ttyd.service
|
||||
rm /bin/ttyd
|
||||
echo -e "\e[1;32mttyd has been uninstalled.\e[0m"
|
||||
fi
|
||||
|
||||
echo "Uninstalling the rest of Simpleadmin..."
|
||||
|
||||
# Check if Lighttpd service is installed and remove it if present
|
||||
if [ -f "/lib/systemd/system/lighttpd.service" ]; then
|
||||
echo "Lighttpd detected, uninstalling Lighttpd and its modules..."
|
||||
systemctl stop lighttpd
|
||||
opkg --force-remove --force-removal-of-dependent-packages remove lighttpd-mod-authn_file lighttpd-mod-auth lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy lighttpd
|
||||
rm -rf $LIGHTTPD_DIR
|
||||
fi
|
||||
|
||||
systemctl stop simpleadmin_generate_status
|
||||
systemctl stop simpleadmin_httpd
|
||||
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||
echo "The rest of Simpleadmin and Lighttpd (if present) uninstalled."
|
||||
remount_ro
|
||||
fi
|
||||
|
||||
echo "Uninstallation process completed."
|
||||
}
|
||||
@@ -494,13 +450,13 @@ uninstall_simpleadmin_components() {
|
||||
tailscale_menu() {
|
||||
while true; do
|
||||
echo -e "\e[1;32mTailscale Menu\e[0m"
|
||||
echo -e "\e[1;32m1) Install/Update/Remove Tailscale\e[0m"
|
||||
echo -e "\e[1;32m1) Install/Update Tailscale\e[0m"
|
||||
echo -e "\e[1;36m2) Configure Tailscale\e[0m"
|
||||
echo -e "\e[1;31m3) Return to Main Menu\e[0m"
|
||||
read -p "Enter your choice: " tailscale_choice
|
||||
|
||||
case $tailscale_choice in
|
||||
1) install_update_remove_tailscale;;
|
||||
1) install_update_tailscale;;
|
||||
2) configure_tailscale;;
|
||||
3) break;;
|
||||
*) echo "Invalid option";;
|
||||
@@ -509,62 +465,17 @@ tailscale_menu() {
|
||||
}
|
||||
|
||||
# Function to install, update, or remove Tailscale
|
||||
install_update_remove_tailscale() {
|
||||
if [ -d "$TAILSCALE_DIR" ]; then
|
||||
echo "Tailscale is already installed."
|
||||
echo "1) Update Tailscale"
|
||||
echo "2) Remove Tailscale"
|
||||
read -p "Enter your choice: " tailscale_update_remove_choice
|
||||
|
||||
case $tailscale_update_remove_choice in
|
||||
1)
|
||||
echo "Updating Tailscale..."
|
||||
/usrdata/tailscale/tailscale update
|
||||
;;
|
||||
2)
|
||||
echo "Removing Tailscale..."
|
||||
remount_rw
|
||||
$TAILSCALE_DIR/tailscale down
|
||||
$TAILSCALE_DIR/tailscale logout
|
||||
systemctl stop tailscaled
|
||||
rm -f /lib/systemd/system/tailscaled.service
|
||||
systemctl daemon-reload
|
||||
rm -rf $TAILSCALE_DIR
|
||||
remount_ro
|
||||
echo "Tailscale removed successfully."
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option";;
|
||||
esac
|
||||
else
|
||||
echo "Installing Tailscale..."
|
||||
remount_rw
|
||||
echo "Creating /usrdata/tailscale/"
|
||||
mkdir $TAILSCALE_DIR
|
||||
mkdir $TAILSCALE_SYSD_DIR
|
||||
cd $TAILSCALE_DIR
|
||||
echo "Downloading binary: /usrdata/tailscale/tailscaled"
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/tailscaled
|
||||
echo "Downloading binary: /usrdata/tailscale/tailscale"
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/tailscale
|
||||
echo "Downloading systemd files..."
|
||||
cd $TAILSCALE_SYSD_DIR
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.service
|
||||
wget https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.defaults
|
||||
sleep 2s
|
||||
echo "Setting Permissions..."
|
||||
chmod +x /usrdata/tailscale/tailscaled
|
||||
chmod +x /usrdata/tailscale/tailscale
|
||||
echo "Copy systemd units..."
|
||||
cp -rf /usrdata/tailscale/systemd/* /lib/systemd/system
|
||||
ln -sf /lib/systemd/system/tailscaled.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
echo "Starting Tailscaled..."
|
||||
systemctl start tailscaled
|
||||
cd /
|
||||
remount_ro
|
||||
echo "Tailscale installed successfully."
|
||||
fi
|
||||
install_update_tailscale() {
|
||||
echo -e "\e[1;31m2) Installing tailscale from the $GITTREE branch\e[0m"
|
||||
ensure_entware_installed
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_tailscale.sh $GITROOT/simpleupdates/scripts/update_tailscale.sh && chmod +x /usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||
echo -e "\e[1;32mInstalling/updating: Tailscale\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
remount_rw
|
||||
/usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||
echo -e "\e[1;32m Tailscale has been updated/installed.\e[0m"
|
||||
}
|
||||
|
||||
# Function to Configure Tailscale
|
||||
@@ -585,8 +496,8 @@ configure_tailscale() {
|
||||
1)
|
||||
remount_rw
|
||||
cd /lib/systemd/system/
|
||||
wget -O tailscale-webui.service https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscale-webui.service
|
||||
wget -O tailscale-webui-trigger.service https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/main/tailscale/systemd/tailscale-webui-trigger.service
|
||||
wget -O tailscale-webui.service $GITROOT/tailscale/systemd/tailscale-webui.service
|
||||
wget -O tailscale-webui-trigger.service $GITROOT/tailscale/systemd/tailscale-webui-trigger.service
|
||||
ln -sf /lib/systemd/system/tailscale-webui-trigger.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
echo "Tailscale Web UI Enabled"
|
||||
@@ -608,7 +519,7 @@ configure_tailscale() {
|
||||
remount_ro
|
||||
;;
|
||||
3) $TAILSCALE_DIR/tailscale up --accept-dns=false --reset;;
|
||||
4) $TAILSCALE_DIR/tailscale up --ssh --accept-dns=false --reset;;
|
||||
4) $TAILSCALE_DIR/tailscale up --ssh --accept-dns=false --reset;;
|
||||
5) $TAILSCALE_DIR/tailscale up --accept-dns=false --reset;;
|
||||
6) $TAILSCALE_DIR/tailscale down;;
|
||||
7) $TAILSCALE_DIR/tailscale logout;;
|
||||
@@ -795,61 +706,61 @@ WantedBy=multi-user.target" > "$cfun_service_path"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function for TTYd install
|
||||
install_ttyd() {
|
||||
echo -e "\e[1;34mStarting ttyd installation process...\e[0m"
|
||||
|
||||
if [ ! -f "/opt/bin/opkg" ]; then
|
||||
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
|
||||
cd /tmp && wget -O installentware.sh "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/installentware.sh" && chmod +x installentware.sh && ./installentware.sh
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mEntware/OPKG installation failed. Please check your internet connection or the repository URL.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
cd /
|
||||
else
|
||||
echo -e "\e[1;32mEntware/OPKG is already installed.\e[0m"
|
||||
install_sshd() {
|
||||
if [ -d "/usrdata/sshd" ]; then
|
||||
echo -e "\e[1;31mSSHD is currently installed.\e[0m"
|
||||
echo -e "Do you want to update or uninstall?"
|
||||
echo -e "1.) Update"
|
||||
echo -e "2.) Uninstall"
|
||||
read -p "Select an option (1 or 2): " sshd_choice
|
||||
|
||||
case $sshd_choice in
|
||||
1)
|
||||
echo -e "\e[1;31m2) Installing sshd from the $GITTREE branch\e[0m"
|
||||
;;
|
||||
2)
|
||||
echo -e "\e[1;31mUninstalling SSHD...\e[0m"
|
||||
systemctl stop sshd
|
||||
rm /lib/systemd/system/sshd.service
|
||||
opkg remove openssh-server-pam
|
||||
echo -e "\e[1;32mSSHD has been uninstalled successfully.\e[0m"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid option. Please select 1 or 2.\e[0m"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
mount -o remount,rw /
|
||||
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
|
||||
|
||||
# Replacing the login and passwd binaries
|
||||
rm /opt/etc/shadow
|
||||
cp /etc/shadow /opt/etc/
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set your system login password.\e[0m"
|
||||
/usr/bin/passwd
|
||||
|
||||
# Setting up ttyd
|
||||
mkdir -p /usrdata/ttyd/scripts /usrdata/ttyd/systemd
|
||||
cd /usrdata/ttyd/
|
||||
wget -O ttyd "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/ttyd/ttyd" && chmod +x ttyd
|
||||
wget -O scripts/ttyd.bash "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/ttyd/scripts/ttyd.bash" && chmod +x scripts/ttyd.bash
|
||||
wget -O systemd/ttyd.service "https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/ttyd/systemd/ttyd.service"
|
||||
cp systemd/ttyd.service /lib/systemd/system/
|
||||
ln -sf /lib/systemd/system/ttyd.service /etc/systemd/system/multi-user.target.wants/
|
||||
|
||||
# Enabling and starting ttyd service
|
||||
systemctl daemon-reload
|
||||
systemctl enable ttyd
|
||||
systemctl start ttyd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mFailed to start ttyd service. Please check the systemd service file and ttyd binary.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\e[1;32mInstall Complete! ttyd server is up on port 443. Note: No TLS/SSL enabled yet.\e[0m"
|
||||
# Proceed with installation or updating if not uninstalling
|
||||
ensure_entware_installed
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_sshd.sh $GITROOT/simpleupdates/scripts/update_sshd.sh && chmod +x /usrdata/simpleupdates/scripts/update_sshd.sh
|
||||
echo -e "\e[1;32mInstalling/updating: SSHd\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_sshd.sh
|
||||
echo -e "\e[1;32m SSHd has been updated/installed.\e[0m"
|
||||
}
|
||||
|
||||
|
||||
# Main menu
|
||||
|
||||
ARCH=$(uname -a)
|
||||
if echo "$ARCH" | grep -q "aarch64"; then
|
||||
cd /tmp && wget -O RM55x_rcPCIe_toolkit.sh http://git.ievo.top/iamromulan/quectel-rgmii-toolkit/SDXPINN/RM55x_rcPCIe_toolkit.sh && chmod +x RM55x_rcPCIe_toolkit.sh && ./RM55x_rcPCIe_toolkit.sh && cd /
|
||||
exit 0
|
||||
elif echo "$ARCH" | grep -q "armv7l"; then
|
||||
# Continue if architecture is armv7l
|
||||
echo "Architecture is armv7l, continuing..."
|
||||
else
|
||||
uname -a
|
||||
echo "Unsupported architecture."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while true; do
|
||||
echo " .%+: "
|
||||
echo " .*@@@-. "
|
||||
@@ -918,14 +829,19 @@ echo " :+##+. "
|
||||
echo "Select an option:"
|
||||
echo -e "\e[0m"
|
||||
echo -e "\e[96m1) Send AT Commands\e[0m" # Cyan
|
||||
echo -e "\e[93m2) Install/Update/Uninstall Simple Admin\e[0m" # Yellow
|
||||
echo -e "\e[95m3) Simple Firewall Management\e[0m" # Light Purple
|
||||
echo -e "\e[94m4) Tailscale Management\e[0m" # Light Blue
|
||||
echo -e "\e[92m5) Install/Change or remove Daily Reboot Timer\e[0m" # Light Green
|
||||
echo -e "\e[91m6) Install/Uninstall CFUN 0 Fix\e[0m" # Light Red
|
||||
echo -e "\e[96m7) Install Entware/OPKG (BETA/Advanced)\e[0m" # Cyan (repeated color for additional options)
|
||||
echo -e "\e[96m8) Install TTYd (BETA,443,No TLS/SSL)\e[0m" # Cyan
|
||||
echo -e "\e[93m9) Exit\e[0m" # Yellow (repeated color for exit option)
|
||||
echo -e "\e[93m2) Install Simple Admin\e[0m" # Yellow
|
||||
echo -e "\e[95m3) Set Simpleadmin (admin) password\e[0m" # Light Purple
|
||||
echo -e "\e[94m4) Set Console/ttyd (root) password\e[0m" # Light Blue
|
||||
echo -e "\e[91m5) Uninstall Simple Admin\e[0m" # Light Red
|
||||
echo -e "\e[95m6) Simple Firewall Management\e[0m" # Light Purple
|
||||
echo -e "\e[94m7) Tailscale Management\e[0m" # Light Blue
|
||||
echo -e "\e[92m8) Install/Change or remove Daily Reboot Timer\e[0m" # Light Green
|
||||
echo -e "\e[96m9) Install/Uninstall CFUN 0 Fix\e[0m" # Cyan (repeated color for additional options)
|
||||
echo -e "\e[91m10) Uninstall Entware/OPKG\e[0m" # Light Red
|
||||
echo -e "\e[92m11) Install Speedtest.net CLI app (speedtest command)\e[0m" # Light Green
|
||||
echo -e "\e[92m12) Install Fast.com CLI app (fast command)(tops out at 40Mbps)\e[0m" # Light Green
|
||||
echo -e "\e[92m13) Install OpenSSH Server\e[0m" # Light Green
|
||||
echo -e "\e[93m14) Exit\e[0m" # Yellow (repeated color for exit option)
|
||||
read -p "Enter your choice: " choice
|
||||
|
||||
case $choice in
|
||||
@@ -933,48 +849,97 @@ echo " :+##+. "
|
||||
send_at_commands
|
||||
;;
|
||||
2)
|
||||
if is_simple_admin_installed; then
|
||||
echo -e "\e[1;31mSimple Admin is already installed. It must be removed first\e[0m"
|
||||
echo -e "\e[1;32m1) Remove\e[0m" # Green
|
||||
echo -e "\e[0;33m2) Return to main menu\e[0m"
|
||||
read -p "Enter your choice: " simple_admin_choice
|
||||
case $simple_admin_choice in
|
||||
1) uninstall_simpleadmin_components;;
|
||||
2) break;;
|
||||
*) echo -e "\e[1;31mInvalid option\e[0m";;
|
||||
esac
|
||||
else
|
||||
echo -e "\e[1;32mInstalling Simple Admin...\e[0m"
|
||||
install_simple_admin
|
||||
fi
|
||||
install_simple_admin
|
||||
;;
|
||||
3)
|
||||
configure_simple_firewall
|
||||
3) set_simpleadmin_passwd
|
||||
;;
|
||||
4)
|
||||
set_root_passwd
|
||||
;;
|
||||
5)
|
||||
uninstall_simpleadmin_components
|
||||
;;
|
||||
6)
|
||||
configure_simple_firewall
|
||||
;;
|
||||
|
||||
4)
|
||||
tailscale_menu
|
||||
;;
|
||||
5)
|
||||
manage_reboot_timer
|
||||
7)
|
||||
tailscale_menu
|
||||
;;
|
||||
8)
|
||||
manage_reboot_timer
|
||||
;;
|
||||
6)
|
||||
manage_cfun_fix
|
||||
9)
|
||||
manage_cfun_fix
|
||||
;;
|
||||
7)
|
||||
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
|
||||
cd /tmp && wget -O installentware.sh https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE/installentware.sh && chmod +x installentware.sh && ./installentware.sh
|
||||
10)
|
||||
echo -e "\033[31mAre you sure you want to uninstall entware?\033[0m"
|
||||
echo -e "\033[31m1) Yes\033[0m"
|
||||
echo -e "\033[31m2) No\033[0m"
|
||||
read -p "Select an option (1 or 2): " user_choice
|
||||
|
||||
case $user_choice in
|
||||
1)
|
||||
# If yes, uninstall existing entware
|
||||
echo -e "\033[31mUninstalling existing entware...\033[0m"
|
||||
uninstall_entware # Assuming uninstall_entware is a defined function or command
|
||||
echo -e "\033[31mEntware has been uninstalled.\033[0m"
|
||||
;;
|
||||
2)
|
||||
# If no, exit the script
|
||||
echo -e "\033[31mUninstallation cancelled.\033[0m"
|
||||
exit # Use 'exit' to terminate the script outside a loop
|
||||
;;
|
||||
*)
|
||||
# Handle invalid input
|
||||
echo -e "\033[31mInvalid option. Please select 1 or 2.\033[0m"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
11)
|
||||
ensure_entware_installed
|
||||
echo -e "\e[1;32mInstalling Speedtest.net CLI (speedtest command)\e[0m"
|
||||
remount_rw
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
cd /usrdata/root/bin
|
||||
wget https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
tar -xzf ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
rm ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
rm speedtest.md
|
||||
cd /
|
||||
ln -sf /usrdata/root/bin/speedtest /bin
|
||||
remount_ro
|
||||
echo -e "\e[1;32mSpeedtest CLI (speedtest command) installed!!\e[0m"
|
||||
echo -e "\e[1;32mTry running the command 'speedtest'\e[0m"
|
||||
echo -e "\e[1;32mNote that it will not work unless you login to the root account first\e[0m"
|
||||
echo -e "\e[1;32mNormaly only an issue in adb, ttyd and ssh you are forced to login\e[0m"
|
||||
echo -e "\e[1;32mIf in adb just type login and then try to run the speedtest command\e[0m"
|
||||
;;
|
||||
8)
|
||||
install_ttyd
|
||||
;;
|
||||
9)
|
||||
echo -e "\e[1;32mGoodbye!\e[0m"
|
||||
12)
|
||||
echo -e "\e[1;32mInstalling fast.com CLI (fast command)\e[0m"
|
||||
remount_rw
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
cd /usrdata/root/bin
|
||||
wget -O fast https://github.com/ddo/fast/releases/download/v0.0.4/fast_linux_arm && chmod +x fast
|
||||
cd /
|
||||
ln -sf /usrdata/root/bin/fast /bin
|
||||
remount_ro
|
||||
echo -e "\e[1;32mFast.com CLI (speedtest command) installed!!\e[0m"
|
||||
echo -e "\e[1;32mTry running the command 'fast'\e[0m"
|
||||
echo -e "\e[1;32mThe fast.com test tops out at 40Mbps on the modem\e[0m"
|
||||
;;
|
||||
13)
|
||||
install_sshd
|
||||
;;
|
||||
14)
|
||||
echo -e "\e[1;32mGoodbye!\e[0m"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid option\e[0m"
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid option\e[0m"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
109
at-list.md
Normal file
109
at-list.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Useful AT Commands
|
||||
|
||||
You can send more than one command at once by sperating them with ``;`` and not including the AT part. ``AT+QENG="servingcell";+QCAINFO`` for example to see the info from both ``AT+QENG="servingcell"`` and ``AT+QCAINFO``
|
||||
|
||||
|
||||
## PCIe RC Ethernet mode setup
|
||||
|
||||
### For RM500-RM521 modems
|
||||
``AT+QETH="eth_driver","r8125",1;+QCFG="pcie/mode",1;+QCFG="usbnet",1;+QMAP="MPDN_rule",0,1,0,1,1,"FF:FF:FF:FF:FF:FF";+QMAP="DHCPV4DNS","disable";+QCFG="usbcfg",0x2C7C,0x0801,1,1,1,1,1,2,0;+CFUN=1,1``
|
||||
|
||||
This will do the following:
|
||||
|
||||
- Set the 2.5Gig Ethernet driver as active
|
||||
- Enable PCIe RC mode
|
||||
- Set to ECM mode via USB and AP mode connection behavior
|
||||
- Enable IPPT
|
||||
- Enable DNS IPPT (disables onboard proxy)
|
||||
- Force Enables ADB Access
|
||||
- Reboots after all the above
|
||||
|
||||
|
||||
|
||||
### For x70 modems (RM550/551)
|
||||
|
||||
For BETA versions of firmware: the adb value 2 trick still works so one and done:
|
||||
|
||||
``AT+QCFG="pcie/mode",1;+QCFG="usbnet",1;+QCFG="usbcfg",0x2C7C,0x0122,1,1,1,1,1,2,0;+CFUN=1,1``
|
||||
|
||||
OR if you are running the latest non-beta firmware
|
||||
|
||||
``AT+QCFG="pcie/mode",1;+QCFG="usbnet",1``
|
||||
|
||||
Then unlock ADB:
|
||||
|
||||
Ask the modem for its adb code by sending: ``AT+QADBKEY?``
|
||||
|
||||
It'll respond with something like ``+QADBKEY: 29229988``
|
||||
|
||||
Take that number and paste it in this generator: https://onecompiler.com/python/3znepjcsq (hint: where it says STDIN)
|
||||
|
||||
You should get something like
|
||||
|
||||
``AT+QADBKEY="mrX4zOPwdSIEjfM"``
|
||||
|
||||
Send that command to the modem and adb will be able to be turned on with the next command
|
||||
|
||||
Now you can turn it on with the usbcfg command ``AT+QCFG="usbcfg"``
|
||||
|
||||
***Be super careful, this controls what ports are on/off over USB.***
|
||||
|
||||
Run it and you will get the current settings. Something like this:
|
||||
|
||||
``+QCFG: "usbcfg",0x2C7C,0x0122,1,1,1,1,1,0,0``
|
||||
|
||||
Send ``AT+QCFG="usbcfg",0x2C7C,0x0122,1,1,1,1,1,1,0`` to enable adb
|
||||
|
||||
Now you can reboot: ``AT+CFUN=1,1``
|
||||
|
||||
|
||||
|
||||
This will do the following:
|
||||
|
||||
- Enable PCIe RC mode (Driver selection is automatic now)
|
||||
- Set to ECM mode via USB and AP mode connection behavior
|
||||
- Force Enables ADB Access
|
||||
- Reboots after all the above
|
||||
|
||||
Tip: APN automatic selection will somtimes choose the wrong APN. You may need to set your APN after powering up with the SIM inserted.
|
||||
|
||||
## The List
|
||||
- ``AT+CFUN=1,1`` (reboot)
|
||||
- ``AT+CFUN=0;CFUN=1`` (Disconnect then reconnect)(tip: run this after chnaging APN and you don't have to reboot)
|
||||
- ``AT+QMAPWAC? ``(get current status of auto connect, 0=disabled 1=enabled)
|
||||
- ``AT+QMAPWAC=1`` (enable auto connect internet for ethernet)
|
||||
- ``AT+QMAPWAC=0`` (disable auto connect for ethernet; use when you want internet over USB to work; IPPT must be disabled)
|
||||
- ``AT+QUIMSLOT?`` (get active sim slot; 1=Slot 1; 2=Slot 2)
|
||||
- ``AT+QUIMSLOT=1`` (switch to sim slot 1)
|
||||
- ``AT+QUIMSLOT=2`` (switch to sim slot 2)
|
||||
- ``AT+CGDCONT?`` (Get active APN profle st 1 through 8)
|
||||
- ``AT+QMBNCFG="AutoSel",0;+QMBNCFG="Deactivate"`` (Disable Automatic APN selection)(You will need to set your APN when you switch SIMs or Slots)(Can also set APN after you switch the run ``AT+CFUN=0;CFUN=1``
|
||||
- ``AT+CGDCONT=1,"IPV4V6","APNHERE"`` (Sets APN profile 1 to APNHERE using both IPV4 and IPV6)
|
||||
- ``AT+GSN`` (Show current IMEI)
|
||||
- ``AT+EGMR=0,7`` (Show current IMEI)
|
||||
- ``AT+EGMR=1,7,"IMEIGOESHERE"`` (sets/repairs IMEI)
|
||||
- ``AT+QCFG="usbcfg",0x2C7C,0x0801,1,1,1,1,1,2,0`` (enables adb bypasses adb key)
|
||||
- ``AT+QENG="servingcell"`` (shows anchor band and network connection status)
|
||||
- ``AT+QCAINFO`` (Show all connected bands/CA info)
|
||||
- ``AT+QNWPREFCFG="mode_pref"`` (Check what the current network search mode is set to)
|
||||
- ``AT+QNWPREFCFG="mode_pref",AUTO`` (Set network search mode to automatic)
|
||||
- ``AT+QNWPREFCFG="mode_pref",NR5G:LTE`` (Set network search mode to 5GNR and 4GLTE only)
|
||||
- ``AT+QNWPREFCFG="mode_pref",NR5G`` (Set network search mode to 5GNR only)
|
||||
- ``AT+QNWPREFCFG="mode_pref",LTE`` (Set network search mode to 4GLTE only)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode"`` (Check to see if SA or NSA NR5G is disabled)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode",0`` (Enable Both SA and NSA 5GNR)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode",1`` (Disable SA 5GNR only)
|
||||
- ``AT+QNWPREFCFG="nr5g_disable_mode",2`` (Disable NSA 5GNR only)
|
||||
- ``AT+QNWPREFCFG="nr5g_band"`` (Get current SA 5GNR bandlock settings)
|
||||
- ``AT+QNWPREFCFG="nsa_nr5g_band"`` (Get current NSA 5GNR bandlock settings)
|
||||
- ``AT+QNWPREFCFG="nr5g_band",1:2:3:4:5:6`` (Example: Lock to SA 5G/NR bands n1,n2,n3,n4,n5, and n6)
|
||||
- ``AT+QNWPREFCFG="nsa_nr5g_band",1:2:3:4:5:6`` (Example: Lock to SA 5G/NR bands n1,n2,n3,n4,n5, and n6)
|
||||
- ``AT+QNWPREFCFG="lte_band"`` (Get current 4GLTE bandlock settings)
|
||||
- ``AT+QNWPREFCFG="lte_band",1:2:3:4:5:6`` (Example: Lock to 4G/LTE bands 1,2,3,4,5, and 6)
|
||||
- ``AT+QMAP="WWAN"`` (Show currently assigned IPv4 and IPv6 from the provider)
|
||||
- ``AT+QMAP="LANIP"`` (Show current DHCP range and Gateway address for VLAN0)
|
||||
- ``AT+QMAP="LANIP",IP_start_range,IP_end_range,Gateway_IP `` (Set IPv4 Start/End range and Gateway IP of DHCP for VLAN0)
|
||||
- ``AT+QMAP="DHCPV4DNS","disable"`` (disable the onboard DNS proxy; recommended for IPPT)
|
||||
- ``AT+QMAP="MPDN_rule",0,1,0,1,1,"FF:FF:FF:FF:FF:FF"`` (Turn on IP Passthrough for Ethernet)
|
||||
(:warning: On the RM551E-GL you must specify the ethernet devices MAC address instead of FF:FF:FF...)
|
||||
- ``AT+QMAP="MPDN_rule",0`` (turn off IPPT/clear MPDN rule 0; Remember to run AT+QMAPWAC=1 and reboot after)
|
||||
114
download
Normal file
114
download
Normal file
@@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Determine the absolute path of the script
|
||||
SCRIPT_PATH=$(realpath "$0")
|
||||
|
||||
download() {
|
||||
if [ "$1" = "github" ]; then
|
||||
download_github_directory "$2" "$3"
|
||||
else
|
||||
download_file "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
download_file() {
|
||||
url="$1"
|
||||
output="${2:-$(basename "$url")}"
|
||||
|
||||
echo "Attempting to download file from URL: $url"
|
||||
echo "Saving to output: $output"
|
||||
|
||||
# Ensure the output directory exists
|
||||
mkdir -p "$(dirname "$output")"
|
||||
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
curl -L -o "$output" "$url"
|
||||
elif command -v wget > /dev/null 2>&1; then
|
||||
wget -O "$output" "$url"
|
||||
else
|
||||
echo "Error: Neither curl nor wget is available."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
download_github_directory() {
|
||||
github_url="$1"
|
||||
output_dir="${2:-.}" # Set output directory to the provided parameter or current directory
|
||||
|
||||
repo_info=$(echo "$github_url" | sed -n 's|https://github.com/\([^/]*\)/\([^/]*\)/tree/\([^/]*\)/\(.*\)|\1 \2 \3 \4|p')
|
||||
owner=$(echo "$repo_info" | cut -d' ' -f1)
|
||||
repo=$(echo "$repo_info" | cut -d' ' -f2)
|
||||
branch=$(echo "$repo_info" | cut -d' ' -f3)
|
||||
directory=$(echo "$repo_info" | cut -d' ' -f4)
|
||||
|
||||
echo "Owner: $owner, Repo: $repo, Branch: $branch, Directory: $directory"
|
||||
|
||||
if [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$branch" ] || [ -z "$directory" ]; then
|
||||
echo "Error: Invalid GitHub URL."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Output directory set to: $output_dir"
|
||||
|
||||
api_url="https://api.github.com/repos/$owner/$repo/contents/$directory?ref=$branch"
|
||||
echo "Fetching directory contents from API URL: $api_url"
|
||||
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
contents=$(curl -s -H "Accept: application/vnd.github.v3+json" "$api_url")
|
||||
elif command -v wget > /dev/null 2>&1; then
|
||||
contents=$(wget -qO- --header="Accept: application/vnd.github.v3+json" "$api_url")
|
||||
else
|
||||
echo "Error: Neither curl nor wget is available."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "API Response Contents:"
|
||||
echo "$contents"
|
||||
|
||||
# Use awk to parse JSON content and prepare commands
|
||||
echo "$contents" | awk -v output_dir="$output_dir" -v owner="$owner" -v repo="$repo" -v branch="$branch" -v script_path="$SCRIPT_PATH" '
|
||||
BEGIN {
|
||||
RS="},"; FS=","; # Set Record Separator to "}," and Field Separator to ","
|
||||
}
|
||||
/"type": "file"/ {
|
||||
file_path = ""; download_url = "";
|
||||
for (i = 1; i <= NF; i++) {
|
||||
if ($i ~ /"path": "/) {
|
||||
gsub(/.*"path": "/, "", $i);
|
||||
gsub(/".*/, "", $i);
|
||||
file_path = $i;
|
||||
}
|
||||
if ($i ~ /"download_url": "/) {
|
||||
gsub(/.*"download_url": "/, "", $i);
|
||||
gsub(/".*/, "", $i);
|
||||
download_url = $i;
|
||||
}
|
||||
}
|
||||
if (file_path && download_url) {
|
||||
output_file_path = output_dir "/" file_path;
|
||||
print "Calling download_file for:", download_url, "to", output_file_path;
|
||||
system("'"$SCRIPT_PATH"'" " \"" download_url "\" \"" output_file_path "\"");
|
||||
}
|
||||
}
|
||||
/"type": "dir"/ {
|
||||
sub_dir = "";
|
||||
for (i = 1; i <= NF; i++) {
|
||||
if ($i ~ /"path": "/) {
|
||||
gsub(/.*"path": "/, "", $i);
|
||||
gsub(/".*/, "", $i);
|
||||
sub_dir = $i;
|
||||
}
|
||||
}
|
||||
if (sub_dir) {
|
||||
print "Calling download_github_directory for sub-directory:", sub_dir;
|
||||
system("'"$SCRIPT_PATH"'" " github \"https://github.com/" owner "/" repo "/tree/" branch "/" sub_dir "\" \"" output_dir "\"");
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
echo "Usage: download <type> <url> [output_directory]"
|
||||
exit 1
|
||||
else
|
||||
download "$@"
|
||||
fi
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Modified by iamromulan 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 |
|
||||
@@ -16,64 +17,6 @@ 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
|
||||
# This step depends on the specific changes made by the user or the installation script
|
||||
|
||||
echo -e '\033[32mInfo: Entware/OPKG has been uninstalled successfully.\033[0m'
|
||||
}
|
||||
|
||||
# Check if /opt exists
|
||||
if [ -d /opt ]; then
|
||||
echo -e "\033[32mDo you want to uninstall Entware/OPKG first? It is already installed.\033[0m"
|
||||
echo -e "\033[32m1) Yes\033[0m"
|
||||
echo -e "\033[32m2) No\033[0m"
|
||||
echo -e "\033[32m3) Cancel\033[0m"
|
||||
read -p "Select an option: " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
# Call the uninstall function
|
||||
uninstall_entware
|
||||
exit 0
|
||||
;;
|
||||
2)
|
||||
# Continue with the script
|
||||
echo "Continuing with the script..."
|
||||
;;
|
||||
3)
|
||||
echo "Canceling. Exiting script."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option. Please select 1, 2, or 3."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
create_opt_mount() {
|
||||
# Bind /usrdata/opt to /opt
|
||||
echo -e '\033[32mInfo: Setting up /opt mount to /usrdata/opt...\033[0m'
|
||||
@@ -114,32 +57,13 @@ EOF
|
||||
}
|
||||
|
||||
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
|
||||
# Automatically rename the existing opkg binary
|
||||
mv "$PRE_OPKG_PATH" "${PRE_OPKG_PATH}_old"
|
||||
echo -e "\033[32mFactory/Already existing opkg has been renamed to opkg_old.\033[0m"
|
||||
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'
|
||||
@@ -206,9 +130,38 @@ 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
|
||||
echo -e '\033[32mInfo: Patching Quectel Login Binary\033[0m'
|
||||
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||
rm /opt/etc/shadow
|
||||
rm /opt/etc/passwd
|
||||
cp /etc/shadow /opt/etc/
|
||||
cp /etc/passwd /opt/etc
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
ln -sf /opt/bin/useradd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||
/usr/bin/passwd
|
||||
|
||||
# Install basic and useful utilites
|
||||
opkg install mc htop dfc lsof
|
||||
ln -sf /opt/bin/mc /bin
|
||||
ln -sf /opt/bin/htop /bin
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
# Remount filesystem as read-only
|
||||
mount -o remount,ro /
|
||||
|
||||
1
simpleadmin/.rev
Normal file
1
simpleadmin/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
7
simpleadmin/console/.profile
Normal file
7
simpleadmin/console/.profile
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
#Path
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
#Post-login execution
|
||||
/usrdata/simpleadmin/console/menu/start_menu.sh
|
||||
150
simpleadmin/console/menu/LAN_settings.sh
Normal file
150
simpleadmin/console/menu/LAN_settings.sh
Normal file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
|
||||
CONFIG_FILE="/etc/data/mobileap_cfg.xml"
|
||||
|
||||
# Display Messages in Colors
|
||||
display_random_color() {
|
||||
local msg="$1"
|
||||
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||
local num_colors=${#colors[@]}
|
||||
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||
}
|
||||
|
||||
display_green() {
|
||||
echo -e "\033[0;32m$1\033[0m"
|
||||
}
|
||||
|
||||
display_red() {
|
||||
echo -e "\033[0;31m$1\033[0m"
|
||||
}
|
||||
|
||||
# Check and Install xml binary if not present
|
||||
check_and_install_xml() {
|
||||
if [ ! -f "/opt/bin/xml" ]; then
|
||||
echo "xml binary not found. Attempting to install xmlstarlet..."
|
||||
opkg update
|
||||
opkg install xmlstarlet
|
||||
# Verify installation
|
||||
if [ ! -f "/opt/bin/xml" ]; then
|
||||
echo "Failed to install xmlstarlet. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "xml binary is available."
|
||||
}
|
||||
|
||||
# Edit XML Value
|
||||
edit_xml_value() {
|
||||
local node="$1"
|
||||
local new_value="$2"
|
||||
/opt/bin/xml ed -L -u "$node" -v "$new_value" "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
# Get Current XML Value
|
||||
get_current_value() {
|
||||
/opt/bin/xml sel -t -v "$1" "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
# Enable/Disable Menu
|
||||
enable_disable_menu() {
|
||||
local node="$1"
|
||||
local current_value=$(get_current_value "$node")
|
||||
echo "Current status: $([ "$current_value" == "1" ] && echo "Enabled" || echo "Disabled")"
|
||||
echo "1. Enable"
|
||||
echo "2. Disable"
|
||||
read -p "Choose an option to toggle (1-2): " choice
|
||||
local new_value="$([ "$choice" == "1" ] && echo "1" || echo "0")"
|
||||
edit_xml_value "$node" "$new_value"
|
||||
display_green "After making changes, please reboot to have them take effect."
|
||||
}
|
||||
|
||||
# Edit Simple Value
|
||||
edit_simple_value() {
|
||||
local node="$1"
|
||||
local description="$2"
|
||||
local current=$(get_current_value "$node")
|
||||
echo "Current $description: $current"
|
||||
read -p "Enter new $description: " new_value
|
||||
edit_xml_value "$node" "$new_value"
|
||||
display_green "After making changes, please reboot to have them take effect."
|
||||
}
|
||||
|
||||
# Edit DHCP IP Range
|
||||
edit_dhcp_range() {
|
||||
local start_ip=$(get_current_value "//MobileAPLanCfg/DHCPCfg/StartIP")
|
||||
local end_ip=$(get_current_value "//MobileAPLanCfg/DHCPCfg/EndIP")
|
||||
echo "Current Start IP: $start_ip"
|
||||
echo "Current End IP: $end_ip"
|
||||
read -p "Enter new Start IP: " new_start_ip
|
||||
read -p "Enter new End IP: " new_end_ip
|
||||
edit_xml_value "//MobileAPLanCfg/DHCPCfg/StartIP" "$new_start_ip"
|
||||
edit_xml_value "//MobileAPLanCfg/DHCPCfg/EndIP" "$new_end_ip"
|
||||
display_green "After making changes, please reboot to have them take effect."
|
||||
}
|
||||
|
||||
# Reboot the system
|
||||
reboot_system() {
|
||||
echo "Rebooting system..."
|
||||
atcmd 'AT+CFUN=1,1' # Ensure this command is correct for your system
|
||||
echo "System reboot initiated. Good luck."
|
||||
}
|
||||
|
||||
# Main Menu
|
||||
main_menu() {
|
||||
while true; do
|
||||
clear
|
||||
display_red "Warning, these changes can break access over the network. Know what you are doing, and be prepared to use ADB to fix this just in case."
|
||||
echo "Configuration Menu"
|
||||
echo "------------------"
|
||||
display_green "1. Edit Gateway IPV4 Address"
|
||||
display_green "2. Edit Gateway URL"
|
||||
display_green "3. Edit LAN DHCP Start/End Range"
|
||||
display_green "4. Edit LAN Subnet Mask"
|
||||
display_green "5. Edit DHCPv6 Base address"
|
||||
display_green "6. Toggle IPv4 NAT"
|
||||
display_green "7. Toggle IPv6 NAT"
|
||||
display_green "8. Toggle DHCP Server"
|
||||
display_green "9. Toggle DHCPv4"
|
||||
display_green "10. Toggle DHCPv6"
|
||||
display_green "11. Toggle WAN Autoconnect"
|
||||
display_green "12. Toggle WAN AutoReconnect"
|
||||
display_green "13. Toggle Roaming"
|
||||
display_green "14. Toggle WAN DNSv4 Passthrough"
|
||||
display_green "15. Toggle WAN DNSv6 Passthrough"
|
||||
display_green "16. Toggle IPPT NAT/Ability to access gateway while in IPPT mode"
|
||||
display_green "17. Toggle UPnP"
|
||||
display_green "18. Reboot System"
|
||||
display_green "19. Exit"
|
||||
echo
|
||||
read -p "Select an option (1-19): " option
|
||||
|
||||
case "$option" in
|
||||
1) edit_simple_value "//MobileAPLanCfg/APIPAddr" "Gateway IPV4 Address";;
|
||||
2) edit_simple_value "//MobileAPLanCfg/GatewayURL" "Gateway URL";;
|
||||
3) edit_dhcp_range;;
|
||||
4) edit_simple_value "//MobileAPLanCfg/SubNetMask" "LAN Subnet Mask";;
|
||||
5) edit_simple_value "//MobileAPLanCfg/ULAIPv6BaseAddr" "DHCPv6 Base Address";;
|
||||
6) enable_disable_menu "//MobileAPNatCfg/IPv4NATDisable";;
|
||||
7) enable_disable_menu "//MobileAPNatv6Cfg/EnableIPv6NAT";;
|
||||
8) enable_disable_menu "//MobileAPLanCfg/EnableDHCPServer";;
|
||||
9) enable_disable_menu "//MobileAPLanCfg/EnableIPV4";;
|
||||
10) enable_disable_menu "//MobileAPLanCfg/EnableIPV6";;
|
||||
11) enable_disable_menu "//MobileAPWanCfg/AutoConnect";;
|
||||
12) enable_disable_menu "//MobileAPWanCfg/ReConnect";;
|
||||
13) enable_disable_menu "//MobileAPWanCfg/Roaming";;
|
||||
14) enable_disable_menu "//Dhcpv4Cfg/EnableDhcpv4Dns";;
|
||||
15) enable_disable_menu "//Dhcpv6Cfg/EnableDhcpv6Dns";;
|
||||
16) enable_disable_menu "//IPPassthroughFeatureWithNAT";;
|
||||
17) enable_disable_menu "//MobileAPSrvcCfg/UPnP";;
|
||||
18) reboot_system;;
|
||||
19) break;;
|
||||
*) echo "Invalid option. Please try again.";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Start by checking and installing xml if necessary, then mount filesystem as rw and run the menu
|
||||
mount -o remount,rw /
|
||||
check_and_install_xml
|
||||
main_menu
|
||||
129
simpleadmin/console/menu/sfirewall_settings.sh
Normal file
129
simpleadmin/console/menu/sfirewall_settings.sh
Normal file
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
|
||||
# Display Messages in Colors
|
||||
display_random_color() {
|
||||
local msg="$1"
|
||||
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||
local num_colors=${#colors[@]}
|
||||
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||
}
|
||||
|
||||
display_green() {
|
||||
echo -e "\033[0;32m$1\033[0m"
|
||||
}
|
||||
|
||||
display_red() {
|
||||
echo -e "\033[0;31m$1\033[0m"
|
||||
}
|
||||
|
||||
set_portblocks() {
|
||||
current_ports_line=$(grep '^PORTS=' "$SIMPLE_FIREWALL_SCRIPT")
|
||||
ports=$(echo "$current_ports_line" | cut -d'=' -f2 | tr -d '()' | tr ' ' '\n' | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mCurrent configured ports:\e[0m"
|
||||
echo "$ports" | awk '{print NR") "$0}'
|
||||
|
||||
while true; do
|
||||
echo -e "\e[1;32mEnter a port number to add/remove, or type 'done' or 'exit' to finish:\e[0m"
|
||||
read port
|
||||
if [ "$port" = "done" ] || [ "$port" = "exit" ]; then
|
||||
if [ "$port" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting without making changes...\e[0m"
|
||||
return
|
||||
fi
|
||||
break
|
||||
elif ! echo "$port" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
elif echo "$ports" | grep -q "^$port\$"; then
|
||||
ports=$(echo "$ports" | grep -v "^$port\$")
|
||||
echo -e "\e[1;32mPort $port removed.\e[0m"
|
||||
else
|
||||
ports=$(echo "$ports"; echo "$port" | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mPort $port added.\e[0m"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$port" != "exit" ]; then
|
||||
new_ports_line="PORTS=($(echo "$ports" | tr '\n' ' '))"
|
||||
sed -i "s/$current_ports_line/$new_ports_line/" "$SIMPLE_FIREWALL_SCRIPT"
|
||||
fi
|
||||
}
|
||||
|
||||
set_ttl(){
|
||||
# TTL configuration code
|
||||
ttl_value=$(cat /usrdata/simplefirewall/ttlvalue)
|
||||
if [ "$ttl_value" -eq 0 ]; then
|
||||
echo -e "\e[1;31mTTL is not set.\e[0m"
|
||||
else
|
||||
echo -e "\e[1;32mTTL value is set to $ttl_value.\e[0m"
|
||||
fi
|
||||
|
||||
echo -e "\e[1;31mType 'exit' to cancel.\e[0m"
|
||||
read -p "What do you want the TTL value to be: " new_ttl_value
|
||||
if [ "$new_ttl_value" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting TTL configuration...\e[0m"
|
||||
return
|
||||
elif ! echo "$new_ttl_value" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
return
|
||||
else
|
||||
/usrdata/simplefirewall/ttl-override stop
|
||||
echo "$new_ttl_value" > /usrdata/simplefirewall/ttlvalue
|
||||
/usrdata/simplefirewall/ttl-override start
|
||||
echo -e "\033[0;32mTTL value updated to $new_ttl_value.\033[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
# function to configure the fetures of simplefirewall
|
||||
simple_firewall_menu() {
|
||||
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
||||
display_random_color "Simplefirewall is not installed, would you like to install it?"
|
||||
display_green "1) Yes"
|
||||
display_red "2) No"
|
||||
read -p "Enter your choice (1-2): " install_choice
|
||||
|
||||
case $install_choice in
|
||||
1)
|
||||
install_simple_firewall
|
||||
;;
|
||||
2)
|
||||
return
|
||||
;;
|
||||
*)
|
||||
display_red "Invalid choice. Please select either 1 or 2."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
display_random_color "Configure Simple Firewall:"
|
||||
display_green "1) Configure incoming port block"
|
||||
display_green "2) Configure TTL"
|
||||
display_green "3) Exit to Main Menu"
|
||||
read -p "Enter your choice (1-2): " menu_choice
|
||||
|
||||
case $menu_choice in
|
||||
1)
|
||||
set_portblocks
|
||||
;;
|
||||
2)
|
||||
set_ttl
|
||||
;;
|
||||
3)
|
||||
return
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid choice. Please select either 1 or 2.\e[0m"
|
||||
;;
|
||||
esac
|
||||
|
||||
systemctl restart simplefirewall
|
||||
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
mount -o remount,rw /
|
||||
simple_firewall_menu
|
||||
118
simpleadmin/console/menu/start_menu.sh
Normal file
118
simpleadmin/console/menu/start_menu.sh
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define executable files path
|
||||
MENU_SH=/usrdata/simpleadmin/console/menu
|
||||
|
||||
# Display Messages in Colors
|
||||
display_random_color() {
|
||||
local msg="$1"
|
||||
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||
local num_colors=${#colors[@]}
|
||||
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||
}
|
||||
|
||||
display_green() {
|
||||
echo -e "\033[0;32m$1\033[0m"
|
||||
}
|
||||
|
||||
display_red() {
|
||||
echo -e "\033[0;31m$1\033[0m"
|
||||
}
|
||||
|
||||
# Menus
|
||||
|
||||
toolkit_menu() {
|
||||
while true; do
|
||||
display_random_color "Run a Toolkit version"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_green "1. Get and run the Toolkit"
|
||||
display_random_color "2. Get and run the Development/unstable Toolkit"
|
||||
display_random_color "3. Exit (Enter Root Shell)"
|
||||
echo
|
||||
read -p "Select an option (1-3): " option
|
||||
|
||||
case "$option" in
|
||||
1) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXLEMUR/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||
2) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development-SDXLEMUR/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||
3) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
apps_menu() {
|
||||
while true; do
|
||||
display_random_color "Run a modem App"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_random_color "1. Open File Browser/Editor (mc)"
|
||||
display_random_color "2. View Used/Available space"
|
||||
display_random_color "3. Open Task Manager/View CPU Load"
|
||||
display_random_color "4. Run speedtest.net test"
|
||||
display_random_color "5. Run fast.com test (30Mbps max)"
|
||||
display_green "6. Go Back"
|
||||
echo
|
||||
read -p "Select an option (1-6): " option
|
||||
|
||||
case "$option" in
|
||||
1) mc ;;
|
||||
2) dfc ;;
|
||||
3) htop ;;
|
||||
4) speedtest ;;
|
||||
5) fast ;;
|
||||
6) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
settings_menu() {
|
||||
while true; do
|
||||
display_random_color "Welcome to" && display_green "iamromulan's" && display_random_color "Simple Console Menu"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_green "1. LAN Settings"
|
||||
display_green "2. simplefirewall settings (TTL and Port Block)"
|
||||
display_green "3. Change simpleadmin (admin) password"
|
||||
display_green "4. Change root password (shell/ssh/console)"
|
||||
display_green "5. Go back"
|
||||
echo
|
||||
read -p "Select an option (1-5): " option
|
||||
|
||||
case "$option" in
|
||||
1) $MENU_SH/LAN_settings.sh ;;
|
||||
2) $MENU_SH/sfirewall_settings.sh ;;
|
||||
3) simplepasswd ;;
|
||||
4) passwd ;;
|
||||
5) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main_menu() {
|
||||
while true; do
|
||||
display_green "Welcome to iamromulan's Simple Console Menu"
|
||||
display_green "To get back to this from the root shell, just type 'menu'"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_random_color "1. Apps"
|
||||
display_random_color "2. Settings"
|
||||
display_random_color "3. Toolkit"
|
||||
display_random_color "4. Exit (Enter Root Shell)"
|
||||
echo
|
||||
read -p "Select an option (1-4): " option
|
||||
|
||||
case "$option" in
|
||||
1) apps_menu ;;
|
||||
2) settings_menu ;;
|
||||
3) toolkit_menu ;;
|
||||
4) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main_menu
|
||||
27
simpleadmin/console/services/ethernet_watchdog.sh
Normal file
27
simpleadmin/console/services/ethernet_watchdog.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the command to execute when the ethernet port breaks
|
||||
command_to_execute="/usrdata/socat-at-bridge/atcmd 'AT+CFUN=1,1'"
|
||||
|
||||
# Define the monitoring function
|
||||
watch() {
|
||||
while true; do
|
||||
# Extract the last 60 lines of dmesg and count the specific pattern occurrences
|
||||
count=$(dmesg | tail -60 | grep -e "eth0: cmd = 0xff, should be 0x47" -e "eth0: pci link is down" | grep -c "eth0")
|
||||
|
||||
# Check if the count of patterns is 4 or more
|
||||
if [ "$count" -ge 4 ]; then
|
||||
echo "Condition met, executing command..."
|
||||
eval "$command_to_execute"
|
||||
# Optionally, add a break here if you want the script to stop after executing the command
|
||||
# break
|
||||
fi
|
||||
|
||||
# Sleep for 3 seconds before checking again
|
||||
sleep 3
|
||||
done
|
||||
}
|
||||
|
||||
# Initial delay before starting monitoring
|
||||
sleep 30
|
||||
watch
|
||||
28
simpleadmin/console/services/ping_watchdog.sh
Normal file
28
simpleadmin/console/services/ping_watchdog.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the hostname or IP address to ping
|
||||
HOSTNAME="google.com"
|
||||
|
||||
# Number of pings to attempt
|
||||
PING_COUNT=6
|
||||
|
||||
# Initialize a counter for successful pings
|
||||
success_count=0
|
||||
|
||||
# Attempt to ping the specified number of times
|
||||
for i in $(seq 1 $PING_COUNT); do
|
||||
# Ping the hostname with a timeout of 1 second per ping
|
||||
if ping -c 1 -W 1 $HOSTNAME &> /dev/null; then
|
||||
((success_count++))
|
||||
else
|
||||
echo "Ping attempt $i failed."
|
||||
fi
|
||||
done
|
||||
|
||||
# Check if all pings failed
|
||||
if [ $success_count -eq 0 ]; then
|
||||
echo "All $PING_COUNT ping attempts failed, executing AT command."
|
||||
/bin/atcmd 'AT+CFUN=1,1'
|
||||
else
|
||||
echo "$success_count out of $PING_COUNT ping attempts were successful."
|
||||
fi
|
||||
14
simpleadmin/console/services/systemd/ping_watchdog.service
Normal file
14
simpleadmin/console/services/systemd/ping_watchdog.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Ping Watchdog Service
|
||||
Wants=network.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 60 # Sleep for 60 seconds to ensure the network is ready
|
||||
ExecStart=/usrdata/simpleadmin/console/services/ping_watchdog.sh
|
||||
Restart=on-failure
|
||||
RestartSec=30s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,7 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Read the serial number and remove the last two digits
|
||||
serial_number=$(cat /sys/devices/soc0/serial_number | sed 's/..$//')
|
||||
# Check if /usrdata/socat-at-bridge/atcmd exists
|
||||
if [ -f "/usrdata/socat-at-bridge/atcmd" ]; then
|
||||
# Read the serial number
|
||||
serial_number=$(/usrdata/socat-at-bridge/atcmd 'AT+EGMR=0,5' | grep '+EGMR:' | cut -d '"' -f2)
|
||||
# Read the firmware revision
|
||||
firmware_revision=$(/usrdata/socat-at-bridge/atcmd 'AT+QGMR' | grep -o 'RM[0-9A-Z].*')
|
||||
else
|
||||
serial_number="UNKNOWN"
|
||||
firmware_revision="UNKNOWN"
|
||||
fi
|
||||
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
@@ -82,9 +90,10 @@ echo " :@@@@@*. "
|
||||
echo " .=@@@@@- "
|
||||
echo " :+##+. "
|
||||
echo "=============================================================="
|
||||
echo "Test ttyd startup file by iamromulan V0.1"
|
||||
echo "quectel-ID: $serial_number"
|
||||
echo "TTYd session file by iamromulan v1.1"
|
||||
echo "Firmware Revision: $firmware_revision"
|
||||
echo "Serial Number: $serial_number"
|
||||
echo "=============================================================="
|
||||
|
||||
# Start a login session
|
||||
exec /bin/login
|
||||
exec /bin/login
|
||||
BIN
simpleadmin/htpasswd
Normal file
BIN
simpleadmin/htpasswd
Normal file
Binary file not shown.
47
simpleadmin/lighttpd.conf
Normal file
47
simpleadmin/lighttpd.conf
Normal file
@@ -0,0 +1,47 @@
|
||||
server.modules = (
|
||||
"mod_redirect",
|
||||
"mod_cgi",
|
||||
"mod_proxy",
|
||||
"mod_openssl",
|
||||
"mod_authn_file",
|
||||
)
|
||||
|
||||
server.username = "www-data"
|
||||
server.groupname = "dialout"
|
||||
|
||||
server.port = 80
|
||||
server.document-root = "/usrdata/simpleadmin/www"
|
||||
index-file.names = ( "index.html" )
|
||||
|
||||
auth.backend = "htpasswd"
|
||||
auth.backend.htpasswd.userfile = "/opt/etc/.htpasswd"
|
||||
|
||||
$SERVER["socket"] == "0.0.0.0:443" {
|
||||
ssl.engine = "enable"
|
||||
ssl.privkey= "/usrdata/simpleadmin/server.key"
|
||||
ssl.pemfile= "/usrdata/simpleadmin/server.crt"
|
||||
ssl.acme-tls-1 = "/etc/simpleadmin/dehydrated/tls-alpn-01"
|
||||
ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2") # (lighttpd 1.4.56 default; recommended to accept only TLSv1.2 and TLSv1.3)
|
||||
auth.require = ( "/" => (
|
||||
"method" => "basic",
|
||||
"realm" => "Authorized users only",
|
||||
"require" => "valid-user"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
# Redirect everything to https
|
||||
$HTTP["scheme"] == "http" {
|
||||
url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")
|
||||
}
|
||||
|
||||
# Anything in /cgi-bin will be run as a script
|
||||
$HTTP["url"] =~ "/cgi-bin/" {
|
||||
cgi.assign = ( "" => "" )
|
||||
}
|
||||
|
||||
# Handle proxy to ttyd if it's running
|
||||
$HTTP["url"] =~ "(^/console)" {
|
||||
proxy.header = ("map-urlpath" => ( "/console" => "/" ), "upgrade" => "enable" )
|
||||
proxy.server = ( "" => ("" => ( "host" => "127.0.0.1", "port" => 8080 )))
|
||||
}
|
||||
60
simpleadmin/script/create_watchcat.sh
Normal file
60
simpleadmin/script/create_watchcat.sh
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Function to create and run the Watchcat script
|
||||
create_and_run_watchcat_script() {
|
||||
local ip=$1
|
||||
local timeout=$2
|
||||
local failure_count=$3
|
||||
local script_path="/usrdata/simpleadmin/script/watchcat.sh"
|
||||
|
||||
# Create the script with the watchcat logic
|
||||
sudo cat << EOF > $script_path
|
||||
#!/bin/sh
|
||||
|
||||
failures=0
|
||||
|
||||
while :; do
|
||||
if ping -c 1 $ip > /dev/null 2>&1; then
|
||||
failures=0
|
||||
else
|
||||
failures=\$((failures + 1))
|
||||
if [ "\$failures" -ge "$failure_count" ]; then
|
||||
echo "Rebooting system due to \$failures consecutive ping failures."
|
||||
/sbin/reboot
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
sleep $timeout
|
||||
done
|
||||
EOF
|
||||
|
||||
# Make the watchcat script executable
|
||||
chmod +x $script_path
|
||||
|
||||
# Create a JSON to be fetched later
|
||||
echo "{\"enabled\": true, \"track_ip\": \"$ip\", \"ping_timeout\": $timeout, \"ping_failure_count\": $failure_count}" > /usrdata/simpleadmin/script/watchcat.json
|
||||
|
||||
# Check if the script was created successfully
|
||||
if [ -f "$script_path" ]; then
|
||||
# Make the script executable
|
||||
chmod +x "$script_path"
|
||||
|
||||
# Run the script in the background
|
||||
# nohup /bin/sh "$script_path" &
|
||||
/bin/sh "$script_path" &
|
||||
|
||||
echo "Watchcat script created and running."
|
||||
else
|
||||
echo "Failed to create the Watchcat script."
|
||||
echo "Please check the script path: $script_path"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if the script is called with the required parameters
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "Usage: $0 <IP> <timeout> <failure_count>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Call the function with the provided arguments
|
||||
create_and_run_watchcat_script "$1" "$2" "$3"
|
||||
32
simpleadmin/script/remove_watchcat.sh
Normal file
32
simpleadmin/script/remove_watchcat.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Function to remove the Watchcat script and JSON file
|
||||
remove_watchcat_script() {
|
||||
local script_path="/usrdata/simpleadmin/script/watchcat.sh"
|
||||
local json_path="/usrdata/simpleadmin/script/watchcat.json"
|
||||
|
||||
# Mount as read-write
|
||||
mount -o remount,rw /
|
||||
|
||||
# Remove the watchcat script if it exists
|
||||
if [ -f "$script_path" ]; then
|
||||
rm "$script_path"
|
||||
echo "Removed $script_path"
|
||||
else
|
||||
echo "$script_path does not exist"
|
||||
fi
|
||||
|
||||
# Remove the JSON file if it exists
|
||||
if [ -f "$json_path" ]; then
|
||||
rm "$json_path"
|
||||
echo "Removed $json_path"
|
||||
else
|
||||
echo "$json_path does not exist"
|
||||
fi
|
||||
|
||||
# Mount as read-only
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Call the function to remove the scripts
|
||||
remove_watchcat_script
|
||||
43
simpleadmin/script/ttl_script.sh
Normal file
43
simpleadmin/script/ttl_script.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check if the required parameters are provided
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <enable|disable> <ttl_value>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign the provided parameters to variables
|
||||
mode="$1"
|
||||
ttl_value="$2"
|
||||
|
||||
# Check if iptables is still set
|
||||
ttlcheck=$(/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||
|
||||
# If TTL is still set, manually remove values
|
||||
if [ ! -z "${ttlcheck}" ]; then
|
||||
/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set "${ttlcheck}" &>/dev/null || true
|
||||
/opt/bin/sudo /usr/sbin/ip6tables -w 5 -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set "${ttlcheck}" &>/dev/null || true
|
||||
fi
|
||||
|
||||
# Handle the enable/disable mode
|
||||
case "${mode}" in
|
||||
enable)
|
||||
# Echo TTL to file
|
||||
echo "${ttl_value}" > /usrdata/simplefirewall/ttlvalue
|
||||
|
||||
# Set Start Service
|
||||
/opt/bin/sudo /usrdata/simplefirewall/ttl-override start
|
||||
;;
|
||||
disable)
|
||||
# Remove TTL value file
|
||||
rm -f /usrdata/simplefirewall/ttlvalue
|
||||
|
||||
# Stop the service
|
||||
/opt/bin/sudo /usrdata/simplefirewall/ttl-override stop
|
||||
;;
|
||||
*)
|
||||
echo "Invalid mode: ${mode}"
|
||||
echo "Usage: $0 <enable|disable> <ttl_value>"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
while true; do
|
||||
# Run AT+CGMM to get the modem model
|
||||
echo -en "AT+CGMM\r\n" | microcom -t 1000 /dev/ttyOUT > /tmp/modemmodel.txt
|
||||
sleep 2
|
||||
|
||||
# Run AT+CGCONTRDP once then proceed to while loop
|
||||
echo -en "AT+CGCONTRDP\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 5 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 5000 /dev/ttyOUT > /tmp/modemstatus.txt
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# Parse
|
||||
if [ -f /tmp/modemstatus.txt ]
|
||||
then
|
||||
/usrdata/simpleadmin/scripts/modemstatus_parse.sh
|
||||
fi
|
||||
fi
|
||||
sleep 25 # Add a sleep to avoid CPU overload
|
||||
done
|
||||
@@ -1,519 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Adapted to work with RJ45 / Quectel Board Dev
|
||||
# Quectel AT Parsing Original source ROOter2203
|
||||
# https://github.com/ofmodemsandmen/ROOterSource2203/blob/6636758b945ff16b6c5b54494de04b74b011c204/package/rooter/ext-rooter-basic/files/usr/lib/rooter/common/quecteldata.sh
|
||||
#
|
||||
|
||||
|
||||
rspr2rssi() {
|
||||
echo ${RSCP} ${BW_N} | awk '{printf "%.0f\n", (($1+10*log(12*$2)/log(10)))}'
|
||||
}
|
||||
|
||||
lte_bw() {
|
||||
BW=$(echo $BW | grep -o "[0-5]\{1\}")
|
||||
case $BW in
|
||||
"0")
|
||||
BW="1.4" ;;
|
||||
"1")
|
||||
BW="3" ;;
|
||||
"2"|"3"|"4"|"5")
|
||||
BW=$((($(echo $BW) - 1) * 5)) ;;
|
||||
esac
|
||||
}
|
||||
|
||||
nr_bw() {
|
||||
BW=$(echo $BW | grep -o "[0-9]\{1,2\}")
|
||||
case $BW in
|
||||
"0"|"1"|"2"|"3"|"4"|"5")
|
||||
BW=$((($(echo $BW) + 1) * 5)) ;;
|
||||
"6"|"7"|"8"|"9"|"10"|"11"|"12")
|
||||
BW=$((($(echo $BW) - 2) * 10)) ;;
|
||||
"13")
|
||||
BW="200" ;;
|
||||
"14")
|
||||
BW="400" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to get the secondary LTE bands
|
||||
get_secondary_bands() {
|
||||
# Extract LTE BANDs from SCC lines
|
||||
SCC_BANDS=$(echo "$OX" | grep '+QCAINFO: "SCC"' | grep -o '"LTE BAND [0-9]\+"' | tr -d '"' | sed '1d')
|
||||
|
||||
# Extract NR5G BANDs from SCC lines
|
||||
NR_BAND=$(echo "$OX" | grep '+QCAINFO: "SCC"' | grep -o '"NR5G BAND [0-9]\+"' | tr -d '"')
|
||||
|
||||
# Check if both SCC and NR bands are non-empty
|
||||
if [ -n "$SCC_BANDS" ] && [ -n "$NR_BAND" ]; then
|
||||
# Concatenate LTE BANDs with NR5G BANDs
|
||||
SC_BANDS="$SCC_BANDS<br />$NR_BAND"
|
||||
else
|
||||
# Set SC_BANDS to the non-empty variable or empty if both are empty
|
||||
SC_BANDS="${SCC_BANDS}${NR_BAND}"
|
||||
fi
|
||||
|
||||
# Get the PCI value. For example: 264 based on this +QCAINFO: "PCC",1775,75,"LTE BAND 3",1,264,-103,-13,-71,0
|
||||
MAIN_PCI=$(echo "$OX" | grep '+QCAINFO: "PCC"' | grep -o ',[0-9]\{1,5\},' | tr -d ',')
|
||||
}
|
||||
|
||||
# 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=$(</tmp/apn.txt)
|
||||
APN=$(echo "$APN" | grep -o '"[^"]*"' | head -n1 | tr -d '"')
|
||||
|
||||
# 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
|
||||
get_secondary_bands
|
||||
# End of QCAINFO
|
||||
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
|
||||
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
|
||||
MODE="LTE/NR EN-DC"
|
||||
echo "0" > /tmp/modnetwork
|
||||
if [ -n "$QENG5" ]; then
|
||||
QENG5=$QENG5",,"
|
||||
# Append the initial PCI value rather than overwriting it
|
||||
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)
|
||||
CHANNEL=$(echo $QENG5 | cut -d, -f10)
|
||||
LBAND=$(echo $QENG5 | cut -d, -f11)
|
||||
PC_BAND="NR5G BAND "$LBAND
|
||||
BW=$(echo $QENG5 | cut -d, -f12)
|
||||
nr_bw
|
||||
LBAND="n"$LBAND" (Bandwidth $BW MHz)"
|
||||
RSCP=$(echo $QENG5 | cut -d, -f13)
|
||||
ECIO=$(echo $QENG5 | cut -d, -f14)
|
||||
if [ "$CSQ_PER" = "-" ]; then
|
||||
BW_N=($BW * 5)
|
||||
RSSI=$(rspr2rssi)
|
||||
CSQ_PER=$((100 - (($RSSI + 51) * 100/-62)))"%"
|
||||
CSQ=$((($RSSI + 113) / 2))
|
||||
CSQ_RSSI=$RSSI" dBm"
|
||||
fi
|
||||
SINRR=$(echo $QENG5 | cut -d, -f15 | grep -o "[0-9]\{1,3\}")
|
||||
if [ -n "$SINRR" ]; then
|
||||
if [ $SINRR -le 30 ]; then
|
||||
SINR=$((($(echo $SINRR) * 2) -20))" dB"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
QRSRP=$(echo "$OX" | grep -o "+QRSRP:[^,]\+,-[0-9]\{1,5\},-[0-9]\{1,5\},-[0-9]\{1,5\}[^ ]*")
|
||||
if [ -n "$QRSRP" ] && [ "$RAT" != "WCDMA" ]; then
|
||||
QRSRP1=$(echo $QRSRP | cut -d, -f1 | grep -o "[-0-9]\+")
|
||||
QRSRP2=$(echo $QRSRP | cut -d, -f2)
|
||||
QRSRP3=$(echo $QRSRP | cut -d, -f3)
|
||||
QRSRP4=$(echo $QRSRP | cut -d, -f4)
|
||||
QRSRPtype=$(echo $QRSRP | cut -d, -f5)
|
||||
if [ "$QRSRPtype" == "NR5G" ]; then
|
||||
if [ -n "$NR_SA" ]; then
|
||||
RSCP=$QRSRP1
|
||||
if [ -n "$QRSRP2" -a "$QRSRP2" != "-32768" ]; then
|
||||
RSCP1="RxD "$QRSRP2
|
||||
fi
|
||||
if [ -n "$QRSRP3" -a "$QRSRP3" != "-32768" -a "$QRSRP3" != "-44" ]; then
|
||||
RSCP=$RSCP" dBm<br />"$QRSRP3
|
||||
fi
|
||||
if [ -n "$QRSRP4" -a "$QRSRP4" != "-32768" -a "$QRSRP4" != "-44" ]; then
|
||||
RSCP1="RxD "$QRSRP4
|
||||
fi
|
||||
else
|
||||
RSCP=$RSRPLTE
|
||||
if [ -n "$QRSRP1" -a "$QRSRP1" != "-32768" -a "$QRSRP1" != "-44" ]; then
|
||||
RSCP=$RSCP" (4G) dBm<br />"$QRSRP1
|
||||
if [ -n "$QRSRP2" -a "$QRSRP2" != "-32768" -a "$QRSRP2" != "-44" ]; then
|
||||
RSCP="$RSCP, $QRSRP2"
|
||||
if [ -n "$QRSRP3" -a "$QRSRP3" != "-32768" -a "$QRSRP3" != "-44" ]; then
|
||||
RSCP="$RSCP, $QRSRP3"
|
||||
if [ -n "$QRSRP4" -a "$QRSRP4" != "-32768" -a "$QRSRP4" != "-44" ]; then
|
||||
RSCP="$RSCP, $QRSRP4"
|
||||
fi
|
||||
fi
|
||||
RSCP=$RSCP" (5G) "
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
elif [ "$QRSRP2$QRSRP3$QRSRP4" != "-44-44-44" -a -z "$QENG5" ]; then
|
||||
RSCP=$QRSRP1
|
||||
if [ "$QRSRP3$QRSRP4" == "-140-140" -o "$QRSRP3$QRSRP4" == "-44-44" -o "$QRSRP3$QRSRP4" == "-32768-32768" ]; then
|
||||
RSCP1="RxD "$(echo $QRSRP | cut -d, -f2)
|
||||
else
|
||||
RSCP=$RSCP" dBm (RxD "$QRSRP2" dBm)<br />"$QRSRP3
|
||||
RSCP1="RxD "$QRSRP4
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
QNSM=$(echo "$QNSM" | grep -o "[0-9]")
|
||||
if [ -n "$QNSM" ]; then
|
||||
MODTYPE="6"
|
||||
case $QNSM in
|
||||
"0" )
|
||||
NETMODE="1" ;;
|
||||
"1" )
|
||||
NETMODE="3" ;;
|
||||
"2"|"5" )
|
||||
NETMODE="5" ;;
|
||||
"3" )
|
||||
NETMODE="7" ;;
|
||||
esac
|
||||
fi
|
||||
if [ -n "$QNWP" ]; then
|
||||
MODTYPE="6"
|
||||
case $QNWP in
|
||||
"AUTO" )
|
||||
NETMODE="1" ;;
|
||||
"WCDMA" )
|
||||
NETMODE="5" ;;
|
||||
"LTE" )
|
||||
NETMODE="7" ;;
|
||||
"LTE:NR5G" )
|
||||
NETMODE="8" ;;
|
||||
"NR5G" )
|
||||
NETMODE="9" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
OX=$(echo "${OX//[ \"]/}")
|
||||
|
||||
REGV=$(echo "$OX" | grep -o "+C5GREG:2,[0-9],[A-F0-9]\{2,6\},[A-F0-9]\{5,10\},[0-9]\{1,2\}")
|
||||
if [ -n "$REGV" ]; then
|
||||
LAC5=$(echo "$REGV" | cut -d, -f3)
|
||||
LAC5=$LAC5" ($(printf "%d" 0x$LAC5))"
|
||||
CID5=$(echo "$REGV" | cut -d, -f4)
|
||||
CID5L=$(printf "%010X" 0x$CID5)
|
||||
RNC5=${CID5L:1:6}
|
||||
RNC5=$RNC5" ($(printf "%d" 0x$RNC5))"
|
||||
CID5=${CID5L:7:3}
|
||||
CID5="Short $(printf "%X" 0x$CID5) ($(printf "%d" 0x$CID5)), Long $(printf "%X" 0x$CID5L) ($(printf "%d" 0x$CID5L))"
|
||||
RAT=$(echo "$REGV" | cut -d, -f5)
|
||||
fi
|
||||
REGV=$(echo "$OX" | grep -o "+CEREG:2,[0-9],[A-F0-9]\{2,4\},[A-F0-9]\{5,8\}")
|
||||
REGFMT="3GPP"
|
||||
if [ -z "$REGV" ]; then
|
||||
REGV=$(echo "$OX" | grep -o "+CEREG:2,[0-9],[A-F0-9]\{2,4\},[A-F0-9]\{1,3\},[A-F0-9]\{5,8\}")
|
||||
REGFMT="SW"
|
||||
fi
|
||||
if [ -n "$REGV" ]; then
|
||||
LAC=$(echo "$REGV" | cut -d, -f3)
|
||||
LAC=$(printf "%04X" 0x$LAC)" ($(printf "%d" 0x$LAC))"
|
||||
if [ $REGFMT = "3GPP" ]; then
|
||||
CID=$(echo "$REGV" | cut -d, -f4)
|
||||
else
|
||||
CID=$(echo "$REGV" | cut -d, -f5)
|
||||
fi
|
||||
CIDL=$(printf "%08X" 0x$CID)
|
||||
RNC=${CIDL:1:5}
|
||||
RNC=$RNC" ($(printf "%d" 0x$RNC))"
|
||||
CID=${CIDL:6:2}
|
||||
CID="Short $(printf "%X" 0x$CID) ($(printf "%d" 0x$CID)), Long $(printf "%X" 0x$CIDL) ($(printf "%d" 0x$CIDL))"
|
||||
|
||||
else
|
||||
REGV=$(echo "$OX" | grep -o "+CREG:2,[0-9],[A-F0-9]\{2,4\},[A-F0-9]\{2,8\}")
|
||||
if [ -n "$REGV" ]; then
|
||||
LAC=$(echo "$REGV" | cut -d, -f3)
|
||||
CID=$(echo "$REGV" | cut -d, -f4)
|
||||
if [ ${#CID} -gt 4 ]; then
|
||||
LAC=$(printf "%04X" 0x$LAC)" ($(printf "%d" 0x$LAC))"
|
||||
CIDL=$(printf "%08X" 0x$CID)
|
||||
RNC=${CIDL:1:3}
|
||||
CID=${CIDL:4:4}
|
||||
CID="Short $(printf "%X" 0x$CID) ($(printf "%d" 0x$CID)), Long $(printf "%X" 0x$CIDL) ($(printf "%d" 0x$CIDL))"
|
||||
else
|
||||
LAC=""
|
||||
fi
|
||||
else
|
||||
LAC=""
|
||||
fi
|
||||
fi
|
||||
REGSTAT=$(echo "$REGV" | cut -d, -f2)
|
||||
if [ "$REGSTAT" == "5" -a "$COPS" != "-" ]; then
|
||||
COPS_MNC=$COPS_MNC" (Roaming)"
|
||||
fi
|
||||
if [ -n "$CID" -a -n "$CID5" ] && [ "$RAT" == "13" -o "$RAT" == "10" ]; then
|
||||
LAC="4G $LAC, 5G $LAC5"
|
||||
CID="4G $CID<br />5G $CID5"
|
||||
RNC="4G $RNC, 5G $RNC5"
|
||||
elif [ -n "$CID5" ]; then
|
||||
LAC=$LAC5
|
||||
CID=$CID5
|
||||
RNC=$RNC5
|
||||
fi
|
||||
if [ -z "$LAC" ]; then
|
||||
LAC="-"
|
||||
CID="-"
|
||||
RNC="-"
|
||||
fi
|
||||
|
||||
LUPDATE=$(date +%s)
|
||||
rm -fR /tmp/signal.txt
|
||||
MODEZ=$(echo $MODE | tr -d '"')
|
||||
{
|
||||
echo 'PROVIDER="'"$PROVIDER"'"'
|
||||
echo 'CSQ="'"$CSQ"'"'
|
||||
echo 'CSQ_PER="'"$CSQ_PER"'"'
|
||||
echo 'CSQ_RSSI="'"$CSQ_RSSI"'"'
|
||||
echo 'ECIO="'"$ECIO"'"'
|
||||
echo 'RSCP="'"$RSCP"'"'
|
||||
echo 'ECIO1="'"$ECIO1"'"'
|
||||
echo 'RSCP1="'"$RSCP1"'"'
|
||||
echo 'MODE="'"$MODEZ"'"'
|
||||
echo 'MODTYPE="'"$MODTYPE"'"'
|
||||
echo 'NETMODE="'"$NETMODE"'"'
|
||||
echo 'CHANNEL="'"$CHANNEL"'"'
|
||||
echo 'LBAND="'"$LBAND"'"'
|
||||
echo 'PC_BAND="'"$PC_BAND"'"'
|
||||
echo 'SC_BANDS="'"$SC_BANDS"'"'
|
||||
echo 'APN="'"$APN"'"'
|
||||
echo 'MODEM_MODEL="'"$MODEM_MODEL"'"'
|
||||
echo 'SIMSLOT="'"$SIMSLOT"'"'
|
||||
echo 'PCI="'"$PCI"'"'
|
||||
echo 'TEMP="'"$CTEMP"'"'
|
||||
echo 'SINR="'"$SINR"'"'
|
||||
echo 'LASTUPDATE="'"$LUPDATE"'"'
|
||||
echo 'COPS="'"$COPS"'"'
|
||||
echo 'COPS_MCC="'"$COPS_MCC"'"'
|
||||
echo 'COPS_MNC="'"$COPS_MNC"'"'
|
||||
echo 'MCCMNC="'"$MCCMNC"'"'
|
||||
echo 'LAC="'"$LAC"'"'
|
||||
echo 'LAC_NUM="'""'"'
|
||||
echo 'CID="'"$CID"'"'
|
||||
echo 'CID_NUM="'""'"'
|
||||
echo 'RNC="'"$RNC"'"'
|
||||
echo 'RNC_NUM="'""'"'
|
||||
} > /tmp/signal.txt
|
||||
|
||||
# Pregenerate JSON File
|
||||
/usrdata/simpleadmin/scripts/tojson.sh /tmp/signal.txt > /tmp/modemstatus.json
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/bash
|
||||
# sarav (hello@grity.com)
|
||||
# convert key=value to json
|
||||
# Created at Gritfy ( Devops Junction )
|
||||
# Updated by: dr-dolomite to make it more robust since it was failing on some casess
|
||||
|
||||
file_name="$1"
|
||||
|
||||
echo "{"
|
||||
last_line=$(wc -l < "$file_name")
|
||||
|
||||
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')
|
||||
|
||||
# Print key-value pair in JSON format without surrounding double quotes on value
|
||||
printf ' "%s" : %s' "$key" "$value"
|
||||
|
||||
# Check if not the last line, add comma
|
||||
if [ $((++current_line)) -lt "$last_line" ]; then
|
||||
printf ','
|
||||
fi
|
||||
|
||||
printf '\n'
|
||||
done < "$file_name"
|
||||
|
||||
echo "}"
|
||||
5
simpleadmin/simplepasswd
Normal file
5
simpleadmin/simplepasswd
Normal file
@@ -0,0 +1,5 @@
|
||||
#/bin/bash
|
||||
|
||||
echo -e "\e[1;31mPlease set your simpleadmin (User: admin) web login password.\e[0m"
|
||||
/usrdata/root/bin/htpasswd -c /opt/etc/.htpasswd admin
|
||||
echo -e "\e[1;32mPassword set.\e[0m"
|
||||
14
simpleadmin/systemd/lighttpd.service
Normal file
14
simpleadmin/systemd/lighttpd.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Lighttpd Daemon
|
||||
After=network.target opt.mount
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
PIDFile=/opt/var/run/lighttpd.pid
|
||||
ExecStartPre=/opt/sbin/lighttpd -tt -f /usrdata/simpleadmin/lighttpd.conf
|
||||
ExecStart=/opt/sbin/lighttpd -D -f /usrdata/simpleadmin/lighttpd.conf
|
||||
ExecReload=/bin/kill -USR1 $MAINPID
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,9 +0,0 @@
|
||||
[Unit]
|
||||
Description=Simpleadmin service to generate status from modem
|
||||
|
||||
[Service]
|
||||
ExecStart=/usrdata/simpleadmin/scripts/build_modem_status
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,11 +0,0 @@
|
||||
[Unit]
|
||||
Description=SimpleAdmin httpd service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/sbin/httpd -f -h /usrdata/simpleadmin/www -p 8080
|
||||
ExecStop=/bin/kill -WINCH ${MAINPID}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
12
simpleadmin/systemd/ttyd.service
Normal file
12
simpleadmin/systemd/ttyd.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=TTYD Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usrdata/simpleadmin/console/ttyd -i 127.0.0.1 -p 8080 -t 'theme={"foreground":"white","background":"black"}' -t fontSize=25 --writable /usrdata/simpleadmin/console/ttyd.bash
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,179 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>RM5xxx AT Commands</title>
|
||||
|
||||
<script src="/js/alpinejs.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/css/bulma.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/admin.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- START NAV -->
|
||||
<nav class="navbar is-black" x-data="{ isOpen: false }">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item brand-text" href="/">
|
||||
Quectel 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="/ttl.html">
|
||||
TTL Changer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- END NAV -->
|
||||
<div class="container" x-data="atCommands()">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<div class="columns">
|
||||
<div class="column is-4">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
AT Command
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<div class="field">
|
||||
<label class="label">AT Command</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" placeholder="ATI" x-model="atcmd">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<p class="control">
|
||||
<button class="button is-success" @click="sendAtCommand()">
|
||||
Send AT Command
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-8">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
ATI Response
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<textarea class="textarea" placeholder="ATI Responses Will Appear Here" rows="10"
|
||||
x-text="atCommandResponse"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- START Useful Commands Section -->
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Useful Commands
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<!-- Add your useful commands content here -->
|
||||
<p>Here are some useful commands:</p>
|
||||
<ul>
|
||||
<li>See https://github.com/iamromulan/RM520N-GL#at-commands for more </li>
|
||||
<li>AT+CFUN=1,1 (reboot)</li>
|
||||
<li>AT+QMAPWAC? (get current status of auto connect, 0=disabled 1=enabled)</li>
|
||||
<li>AT+QMAPWAC=1 (enable auto connect internet for ethernet)</li>
|
||||
<li>AT+QMAPWAC=0 (disable auto connect for ethernet; use when you want internet over usb to work; IPPT must be disabled)</li>
|
||||
<li>AT+QUIMSLOT? (get active sim slot; 1=Slot 1; 2=Slot 2)</li>
|
||||
<li>AT+QUIMSLOT=1 (switch to sim slot 1)</li>
|
||||
<li>AT+QUIMSLOT=2 (switch to sim slot 2)</li>
|
||||
<li>AT+CGDCONT? (Get active APN profle list 1 through 8)</li>
|
||||
<li>AT+CGDCONT=1,"IPV4V6","APNHERE" (Sets APN profle 1 to APNHERE using both IPV4 and IPV6)</li>
|
||||
<li>AT+GSN (Show current IMEI)</li>
|
||||
<li>AT+EGMR=1,7,"IMEIGOESHERE" (sets/repairs IMEI)</li>
|
||||
<li>AT+QCAINFO (Show all connected bands/CA info)</li>
|
||||
<li>AT+QNWPREFCFG="mode_pref" (Check what the current network search mode is set to)</li>
|
||||
<li>AT+QNWPREFCFG="mode_pref",AUTO (Set network search mode to automatic)</li>
|
||||
<li>AT+QNWPREFCFG="mode_pref",NR5G:LTE (Set network search mode to 5G/NR and 4G/LTE only)</li>
|
||||
<li>AT+QNWPREFCFG="mode_pref",NR5G (Set network search mode to 5G/NR only)</li>
|
||||
<li>AT+QNWPREFCFG="mode_pref",LTE (Set network search mode to 4G/LTE only)</li>
|
||||
<li>AT+QNWPREFCFG="nr5g_disable_mode" (Check to see if SA or NSA NR5G is disabled)</li>
|
||||
<li>AT+QNWPREFCFG="nr5g_disable_mode",0 (Enable Both SA and NSA 5G/NR)</li>
|
||||
<li>AT+QNWPREFCFG="nr5g_disable_mode",1 (Disable SA 5G/NR only)</li>
|
||||
<li>AT+QNWPREFCFG="nr5g_disable_mode",2 (Disable NSA 5G/NR only)</li>
|
||||
<li>AT+QNWPREFCFG="nr5g_band" (Get current 5G/NR bandlock settings)</li>
|
||||
<li>AT+QNWPREFCFG="nr5g_band",1:2:3:4:5:6 (Example: Lock to 5G/NR bands n1,n2,n3,n4,n5, and n6)</li>
|
||||
<li>AT+QNWPREFCFG="lte_band" (Get current 4G/LTE bandlock settings)</li>
|
||||
<li>AT+QNWPREFCFG="lte_band",1:2:3:4:5:6 (Example: Lock to 4G/LTE bands 1,2,3,4,5, and 6)</li>
|
||||
<li>AT+QMAP="WWAN" (Show currently assigned IPv4 and IPv6 from the provider)</li>
|
||||
<li>AT+QMAP="LANIP" (Show current DHCP range and Gateway address for VLAN0)</li>
|
||||
<li>AT+QMAP="LANIP",IP_start_range,IP_end_range,Gateway_IP (Set IPv4 Start/End range and Gateway IP of DHCP for VLAN0)</li>
|
||||
<li>AT+QMAP="DHCPV4DNS","disable" (disable the onboard DNS proxy; recommended for IPPT)</li>
|
||||
<li>AT+QMAP="MPDN_rule",0,1,0,1,1,"FF:FF:FF:FF:FF:FF" (Turn on IP Passthrough for Ethernet)</li>
|
||||
<li>AT+QMAP="MPDN_rule",0 (turn off IPPT/clear MPDN rule 0; Remember to run AT+QMAPWAC=1 and reboot after)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END Useful Commands Section -->
|
||||
|
||||
<script>
|
||||
|
||||
function atCommands() {
|
||||
return {
|
||||
isLoading: false,
|
||||
atcmd: null,
|
||||
atCommandResponse: null,
|
||||
sendAtCommand() {
|
||||
fetch('/cgi-bin/get_atcommand?' + new URLSearchParams({
|
||||
atcmd: this.atcmd,
|
||||
}))
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.isLoading = false;
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -3,24 +3,30 @@ 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
|
||||
|
||||
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
|
||||
|
||||
x=$(urldecode "$atcmd")
|
||||
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
|
||||
if [ -n "${MYATCMD}" ]; then
|
||||
x=$(urldecode "$atcmd")
|
||||
runcmd=$(echo -en "$x\r\n" | microcom -t 2000 /dev/ttyOUT2)
|
||||
# Initialize wait time to 200 ms
|
||||
wait_time=200
|
||||
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"
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -f /tmp/modemstatus.json ]
|
||||
then
|
||||
/usrdata/simpleadmin/scripts/modemstatus_parse.sh > /dev/null
|
||||
fi
|
||||
|
||||
runcmd=$(</tmp/modemstatus.json)
|
||||
|
||||
echo "Content-type: text/json"
|
||||
echo ""
|
||||
cat <<EOT
|
||||
$runcmd
|
||||
19
simpleadmin/www/cgi-bin/get_ping
Normal file
19
simpleadmin/www/cgi-bin/get_ping
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will ping 8.8.8.8 and return the result
|
||||
# If the ping is successful, it will return "OK"
|
||||
# If the ping fails, it will return "ERROR"
|
||||
|
||||
# Send the ping command and store the output
|
||||
ping_output=$(ping -c 1 8.8.8.8)
|
||||
|
||||
# Check if the output contains "0% packet loss"
|
||||
if echo "$ping_output" | grep -q "0% packet loss"; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "OK"
|
||||
else
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "ERROR"
|
||||
fi
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check iptables for ttlvalue
|
||||
ttlvalue=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||
ttlvalue=$(/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -vnL | grep TTL | awk '{print $13}' | head -n1)
|
||||
ttlenabled=true;
|
||||
|
||||
# Set Variables
|
||||
@@ -16,4 +16,5 @@ cat <<EOT
|
||||
{
|
||||
"isEnabled": $ttlenabled,
|
||||
"ttl": $ttlvalue
|
||||
}
|
||||
}
|
||||
EOT
|
||||
|
||||
11
simpleadmin/www/cgi-bin/get_uptime
Normal file
11
simpleadmin/www/cgi-bin/get_uptime
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Execute the uptime command and store the result
|
||||
uptime_output=$(uptime)
|
||||
|
||||
# Set header for plain text content
|
||||
echo "Content-Type: text/plain"
|
||||
echo ""
|
||||
|
||||
# Output the uptime result
|
||||
echo "$uptime_output"
|
||||
17
simpleadmin/www/cgi-bin/get_watchcat_status
Normal file
17
simpleadmin/www/cgi-bin/get_watchcat_status
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Content type header
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# This script fetches the watchCat parameters from the /tmp/watchcat.json and returns it as JSON
|
||||
# Example content of /tmp/watchcat:
|
||||
# {"watchcat": {"enabled": true, "track_ip": "1.1.1.1", "ping_timeout": 30, "ping_failure_count": 10}}
|
||||
|
||||
# Check if the file exists
|
||||
if [ -f /tmp/watchcat.json ]; then
|
||||
cat /tmp/watchcat.json
|
||||
else
|
||||
# return an empty JSON object
|
||||
echo "{}"
|
||||
fi
|
||||
31
simpleadmin/www/cgi-bin/send_sms
Normal file
31
simpleadmin/www/cgi-bin/send_sms
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
urldecode() {
|
||||
local data
|
||||
data="${*//+/ }"
|
||||
echo -e "${data//%/\\x}"
|
||||
}
|
||||
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [[ "$cmd" == *=* ]]; then
|
||||
key=$(echo "$cmd" | awk -F '=' '{print $1}')
|
||||
value=$(echo "$cmd" | awk -F '=' '{print $2}')
|
||||
eval "$key"="$(urldecode "$value")"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
phone_number="$number"
|
||||
message_encoded="$msg"
|
||||
|
||||
|
||||
send_at_command() {
|
||||
local cmd=$1
|
||||
echo -en "$cmd\r" | microcom -t 100 /dev/ttyOUT2
|
||||
}
|
||||
|
||||
send_at_command "AT+CMGS=\"$phone_number\","$Command""
|
||||
runcmd=$((echo -en "$message_encoded"; echo -en "\x1A") | microcom -t 500 /dev/ttyOUT2)
|
||||
echo "$runcmd"
|
||||
@@ -1,61 +1,64 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Debug log function
|
||||
log_debug() {
|
||||
local message="$1"
|
||||
debug_logs+=("$message")
|
||||
}
|
||||
|
||||
# Initialize debug logs array
|
||||
declare -a debug_logs=()
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
log_debug "Received parameter: $key=$value"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
setTTL=$(printf '%b\n' "${ttlvalue//%/\\x}")
|
||||
|
||||
if [ -n "${setTTL}" ]; then
|
||||
# Stop Service To Remove Rules
|
||||
log_debug "Stopping 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
|
||||
# Convert ttlvalue to integer
|
||||
if [ "${ttlvalue}" ]; then
|
||||
ttlvalue_int=$(echo "${ttlvalue}" | sed 's/[^0-9]//g')
|
||||
log_debug "Converted ttlvalue to integer: $ttlvalue_int"
|
||||
fi
|
||||
|
||||
# Echo TTL to file
|
||||
echo $setTTL > /usrdata/simplefirewall/ttlvalue
|
||||
# Call the sh script with the appropriate parameters
|
||||
if [ "${ttlvalue_int}" != 0 ]; then
|
||||
log_debug "Enabling TTL with value: ${setTTL}"
|
||||
/usrdata/simpleadmin/script/ttl_script.sh enable "${setTTL}"
|
||||
commandRan="/usrdata/simpleadmin/script/ttl_script.sh enable ${setTTL}"
|
||||
ttlenabled=true
|
||||
ttlvalue=$ttlvalue_int
|
||||
elif [ "${ttlvalue_int}" = 0 ]; then
|
||||
log_debug "Disabling TTL"
|
||||
/usrdata/simpleadmin/script/ttl_script.sh disable 0
|
||||
commandRan="/usrdata/simpleadmin/script/ttl_script.sh disable 0"
|
||||
ttlenabled=false
|
||||
ttlvalue=0
|
||||
fi
|
||||
|
||||
# Set Start Service
|
||||
log_debug "Starting service to apply rules"
|
||||
/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 "Content-type: text/text"
|
||||
echo ""
|
||||
cat <<EOT
|
||||
{
|
||||
"isEnabled": $ttlenabled,
|
||||
"ttl": $ttlvalue
|
||||
}
|
||||
"debug_logs": [
|
||||
$(printf '"%s",' "${debug_logs[@]}")
|
||||
]
|
||||
}
|
||||
EOT
|
||||
125
simpleadmin/www/cgi-bin/set_watchcat
Normal file
125
simpleadmin/www/cgi-bin/set_watchcat
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/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 [[ "$cmd" == *"="* ]]; then
|
||||
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||
eval $key=$(urldecode $value)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$status" ] || [ -z "$IpDNS" ] || [ -z "$cooldown" ] || [ -z "$failures" ] || [ -z "$action" ]; then
|
||||
response="Missing parameters. Please provide the following parameters: IpDNS, cooldown, failures, action."
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "$response"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$status" == "enabled" ]; then
|
||||
watch_script="/usrdata/simpleadmin/script/watchat.sh"
|
||||
mount -o remount,rw /
|
||||
|
||||
cat <<EOF > $watch_script
|
||||
#!/bin/bash
|
||||
|
||||
ip_or_dns="$IpDNS"
|
||||
cooldown=$cooldown
|
||||
action="$action"
|
||||
fail_count=0
|
||||
max_failures=$failures
|
||||
|
||||
# Process the action variable.
|
||||
|
||||
# Create a JSON file containing the parameters of the script
|
||||
echo -n '{"ip_or_dns":"$ip_or_dns","cooldown":$cooldown,"action":"$action","fail_count":$fail_count,"max_failures":$max_failures}' > /tmp/watchatParams.json
|
||||
|
||||
|
||||
while true; do
|
||||
if ping -c 1 -W 1 \$ip_or_dns > /dev/null; then
|
||||
fail_count=0
|
||||
echo "Success at \$(date)" >> /tmp/watchat.log
|
||||
# Convert /tmp/watchat.log to json format
|
||||
echo -n '{"log":[' > /tmp/watchat.json
|
||||
cat /tmp/watchat.log | sed 's/$/,/' | tr -d '\n' | sed 's/,$//' >> /tmp/watchat.json
|
||||
echo -n ']}' >> /tmp/watchat.json
|
||||
else
|
||||
((fail_count++))
|
||||
if [ \$fail_count -ge \$max_failures ]; then
|
||||
case "\$action" in
|
||||
reboot)
|
||||
echo "Rebooting system..."
|
||||
/sbin/reboot
|
||||
;;
|
||||
switch_sim)
|
||||
echo "Switching SIM..."
|
||||
echo -ne "AT+CNMI=2,1\r" > /dev/ttyOUT2
|
||||
sleep 1
|
||||
echo "Switching SIM at \$(date)" >> /tmp/watchat.log
|
||||
;;
|
||||
none)
|
||||
echo "No action taken."
|
||||
echo "No action taken at \$(date)" >> /tmp/watchat.log
|
||||
;;
|
||||
*)
|
||||
echo "Unknown action: \$action"
|
||||
;;
|
||||
esac
|
||||
# Reset fail count
|
||||
fail_count=0
|
||||
fi
|
||||
fi
|
||||
echo "Fail count: \$fail_count at \$(date)" >> /tmp/watchat.log
|
||||
# Convert /tmp/watchat.log to json format
|
||||
echo -n '{"log":[' > /tmp/watchat.json
|
||||
cat /tmp/watchat.log | sed 's/$/,/' | tr -d '\n' | sed 's/,$//' >> /tmp/watchat.json
|
||||
echo -n ']}' >> /tmp/watchat.json
|
||||
sleep \$cooldown
|
||||
done
|
||||
EOF
|
||||
|
||||
chmod +x $watch_script
|
||||
|
||||
cat <<EOF > /lib/systemd/system/watchcat.service
|
||||
[Unit]
|
||||
Description=Ping Watcher Service
|
||||
|
||||
[Service]
|
||||
ExecStart=$watch_script
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
ln -s /lib/systemd/system/watchcat.service /etc/systemd/system/multi-user.target.wants/watchcat.service
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl start watchcat.service
|
||||
|
||||
response="Script created at $watch_script and made executable. Service created and started."
|
||||
|
||||
elif [ "$status" == "disabled" ]; then
|
||||
watch_script="/usrdata/simpleadmin/script/watchat.sh"
|
||||
rm -f $watch_script
|
||||
|
||||
systemctl stop watchcat.service
|
||||
rm -f /lib/systemd/system/watchcat.service
|
||||
rm -f /etc/systemd/system/multi-user.target.wants/watchcat.service
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
response="Script removed at $watch_script. Service stopped and removed."
|
||||
else
|
||||
response="Invalid status. Please provide either enabled or disabled."
|
||||
fi
|
||||
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "$response"
|
||||
26
simpleadmin/www/cgi-bin/user_atcommand
Normal file
26
simpleadmin/www/cgi-bin/user_atcommand
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/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
|
||||
|
||||
x=$(urldecode "$atcmd")
|
||||
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
|
||||
if [ -n "${MYATCMD}" ]; then
|
||||
# Capture the response and remove ANSI color codes using awk
|
||||
runcmd=$(atcmd '$x' | awk '{ gsub(/\x1B\[[0-9;]*[mG]/, "") }1')
|
||||
fi
|
||||
|
||||
echo "Content-type: text/plain"
|
||||
echo $x
|
||||
echo ""
|
||||
echo "$runcmd"
|
||||
72
simpleadmin/www/cgi-bin/watchcat_maker
Normal file
72
simpleadmin/www/cgi-bin/watchcat_maker
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Decode URL-encoded strings
|
||||
function urldecode() {
|
||||
local data=${1//+/ }
|
||||
printf '%b' "${data//%/\\x}"
|
||||
}
|
||||
|
||||
# Parse QUERY_STRING
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [[ "$cmd" == *"="* ]]; then
|
||||
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||
eval $key=$(urldecode $value)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Set default values
|
||||
WATCHCAT_ENABLED=${WATCHCAT_ENABLED:-"disable"}
|
||||
TRACK_IP=${TRACK_IP:-"1.1.1.1"}
|
||||
PING_TIMEOUT=${PING_TIMEOUT:-30}
|
||||
PING_FAILURE_COUNT=${PING_FAILURE_COUNT:-3}
|
||||
|
||||
# Validate input
|
||||
if ! [[ "$WATCHCAT_ENABLED" =~ ^(enable|disable)$ ]]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Invalid value for WATCHCAT_ENABLED. Use 'enable' or 'disable'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$TRACK_IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Invalid IP address format for TRACK_IP."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$PING_TIMEOUT" =~ ^[0-9]+$ ]] || [ "$PING_TIMEOUT" -le 0 ]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "PING_TIMEOUT must be a positive integer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$PING_FAILURE_COUNT" =~ ^[0-9]+$ ]] || [ "$PING_FAILURE_COUNT" -le 0 ]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "PING_FAILURE_COUNT must be a positive integer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Implement the Watchcat logic
|
||||
if [ "$WATCHCAT_ENABLED" == "enable" ]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Watchcat is enabled. Tracking IP: $TRACK_IP, Ping timeout: $PING_TIMEOUT seconds, Ping failure count: $PING_FAILURE_COUNT"
|
||||
# Call the create script here and use the needed parameters
|
||||
sudo /usrdata/simpleadmin/script/create_watchcat.sh "$TRACK_IP" "$PING_TIMEOUT" "$PING_FAILURE_COUNT"
|
||||
else
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Watchcat is disabled."
|
||||
# Call the remove script here
|
||||
sudo /usrdata/simpleadmin/script/remove_watchcat.sh
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,86 +0,0 @@
|
||||
:root{
|
||||
::-webkit-scrollbar{height:10px;width:10px}::-webkit-scrollbar-track{background:#efefef;border-radius:6px}::-webkit-scrollbar-thumb{background:#d5d5d5;border-radius:6px}::-webkit-scrollbar-thumb:hover{background:#c4c4c4}
|
||||
}
|
||||
html, body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
height: 100%;
|
||||
background: #ECF0F3;
|
||||
}
|
||||
nav.navbar {
|
||||
border-top: 4px solid #276cda;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.navbar-item.brand-text {
|
||||
font-weight: 300;
|
||||
}
|
||||
.navbar-item, .navbar-link {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.columns {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
.menu-label {
|
||||
color: #8F99A3;
|
||||
letter-spacing: 1.3;
|
||||
font-weight: 700;
|
||||
}
|
||||
.menu-list a {
|
||||
color: #0F1D38;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.menu-list a:hover {
|
||||
background-color: transparent;
|
||||
color: #276cda;
|
||||
}
|
||||
.menu-list a.is-active {
|
||||
background-color: transparent;
|
||||
color: #276cda;
|
||||
font-weight: 700;
|
||||
}
|
||||
.card {
|
||||
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.18);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.card-header-title {
|
||||
color: #8F99A3;
|
||||
font-weight: 400;
|
||||
}
|
||||
.info-tiles {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.info-tiles .subtitle {
|
||||
font-weight: 300;
|
||||
color: #8F99A3;
|
||||
}
|
||||
.hero.welcome.is-info {
|
||||
background: #36D1DC;
|
||||
background: -webkit-linear-gradient(to right, #5B86E5, #36D1DC);
|
||||
background: linear-gradient(to right, #5B86E5, #36D1DC);
|
||||
}
|
||||
.hero.welcome .title, .hero.welcome .subtitle {
|
||||
color: hsl(192, 17%, 99%);
|
||||
}
|
||||
.card .content {
|
||||
font-size: 14px;
|
||||
}
|
||||
.card-footer-item {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #8F99A3;
|
||||
}
|
||||
.card-footer-item:hover {
|
||||
}
|
||||
.card-table .table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.events-card .card-table {
|
||||
height: 330px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
6143
simpleadmin/www/css/all.min.css
vendored
Normal file
6143
simpleadmin/www/css/all.min.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
simpleadmin/www/css/bootstrap.min.css
vendored
Normal file
6
simpleadmin/www/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
simpleadmin/www/css/bulma.css
vendored
1
simpleadmin/www/css/bulma.css
vendored
File diff suppressed because one or more lines are too long
173
simpleadmin/www/css/styles.css
Normal file
173
simpleadmin/www/css/styles.css
Normal file
@@ -0,0 +1,173 @@
|
||||
/* import poppins */
|
||||
/* poppins-300 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url('../fonts/poppins-v23-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-300italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: url('../fonts/poppins-v23-latin-300italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-regular - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('../fonts/poppins-v23-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: url('../fonts/poppins-v23-latin-italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-500 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('../fonts/poppins-v23-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-500italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
src: url('../fonts/poppins-v23-latin-500italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-600 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url('../fonts/poppins-v23-latin-600.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-600italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: url('../fonts/poppins-v23-latin-600italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-700 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url('../fonts/poppins-v23-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-700italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url('../fonts/poppins-v23-latin-700italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* import fontawesome icons */
|
||||
@import url("./all.min.css");
|
||||
|
||||
* {
|
||||
font-family: "Poppins", sans-serif;
|
||||
}
|
||||
|
||||
.custom-checkbox .form-check-input {
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.loading-modal {
|
||||
background-color: #fff;
|
||||
padding: 3rem;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.loader {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border: 3px dotted #000;
|
||||
border-style: solid solid dotted dotted;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
animation: rotation 2s linear infinite;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.loader::after {
|
||||
content: "";
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
border: 3px dotted #0b5ed7;
|
||||
border-style: solid solid dotted;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
animation: rotationBack 1s linear infinite;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationBack {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.is-warning {
|
||||
background-color: #ffb70f !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.is-medium {
|
||||
font-weight: 600;
|
||||
}
|
||||
522
simpleadmin/www/deviceinfo.html
Normal file
522
simpleadmin/www/deviceinfo.html
Normal file
@@ -0,0 +1,522 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- <link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
||||
crossorigin="anonymous"
|
||||
/> -->
|
||||
<!-- Import all the bootstrap css files from css folder -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="fetchDeviceInfo()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/settings.html">Simple Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/deviceinfo.html"
|
||||
aria-current="page"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="row mt-5 gap-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Device Information</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Manufacturer</th>
|
||||
<td x-text="manufacturer"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Model Name</th>
|
||||
<td x-text="modelName"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Firmware version</th>
|
||||
<td class="col-md-2" x-text="firmwareVersion"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Phone Number</th>
|
||||
<td class="col-md-2" x-text="phoneNumber"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">IMSI</th>
|
||||
<td class="col-md-2" x-text="imsi"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">ICCID</th>
|
||||
<td class="col-md-2" x-text="iccid"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">IMEI</th>
|
||||
<td class="col-md-2">
|
||||
<input
|
||||
class="form-control"
|
||||
type="text"
|
||||
x-model="newImei"
|
||||
x-bind:placeholder="imei === '-' ? 'Fetching IMEI...' : imei"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
@click="openModal()"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">LAN IP</th>
|
||||
<td class="col-md-2" x-text="lanIp"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">WWAN IPv<sup>4</sup></th>
|
||||
<td class="col-md-2" x-text="wwanIpv4"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">WWAN IPv<sup>6</sup></th>
|
||||
<td class="col-md-2" x-text="wwanIpv6"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Simple Admin Version</th>
|
||||
<td class="col-md-2">SimpleAdminRev-Alpha-0.9</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Project Contributors</th>
|
||||
<td>
|
||||
<!-- Button trigger modal -->
|
||||
<p
|
||||
type="button"
|
||||
class="link-info link-opacity-50-hover link-offset-2"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#staticBackdrop"
|
||||
>
|
||||
Show Contributors
|
||||
</p>
|
||||
|
||||
<!-- Modal -->
|
||||
<div
|
||||
class="modal fade"
|
||||
id="staticBackdrop"
|
||||
data-bs-backdrop="static"
|
||||
data-bs-keyboard="false"
|
||||
tabindex="-1"
|
||||
aria-labelledby="staticBackdropLabel"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1
|
||||
class="modal-title fs-5"
|
||||
id="staticBackdropLabel"
|
||||
>
|
||||
Contributors
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
RGMII Toolkit and Documentation
|
||||
</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/iamromulan"
|
||||
target="_blank"
|
||||
>iamromulan</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Simple Admin 2.0</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/dr-dolomite"
|
||||
target="_blank"
|
||||
>dr-dolomite</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>SMS Feature</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/snjzb"
|
||||
target="_blank"
|
||||
>snjzb</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Original Simple Admin</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/aesthernr"
|
||||
target="_blank"
|
||||
>aesthernr</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Original Socat Bridge</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/natecarlson"
|
||||
target="_blank"
|
||||
>natecarlson</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Original Simple Admin Fixes</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/rbflurry/"
|
||||
target="_blank"
|
||||
>rbflurry</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>SA Parsing Patch</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/tarunVreddy"
|
||||
target="_blank"
|
||||
>tarunVreddy</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
data-bs-dismiss="modal"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
Visit our
|
||||
<a
|
||||
href="https://github.com/iamromulan/quectel-rgmii-toolkit/tree/development"
|
||||
target="_blank"
|
||||
class="text-reset"
|
||||
>repository</a
|
||||
>
|
||||
or
|
||||
<a
|
||||
href="https://github.com/iamromulan/quectel-rgmii-configuration-notes.git"
|
||||
target="_blank"
|
||||
class="text-reset"
|
||||
>documentation</a
|
||||
>
|
||||
for more information. All rights reserved. 2025
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading Modal for Reboot -->
|
||||
<div class="modal-overlay" x-show="showModal">
|
||||
<div class="loading-modal">
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>This will reboot the modem.</h3>
|
||||
<p style="margin-top: 0.5rem">Continue?</p>
|
||||
</div>
|
||||
<div class="d-grid gap-2 d-md-block">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
@click="updateIMEI()"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
@click="closeModal()"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reboot Modal Countdown -->
|
||||
<div class="modal-overlay" x-show="isRebooting">
|
||||
<div class="loading-modal">
|
||||
<div class="loader"></div>
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>Rebooting...</h3>
|
||||
<p style="margin-top: 0.5rem">
|
||||
Please wait for
|
||||
<span x-text="countdown" style="font-weight: 500"></span>
|
||||
seconds.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function fetchDeviceInfo() {
|
||||
return {
|
||||
manufacturer: "-",
|
||||
modelName: "-",
|
||||
firmwareVersion: "-",
|
||||
imsi: "-",
|
||||
iccid: "-",
|
||||
imei: "-",
|
||||
newImei: null,
|
||||
lanIp: "-",
|
||||
wwanIpv4: "-",
|
||||
wwanIpv6: "-",
|
||||
phoneNumber: "Unknown",
|
||||
simpleAdminVersion: "-",
|
||||
atcmd: null,
|
||||
atCommandResponse: "",
|
||||
showModal: false,
|
||||
isLoading: false,
|
||||
isRebooting: false,
|
||||
countdown: 3,
|
||||
|
||||
sendATCommand() {
|
||||
if (!this.atcmd) {
|
||||
// Use ATI as default command
|
||||
console.log(
|
||||
"AT Command is empty, using ATI as default command: "
|
||||
);
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
});
|
||||
},
|
||||
|
||||
fetchATCommand() {
|
||||
this.atcmd =
|
||||
'AT+CGMI;+CGMM;+QGMR;+CIMI;+ICCID;+CGSN;+QMAP="LANIP";+QMAP="WWAN";+CNUM';
|
||||
this.isLoading = true;
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.parseFetchedData();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
});
|
||||
},
|
||||
|
||||
parseFetchedData() {
|
||||
const lines = this.atCommandResponse.split("\n");
|
||||
|
||||
console.log("AT Command Response: ", lines);
|
||||
|
||||
this.manufacturer = lines[1].trim();
|
||||
this.modelName = lines[3].trim();
|
||||
this.firmwareVersion = lines[5].trim();
|
||||
this.imei = lines[11].trim();
|
||||
this.lanIp = lines[13].trim().split(",")[3];
|
||||
this.wwanIpv4 = lines[15].trim().split(",")[4].replace(/"/g, "");
|
||||
this.wwanIpv6 = lines[16].trim().split(",")[4].replace(/"/g, "");
|
||||
|
||||
try {
|
||||
this.imsi = lines[7].trim();
|
||||
this.iccid = lines[9].trim().replace("+ICCID: ", "");
|
||||
this.phoneNumber = lines[18]
|
||||
.trim()
|
||||
.split(",")[1]
|
||||
.replace(/"/g, "");
|
||||
|
||||
if (this.phoneNumber === "") {
|
||||
this.phoneNumber = "Unknown";
|
||||
}
|
||||
} catch (error) {
|
||||
this.phoneNumber = "No SIM Card Inserted or Detected";
|
||||
this.imsi = " ";
|
||||
this.iccid = " ";
|
||||
}
|
||||
|
||||
this.simpleAdminVersion = "SimpleAdminRev-Beta-1.0";
|
||||
this.isLoading = false;
|
||||
},
|
||||
|
||||
updateIMEI() {
|
||||
this.atcmd = `AT+EGMR=1,7,"${this.newImei}"`;
|
||||
this.sendATCommand();
|
||||
this.rebootDevice();
|
||||
},
|
||||
|
||||
rebootDevice() {
|
||||
this.atcmd = "AT+CFUN=1,1";
|
||||
this.sendATCommand();
|
||||
|
||||
this.isLoading = true;
|
||||
this.showModal = false;
|
||||
this.isRebooting = true;
|
||||
this.countdown = 40;
|
||||
const interval = setInterval(() => {
|
||||
this.countdown--;
|
||||
if (this.countdown === 0) {
|
||||
clearInterval(interval);
|
||||
this.isLoading = false;
|
||||
this.showModal = false;
|
||||
this.isRebooting = false;
|
||||
this.init();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
openModal() {
|
||||
if (!this.newImei) {
|
||||
alert("No new IMEI provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.newImei.length !== 15) {
|
||||
alert("IMEI is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.newImei === this.imei) {
|
||||
alert("IMEI is the same as the current IMEI");
|
||||
return;
|
||||
}
|
||||
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
closeModal() {
|
||||
this.showModal = false;
|
||||
},
|
||||
|
||||
init() {
|
||||
this.fetchATCommand();
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
simpleadmin/www/favicon.ico
Normal file
BIN
simpleadmin/www/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
simpleadmin/www/fonts/poppins-v23-latin-300.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-300.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-300italic.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-300italic.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-500.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-500.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-500italic.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-500italic.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-600.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-600.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-600italic.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-600italic.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-700.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-700.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-700italic.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-700italic.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-italic.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-italic.woff2
Normal file
Binary file not shown.
BIN
simpleadmin/www/fonts/poppins-v23-latin-regular.woff2
Normal file
BIN
simpleadmin/www/fonts/poppins-v23-latin-regular.woff2
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
7
simpleadmin/www/js/bootstrap.bundle.min.js
vendored
Normal file
7
simpleadmin/www/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
37
simpleadmin/www/js/dark-mode.js
Normal file
37
simpleadmin/www/js/dark-mode.js
Normal file
@@ -0,0 +1,37 @@
|
||||
// Function to toggle dark mode
|
||||
const toggleDarkMode = () => {
|
||||
const html = document.querySelector('html');
|
||||
const currentTheme = html.getAttribute('data-bs-theme');
|
||||
|
||||
if (currentTheme === 'dark') {
|
||||
html.removeAttribute('data-bs-theme');
|
||||
darkModeToggle.textContent = 'Dark Mode';
|
||||
localStorage.setItem('theme', 'light'); // Store the theme in localStorage
|
||||
} else {
|
||||
html.setAttribute('data-bs-theme', 'dark');
|
||||
darkModeToggle.textContent = 'Light Mode';
|
||||
localStorage.setItem('theme', 'dark'); // Store the theme in localStorage
|
||||
}
|
||||
};
|
||||
|
||||
const darkModeToggle = document.getElementById('darkModeToggle');
|
||||
|
||||
// Check if theme preference is stored in localStorage
|
||||
const storedTheme = localStorage.getItem('theme');
|
||||
const html = document.querySelector('html');
|
||||
|
||||
if (storedTheme) {
|
||||
html.setAttribute('data-bs-theme', storedTheme);
|
||||
if (storedTheme === 'dark') {
|
||||
darkModeToggle.textContent = 'Light Mode';
|
||||
} else {
|
||||
darkModeToggle.textContent = 'Dark Mode';
|
||||
}
|
||||
} else {
|
||||
// If no preference is stored, default to dark mode
|
||||
html.setAttribute('data-bs-theme', 'dark');
|
||||
darkModeToggle.textContent = 'Light Mode';
|
||||
localStorage.setItem('theme', 'dark');
|
||||
}
|
||||
|
||||
darkModeToggle.addEventListener('click', toggleDarkMode);
|
||||
37
simpleadmin/www/js/generate-freq-box.js
Normal file
37
simpleadmin/www/js/generate-freq-box.js
Normal file
@@ -0,0 +1,37 @@
|
||||
const freqNumbersContainer = document.getElementById(
|
||||
"freqNumbersContainer"
|
||||
);
|
||||
|
||||
function generateFreqNumberInputs(num) {
|
||||
let html = "";
|
||||
const maxFields = Math.min(num, 10); // Limit to a maximum of 10 fields
|
||||
for (let i = 1; i <= maxFields; i++) {
|
||||
html += `
|
||||
<div class="input-group mb-3" x-show="cellNum >= ${i} && networkModeCell == 'LTE'">
|
||||
<input
|
||||
type="text"
|
||||
aria-label="EARFCN"
|
||||
placeholder="EARFCN"
|
||||
class="form-control"
|
||||
x-model="earfcn${i}"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label="PCI"
|
||||
placeholder="PCI"
|
||||
class="form-control"
|
||||
x-model="pci${i}"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const cellNumInput = document.querySelector("[aria-label='NumCells']");
|
||||
cellNumInput.addEventListener("input", function () {
|
||||
const cellNum = parseInt(this.value);
|
||||
freqNumbersContainer.innerHTML = generateFreqNumberInputs(cellNum);
|
||||
});
|
||||
});
|
||||
99
simpleadmin/www/js/parse-settings.js
Normal file
99
simpleadmin/www/js/parse-settings.js
Normal file
@@ -0,0 +1,99 @@
|
||||
function parseCurrentSettings(rawdata) {
|
||||
const data = rawdata;
|
||||
|
||||
const lines = data.split("\n");
|
||||
console.log(lines);
|
||||
|
||||
// Remove QUIMSLOT and only take 1 or 2
|
||||
this.sim = lines
|
||||
.find(
|
||||
(line) => line.includes("QUIMSLOT: 1") || line.includes("QUIMSLOT: 2")
|
||||
)
|
||||
.split(":")[1]
|
||||
// remove spaces
|
||||
.replace(/\s/g, "");
|
||||
// .replace(/\"/g, "");
|
||||
|
||||
try {
|
||||
this.apn = lines
|
||||
.find((line) => line.includes("+CGCONTRDP: 1"))
|
||||
.split(",")[2]
|
||||
.replace(/\"/g, "");
|
||||
} catch (error) {
|
||||
this.apn = "Failed fetching APN";
|
||||
}
|
||||
|
||||
this.cellLock4GStatus = lines
|
||||
.find((line) => line.includes('+QNWLOCK: "common/4g"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.cellLock5GStatus = lines
|
||||
.find((line) => line.includes('+QNWLOCK: "common/5g"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.prefNetwork = lines
|
||||
.find((line) => line.includes('+QNWPREFCFG: "mode_pref"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.nrModeControlStatus = lines
|
||||
.find((line) => line.includes('+QNWPREFCFG: "nr5g_disable_mode"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.apnIP = lines
|
||||
.find((line) => line.includes("+CGDCONT: 1"))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
try {
|
||||
const PCCbands = lines
|
||||
.find((line) => line.includes('+QCAINFO: "PCC"'))
|
||||
.split(",")[3]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
// Loop over all QCAINFO: "SCC" lines and get the bands
|
||||
try {
|
||||
const SCCbands = lines
|
||||
.filter((line) => line.includes('+QCAINFO: "SCC"'))
|
||||
.map((line) => line.split(",")[3].replace(/\"/g, ""))
|
||||
.join(", ");
|
||||
this.bands = `${PCCbands}, ${SCCbands}`;
|
||||
} catch (error) {
|
||||
this.bands = PCCbands;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.bands = "Failed fetching bands";
|
||||
}
|
||||
|
||||
if (this.cellLock4GStatus == 1 && this.cellLock5GStatus == 1) {
|
||||
this.cellLockStatus = "Locked to 4G and 5G";
|
||||
} else if (this.cellLock4GStatus == 1) {
|
||||
this.cellLockStatus = "Locked to 4G";
|
||||
} else if (this.cellLock5GStatus == 1) {
|
||||
this.cellLockStatus = "Locked to 5G";
|
||||
} else {
|
||||
this.cellLockStatus = "Not Locked";
|
||||
}
|
||||
|
||||
if (this.nrModeControlStatus == 0) {
|
||||
this.nrModeControlStatus = "Not Disabled";
|
||||
} else if (this.nrModeControlStatus == 1) {
|
||||
this.nrModeControlStatus = "SA Disabled";
|
||||
} else {
|
||||
this.nrModeControlStatus = "NSA Disabled";
|
||||
}
|
||||
|
||||
return {
|
||||
sim: sim,
|
||||
apn: apn,
|
||||
apnIP: apnIP,
|
||||
cellLockStatus: cellLockStatus,
|
||||
prefNetwork: prefNetwork,
|
||||
nrModeControl: nrModeControlStatus,
|
||||
bands: bands,
|
||||
};
|
||||
}
|
||||
81
simpleadmin/www/js/populate-checkbox.js
Normal file
81
simpleadmin/www/js/populate-checkbox.js
Normal file
@@ -0,0 +1,81 @@
|
||||
function populateCheckboxes(lte_band, nsa_nr5g_band, nr5g_band, locked_lte_bands, locked_nsa_bands, locked_sa_bands, cellLock) {
|
||||
var checkboxesForm = document.getElementById("checkboxForm");
|
||||
var selectedMode = document.getElementById("networkModeBand").value;
|
||||
var bands;
|
||||
var prefix;
|
||||
|
||||
// Determine bands and prefix based on selected network mode
|
||||
if (selectedMode === "LTE") {
|
||||
bands = lte_band;
|
||||
prefix = "B";
|
||||
} else if (selectedMode === "NSA") {
|
||||
bands = nsa_nr5g_band;
|
||||
prefix = "N";
|
||||
} else if (selectedMode === "SA") {
|
||||
bands = nr5g_band;
|
||||
prefix = "N";
|
||||
}
|
||||
|
||||
checkboxesForm.innerHTML = ""; // Clear existing checkboxes
|
||||
|
||||
// Store the locked bands in arrays
|
||||
var locked_lte_bands_array = locked_lte_bands.split(":");
|
||||
var locked_nsa_bands_array = locked_nsa_bands.split(":");
|
||||
var locked_sa_bands_array = locked_sa_bands.split(":");
|
||||
|
||||
var isBandLocked = function(band) {
|
||||
if (selectedMode === "LTE" && locked_lte_bands_array.includes(band)) {
|
||||
return true;
|
||||
}
|
||||
if (selectedMode === "NSA" && locked_nsa_bands_array.includes(band)) {
|
||||
return true;
|
||||
}
|
||||
if (selectedMode === "SA" && locked_sa_bands_array.includes(band)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
|
||||
if (bands !== null && bands !== "0") {
|
||||
var bandsArray = bands.split(":");
|
||||
var currentRow;
|
||||
|
||||
bandsArray.forEach(function(band, index) {
|
||||
if (index % 5 === 0) {
|
||||
currentRow = document.createElement("div");
|
||||
currentRow.className = "row mb-2 mx-auto"; // Add margin bottom for spacing
|
||||
fragment.appendChild(currentRow);
|
||||
}
|
||||
|
||||
var checkboxDiv = document.createElement("div");
|
||||
checkboxDiv.className = "form-check form-check-reverse col-2"; // Each checkbox takes a column
|
||||
var checkboxInput = document.createElement("input");
|
||||
checkboxInput.className = "form-check-input";
|
||||
checkboxInput.type = "checkbox";
|
||||
checkboxInput.id = "inlineCheckbox" + band;
|
||||
checkboxInput.value = band;
|
||||
checkboxInput.autocomplete = "off";
|
||||
checkboxInput.checked = isBandLocked(band);
|
||||
|
||||
var checkboxLabel = document.createElement("label");
|
||||
checkboxLabel.className = "form-check-label";
|
||||
checkboxLabel.htmlFor = "inlineCheckbox" + band;
|
||||
checkboxLabel.innerText = prefix + band;
|
||||
|
||||
checkboxDiv.appendChild(checkboxInput);
|
||||
checkboxDiv.appendChild(checkboxLabel);
|
||||
currentRow.appendChild(checkboxDiv);
|
||||
});
|
||||
} else {
|
||||
// Create a text saying that no bands are available
|
||||
var noBandsText = document.createElement("p");
|
||||
noBandsText.className = "text-center";
|
||||
noBandsText.innerText = "No supported bands available";
|
||||
fragment.appendChild(noBandsText);
|
||||
}
|
||||
|
||||
checkboxesForm.appendChild(fragment);
|
||||
addCheckboxListeners(cellLock);
|
||||
}
|
||||
1000
simpleadmin/www/network.html
Normal file
1000
simpleadmin/www/network.html
Normal file
File diff suppressed because it is too large
Load Diff
2393
simpleadmin/www/scanner.html
Normal file
2393
simpleadmin/www/scanner.html
Normal file
File diff suppressed because it is too large
Load Diff
667
simpleadmin/www/settings.html
Normal file
667
simpleadmin/www/settings.html
Normal file
@@ -0,0 +1,667 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Logo -->
|
||||
<link rel="simpleadmin-logo" href="favicon.ico" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="simpleSettings()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/settings.html"
|
||||
aria-current="page"
|
||||
>Simple Settings</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="row mt-5 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">AT Terminal</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="form-floating mb-4">
|
||||
<!-- At commands output here -->
|
||||
<textarea
|
||||
class="form-control"
|
||||
placeholder="ATI"
|
||||
id="atOutputBox"
|
||||
style="height: 210px"
|
||||
x-text="atCommandResponse"
|
||||
readonly
|
||||
>
|
||||
<label for="floatingTextarea">ATI</label>
|
||||
</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="exampleInputEmail1" class="form-label"
|
||||
>AT Command</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="atCommandInput"
|
||||
placeholder="ATI"
|
||||
aria-describedby="atCommandInput"
|
||||
x-model="atcmd"
|
||||
@keydown.enter="sendATCommand()"
|
||||
/>
|
||||
<div id="atCommandInputHelper" class="form-text">
|
||||
Seperate multiple commands with comma (,).
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-grid gap-2 d-md-flex justify-content-md-start"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary me-md-2"
|
||||
type="button"
|
||||
@click="sendATCommand()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
@click="clearResponses()"
|
||||
:disabled="isClean"
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">One Click Utilities</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Reboot</th>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="showRebootModal()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Reset AT Commands Settings</th>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="resetATCommands()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">IP Passthrough</th>
|
||||
<td>
|
||||
<select
|
||||
class="form-select"
|
||||
id="ipPassModeSelect"
|
||||
x-model="ipPassMode"
|
||||
>
|
||||
<option selected>Passthrough Mode</option>
|
||||
<option value="ETH">ETH</option>
|
||||
<option value="USB">USB (ECM/RNDIS)</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
@click="ipPassThroughEnable()"
|
||||
x-show="ipPassStatus === false"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Enable
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="ipPassThroughDisable()"
|
||||
x-show="ipPassStatus === true"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Disable
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">USB Modem Protocol</th>
|
||||
<td>
|
||||
<select
|
||||
class="form-select"
|
||||
id="usbNetModeSelect"
|
||||
x-model="usbNetMode"
|
||||
>
|
||||
<option
|
||||
selected
|
||||
x-text="currentUsbNetMode"
|
||||
></option>
|
||||
<option value="RMNET">RMNET</option>
|
||||
<option value="ECM">ECM (Recommended)</option>
|
||||
<option value="MBIM">MBIM</option>
|
||||
<option value="RNDIS">RNDIS</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
@click="usbNetModeChanger()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Change
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Onboard DNS Proxy</th>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
@click="onBoardDNSProxyEnable()"
|
||||
x-show="DNSProxyStatus === false"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Enable
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="onBoardDNSProxyDisable()"
|
||||
x-show="DNSProxyStatus === true"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Disable
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">TTL and Network Scan Settings</div>
|
||||
<div class="card-body">
|
||||
<label for="TTLState" class="form-label"
|
||||
>TTL State and Value</label
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div
|
||||
class="p-3 text-primary-emphasis bg-primary-subtle border border-primary-subtle rounded-3"
|
||||
x-show="ttlStatus === true"
|
||||
>
|
||||
TTL is Active
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="p-3 text-danger-emphasis bg-danger-subtle border border-danger-subtle rounded-3"
|
||||
x-show="ttlStatus === false"
|
||||
>
|
||||
TTL is Inactive
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div
|
||||
class="p-3 text-info-emphasis bg-info-subtle border border-info-subtle rounded-3 mb-4"
|
||||
x-text="ttlvalue"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-text mb-3">
|
||||
<div class="mb-4">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ttlInput"
|
||||
placeholder="TTL Value"
|
||||
x-model="newTTL"
|
||||
/>
|
||||
<div id="ttlValueHelper" class="form-text">
|
||||
Set TTL Value to 0 to disable.
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-grid gap-1">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
@click="setTTL()"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="card-text">
|
||||
<div class="d-flex flex-row gap-4 w-full">
|
||||
<p><a class="link-info link-opacity-50-hover link-offset-2" href="/scanner.html">Go to Cell Scanner</a></p>
|
||||
<p><a class="link-info link-opacity-50-hover link-offset-2" href="/watchcat.html">Go to WatchCat</a></p>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading Modal for Reboot -->
|
||||
<div class="modal-overlay" x-show="showModal">
|
||||
<div class="loading-modal">
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>This will reboot the modem.</h3>
|
||||
<p style="margin-top: 0.5rem">Continue?</p>
|
||||
</div>
|
||||
<div class="d-grid gap-2 d-md-block">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
@click="rebootDevice()"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
@click="closeModal()"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reboot Modal Countdown -->
|
||||
<div class="modal-overlay" x-show="isRebooting">
|
||||
<div class="loading-modal">
|
||||
<div class="loader"></div>
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>Rebooting...</h3>
|
||||
<p style="margin-top: 0.5rem">
|
||||
Please wait for
|
||||
<span x-text="countdown" style="font-weight: 500"></span>
|
||||
seconds.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function simpleSettings() {
|
||||
return {
|
||||
isLoading: false,
|
||||
showSuccess: false,
|
||||
showError: false,
|
||||
isClean: true,
|
||||
showModal: false,
|
||||
isRebooting: false,
|
||||
atcmd: "",
|
||||
fetchATCommand: "",
|
||||
countdown: 0,
|
||||
atCommandResponse: "",
|
||||
currentSettingsResponse: "",
|
||||
ttldata: null,
|
||||
ttlvalue: 0,
|
||||
ttlStatus: false,
|
||||
newTTL: null,
|
||||
ipPassMode: "Unspecified",
|
||||
ipPassStatus: false,
|
||||
usbNetMode: "Unspecified",
|
||||
currentUsbNetMode: "Unknown",
|
||||
DNSProxyStatus: true,
|
||||
|
||||
closeModal() {
|
||||
this.confirmModal = false;
|
||||
this.showModal = false;
|
||||
},
|
||||
|
||||
showRebootModal() {
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
sendATCommand() {
|
||||
if (!this.atcmd) {
|
||||
// Use ATI as default command
|
||||
this.atcmd = "ATI";
|
||||
console.log(
|
||||
"AT Command is empty, using ATI as default command: ",
|
||||
this.atcmd
|
||||
);
|
||||
}
|
||||
this.isLoading = true;
|
||||
const encodedATCmd = encodeURIComponent(this.atcmd);
|
||||
const url = `/cgi-bin/get_atcommand?atcmd=${encodedATCmd}`;
|
||||
|
||||
fetch(url)
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.isLoading = false;
|
||||
this.isClean = false;
|
||||
this.fetchCurrentSettings();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
sendUserATCommand() {
|
||||
this.isLoading = true;
|
||||
const encodedATCmd = encodeURIComponent(this.atcmd);
|
||||
const url = `/cgi-bin/user_atcommand?atcmd=${encodedATCmd}`;
|
||||
|
||||
fetch(url)
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.isLoading = false;
|
||||
this.isClean = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
clearResponses() {
|
||||
this.atCommandResponse = "";
|
||||
this.isClean = true;
|
||||
},
|
||||
|
||||
rebootDevice() {
|
||||
this.atcmd = "AT+CFUN=1,1";
|
||||
this.sendATCommand();
|
||||
|
||||
this.atCommandResponse = "";
|
||||
this.showModal = false;
|
||||
this.isRebooting = true;
|
||||
this.countdown = 40;
|
||||
|
||||
// Do the countdown
|
||||
const interval = setInterval(() => {
|
||||
this.countdown--;
|
||||
if (this.countdown === 0) {
|
||||
clearInterval(interval);
|
||||
this.isRebooting = false;
|
||||
this.init();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
resetATCommands() {
|
||||
this.atcmd = "AT&F";
|
||||
this.sendATCommand();
|
||||
console.log("Resetting AT Commands");
|
||||
this.atcmd = "";
|
||||
this.atCommandResponse = "";
|
||||
this.showRebootModal();
|
||||
},
|
||||
|
||||
ipPassThroughEnable() {
|
||||
if (this.ipPassMode != "Unspecified") {
|
||||
if (this.ipPassMode == "ETH") {
|
||||
this.atcmd =
|
||||
// at+qmap="mpdn_rule",0,1,1,1,1,"FF:FF:FF:FF:FF:FF"
|
||||
'AT+QMAP="MPDN_RULE",0,1,0,1,1,"FF:FF:FF:FF:FF:FF"';
|
||||
this.sendATCommand();
|
||||
} else if (this.ipPassMode == "USB") {
|
||||
this.atcmd =
|
||||
'AT+QMAP="MPDN_RULE",0,1,0,3,1,"FF:FF:FF:FF:FF:FF"';
|
||||
this.sendATCommand();
|
||||
} else {
|
||||
console.error("Invalid IP Passthrough Mode");
|
||||
}
|
||||
} else {
|
||||
console.error("IP Passthrough Mode not specified");
|
||||
}
|
||||
},
|
||||
|
||||
ipPassThroughDisable() {
|
||||
this.atcmd = 'AT+QMAP="MPDN_RULE",0;+QMAPWAC=1';
|
||||
this.sendATCommand();
|
||||
},
|
||||
|
||||
onBoardDNSProxyEnable() {
|
||||
this.atcmd = 'AT+QMAP="DHCPV4DNS","enable"';
|
||||
this.sendATCommand().then(() => {
|
||||
this.fetchCurrentSettings();
|
||||
});
|
||||
},
|
||||
|
||||
onBoardDNSProxyDisable() {
|
||||
this.atcmd = 'AT+QMAP="DHCPV4DNS","disable"';
|
||||
this.sendATCommand().then(() => {
|
||||
this.fetchCurrentSettings();
|
||||
});
|
||||
},
|
||||
|
||||
usbNetModeChanger() {
|
||||
if (this.usbNetMode != "Unspecified") {
|
||||
if (this.usbNetMode == "RMNET") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",0;';
|
||||
this.sendATCommand();
|
||||
} else if (this.usbNetMode == "ECM") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",1;';
|
||||
this.sendATCommand();
|
||||
} else if (this.usbNetMode == "MBIM") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",2;';
|
||||
this.sendATCommand();
|
||||
} else if (this.usbNetMode == "RNDIS") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",3;';
|
||||
this.sendATCommand();
|
||||
} else {
|
||||
console.log("USB Net Mode Invalid");
|
||||
}
|
||||
} else {
|
||||
console.error("USB Net Mode not specified");
|
||||
}
|
||||
this.rebootDevice();
|
||||
},
|
||||
|
||||
fetchCurrentSettings() {
|
||||
this.fetchATCommand =
|
||||
'AT+QMAP="MPDN_RULE";+QMAP="DHCPV4DNS";+QCFG="usbnet"';
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.fetchATCommand,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
// Set the value of currentSettingsResponse
|
||||
this.currentSettingsResponse = data;
|
||||
const currentData = data.split("\n");
|
||||
console.log("Lines: ", currentData);
|
||||
|
||||
const testEthpass = currentData[1].match(
|
||||
/\+QMAP: "MPDN_rule",0,0,0,0,0/
|
||||
);
|
||||
|
||||
if (testEthpass) {
|
||||
this.ipPassStatus = false;
|
||||
} else {
|
||||
this.ipPassStatus = true;
|
||||
}
|
||||
|
||||
const testDNSProxy = currentData[6].match(
|
||||
/\+QMAP: "DHCPV4DNS","enable"/
|
||||
);
|
||||
|
||||
if (testDNSProxy) {
|
||||
this.DNSProxyStatus = true;
|
||||
} else {
|
||||
this.DNSProxyStatus = false;
|
||||
}
|
||||
|
||||
const testUSBNet = currentData[8].match(
|
||||
/\+QCFG: "usbnet",(\d)/
|
||||
);
|
||||
|
||||
if (testUSBNet[1] == "0") {
|
||||
this.currentUsbNetMode = "RMNET";
|
||||
} else if (testUSBNet[1] == "1") {
|
||||
this.currentUsbNetMode = "ECM";
|
||||
} else if (testUSBNet[1] == "2") {
|
||||
this.currentUsbNetMode = "MBIM";
|
||||
} else if (testUSBNet[1] == "3") {
|
||||
this.currentUsbNetMode = "RNDIS";
|
||||
} else {
|
||||
this.currentUsbNetMode = "Unknown";
|
||||
}
|
||||
|
||||
// clear atcmd
|
||||
this.atcmd = "";
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
});
|
||||
},
|
||||
|
||||
fetchTTL() {
|
||||
fetch("/cgi-bin/get_ttl_status")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.ttldata = data;
|
||||
this.ttlStatus = this.ttldata.isEnabled;
|
||||
this.ttlvalue = this.ttldata.ttl;
|
||||
});
|
||||
},
|
||||
|
||||
setTTL() {
|
||||
this.isLoading = true; // Set loading state while updating TTL
|
||||
const ttlval = this.newTTL;
|
||||
fetch(
|
||||
"/cgi-bin/set_ttl?" + new URLSearchParams({ ttlvalue: ttlval })
|
||||
)
|
||||
.then((res) => res.text()) // Use res.text() instead of res.json()
|
||||
.then((data) => {
|
||||
// Manually handle the response data
|
||||
console.log("Response from server:", data);
|
||||
// You can try to parse the JSON manually or handle the response as needed
|
||||
|
||||
// Once TTL is updated, fetch the updated TTL data
|
||||
this.fetchTTL();
|
||||
this.isLoading = false; // Set loading state back to false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error updating TTL: ", error);
|
||||
this.isLoading = false; // Ensure loading state is properly handled in case of error
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.fetchCurrentSettings();
|
||||
this.fetchTTL();
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
421
simpleadmin/www/sms.html
Normal file
421
simpleadmin/www/sms.html
Normal file
@@ -0,0 +1,421 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- 导入自定义和Bootstrap样式 -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
<!-- 网站图标 -->
|
||||
<link rel="icon" href="favicon.ico" />
|
||||
<!-- 导入Bootstrap和Alpine.js脚本 -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
|
||||
<!-- Contributed By: snjzb -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="fetchSMS()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"><span class="mb-0 h4">Simple Admin</span></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarText"
|
||||
aria-controls="navbarText" aria-expanded="false" aria-label="切换导航">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 ml-4 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/settings.html">Simple Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html">Device Information</a>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="row mt-5 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">SMS Inbox</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="col">
|
||||
<div style="
|
||||
max-height: 400px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
">
|
||||
<div x-show="isLoading">
|
||||
<h4>Fetching SMS...</h4>
|
||||
</div>
|
||||
<table class="table table-hover border-success" x-show="!isLoading">
|
||||
<tbody>
|
||||
<!-- 没有消息时显示 -->
|
||||
<!-- Display when there are no messages -->
|
||||
<template x-if="messages.length === 0 && !isLoading">
|
||||
<div>
|
||||
<p>Inbox is Empty</p>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 循环显示短信消息 -->
|
||||
<!-- "Loop display SMS messages" -->
|
||||
<template x-for="(message, index) in messages" :key="index">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" :value="index"
|
||||
x-model="selectedMessages" />
|
||||
<div class="row column-gap-1 mb-2">
|
||||
<div class="col-md-3">
|
||||
<p x-text="'Sender: ' + senders[index]"></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<p x-text="'Date and Time: ' + dates[index]"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<p x-text="message.text"></p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 添加判断,只有当messages数组有内容时才显示全选复选框及其区域 -->
|
||||
<!-- Add a judgment, only when the messages array has content will the select all checkbox and its area be displayed" -->
|
||||
<div class="card-body border-top" x-show="messages.length > 0">
|
||||
<div class="form-check">
|
||||
<input id="selectAllCheckbox" class="form-check-input" type="checkbox" @change="toggleAll($event)" />
|
||||
<label class="form-check-label">Select All</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
|
||||
<!-- 刷新按钮 -->
|
||||
<!-- Refresh button -->
|
||||
<button class="btn btn-success" type="button" @click="init()">
|
||||
Refresh
|
||||
</button>
|
||||
<!-- 删除选中短信按钮 -->
|
||||
<!-- Delete selected SMS button -->
|
||||
<button class="btn btn-danger" type="button" @click="deleteSelectedSMS()">
|
||||
Delete Selected SMS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-5 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Send Message</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label for="phoneNumber" class="form-label">Recipient's Number</label>
|
||||
<input type="text" class="form-control" id="phoneNumber" x-model="phoneNumber"
|
||||
placeholder="Enter the recipient's number." />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="messageToSend" class="form-label">SMS Content</label>
|
||||
<textarea class="form-control" id="messageToSend" rows="3" x-model="messageToSend"
|
||||
placeholder="Enter SMS content."></textarea>
|
||||
</div>
|
||||
<div id="notification" class="alert" style="display: none;"></div>
|
||||
<button class="btn btn-primary" @click="sendSMS()">
|
||||
Send SMS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function fetchSMS() {
|
||||
return {
|
||||
isLoading: false,
|
||||
atCommandResponse: "",
|
||||
messages: [],
|
||||
senders: [],
|
||||
dates: [],
|
||||
selectedMessages: [],
|
||||
phoneNumber: '',
|
||||
messageToSend: '',
|
||||
messageIndices: [], // 确保初始化messageIndices数组
|
||||
|
||||
// 清除现有数据
|
||||
clearData() {
|
||||
this.messages = [];
|
||||
this.senders = [];
|
||||
this.dates = [];
|
||||
this.selectedMessages = [];
|
||||
this.messageIndices = [];
|
||||
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
|
||||
if (selectAllCheckbox) {
|
||||
selectAllCheckbox.checked = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 请求获取短信
|
||||
requestSMS() {
|
||||
this.isLoading = true;
|
||||
fetch(`/cgi-bin/get_atcommand?${new URLSearchParams({ atcmd: "AT+CSMS=1;+CSDH=0;+CNMI=2,1,0,0,0;+CMGF=1;+CSCA?;+CSMP=17,167,0,8;+CPMS=\"ME\",\"ME\",\"ME\";+CSCS=\"UCS2\";+CMGL=\"ALL\"" })}`)
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
this.atCommandResponse = data.split('\n')
|
||||
.filter(line => line.trim() !== "OK" && line.trim() !== "")
|
||||
.join('\n');
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
this.clearData();
|
||||
this.parseSMSData(this.atCommandResponse);
|
||||
});
|
||||
},
|
||||
|
||||
// 解析短信数据的方法
|
||||
parseSMSData(data) {
|
||||
const cmglRegex = /^\s*\+CMGL:\s*(\d+),"[^"]*","([^"]*)"[^"]*,"([^"]*)"/gm;
|
||||
const cscaRegex = /^\s*\+CSCA:\s*"([^"]*)"/gm;
|
||||
this.messageIndices = [];
|
||||
this.serviceCenters = [];
|
||||
this.dates = [];
|
||||
this.senders = [];
|
||||
this.messages = [];
|
||||
let match;
|
||||
let lastIndex = null;
|
||||
while ((match = cmglRegex.exec(data)) !== null) {
|
||||
const index = parseInt(match[1]);
|
||||
const senderHex = match[2];
|
||||
// Maximum world wide phone number length is 17 (North Korea), UTF-16BE Hex string comes back at 48+ for US Number, min length is 3.
|
||||
// When 3 digit SMS short code is used the result is a 12 length string (which we then need to check if the sender hex starts with 003 or 002B(+))
|
||||
// This check is probably completley unecessary but I have no data on how the modems behave with different firmware(whether support for CSCS="UCS2" is available).
|
||||
const sender = senderHex.length > 11 && (senderHex.startsWith('002B') || senderHex.startsWith('003')) ? this.convertHexToText(senderHex) : senderHex;
|
||||
const dateStr = match[3].replace(/\+\d{2}$/, "");
|
||||
const date = this.parseCustomDate(dateStr);
|
||||
if (isNaN(date)) {
|
||||
console.error(`Invalid Date: ${dateStr}`);
|
||||
continue;
|
||||
}
|
||||
const startIndex = cmglRegex.lastIndex;
|
||||
const endIndex = data.indexOf("+CMGL:", startIndex) !== -1 ? data.indexOf("+CMGL:", startIndex) : data.length;
|
||||
const messageHex = data.substring(startIndex, endIndex).trim();
|
||||
const message = /^[0-9a-fA-F]+$/.test(messageHex) ? this.convertHexToText(messageHex) : messageHex;
|
||||
if (lastIndex !== null && this.messages[lastIndex].sender === sender && (date - this.messages[lastIndex].date) / 1000 <= 1) {
|
||||
this.messages[lastIndex].text += " " + message;
|
||||
this.messages[lastIndex].indices.push(index);
|
||||
this.dates[lastIndex] = this.formatDate(date);
|
||||
} else {
|
||||
this.messageIndices.push([index]);
|
||||
this.senders.push(sender);
|
||||
this.dates.push(this.formatDate(date));
|
||||
this.messages.push({ text: message, sender: sender, date: date, indices: [index] });
|
||||
lastIndex = this.messages.length - 1;
|
||||
}
|
||||
}
|
||||
while ((match = cscaRegex.exec(data)) !== null) {
|
||||
const serviceCenterHex = match[1];
|
||||
const serviceCenter = this.convertHexToText(serviceCenterHex);
|
||||
this.serviceCenters.push(serviceCenter);
|
||||
}
|
||||
},
|
||||
|
||||
// 将十六进制转换为文本(假设使用 UTF-16BE 编码)
|
||||
convertHexToText(hex) {
|
||||
const bytes = new Uint8Array(hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
|
||||
return new TextDecoder('utf-16be').decode(bytes);
|
||||
},
|
||||
|
||||
// 自定义解析日期函数
|
||||
parseCustomDate(dateStr) {
|
||||
const [datePart, timePart] = dateStr.split(',');
|
||||
const [day, month, year] = datePart.split('/').map(part => parseInt(part, 10));
|
||||
const [hour, minute, second] = timePart.split(':').map(part => parseInt(part, 10));
|
||||
|
||||
// 将日期转换为标准格式的日期对象
|
||||
return new Date(Date.UTC(2000 + year, month - 1, day, hour, minute, second));
|
||||
},
|
||||
|
||||
// 自定义格式化日期函数
|
||||
formatDate(date) {
|
||||
const year = date.getUTCFullYear() - 2000;
|
||||
const month = (date.getUTCMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getUTCDate().toString().padStart(2, '0');
|
||||
const hour = date.getUTCHours().toString().padStart(2, '0');
|
||||
const minute = date.getUTCMinutes().toString().padStart(2, '0');
|
||||
const second = date.getUTCSeconds().toString().padStart(2, '0');
|
||||
return `${day}/${month}/${year},${hour}:${minute}:${second}`;
|
||||
},
|
||||
|
||||
// 删除选中的短信
|
||||
deleteSelectedSMS() {
|
||||
if (this.selectedMessages.length === 0) {
|
||||
console.warn("没有选中的短信");
|
||||
return;
|
||||
}
|
||||
if (!this.messageIndices || this.messageIndices.length === 0) {
|
||||
console.error("短信索引未正确初始化或为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否全选
|
||||
const isAllSelected = this.selectedMessages.length === this.messages.length;
|
||||
|
||||
if (isAllSelected) {
|
||||
// 如果全选,则调用删除所有短信的方法
|
||||
this.deleteAllSMS();
|
||||
} else {
|
||||
// 否则,删除选中的短信
|
||||
const indicesToDelete = [];
|
||||
this.selectedMessages.forEach(index => {
|
||||
indicesToDelete.push(...this.messages[index].indices);
|
||||
});
|
||||
if (indicesToDelete.length === 0) {
|
||||
console.warn("没有有效的短信索引");
|
||||
return;
|
||||
}
|
||||
|
||||
// 拼接 AT 命令
|
||||
const atCommands = indicesToDelete.map((index, i) => i === 0 ? `AT+CMGD=${index}` : `+CMGD=${index}`).join(';');
|
||||
fetch(`/cgi-bin/get_atcommand?${new URLSearchParams({ atcmd: atCommands })}`)
|
||||
.finally(() => {
|
||||
this.selectedMessages = [];
|
||||
this.requestSMS();
|
||||
});
|
||||
}
|
||||
},
|
||||
// 删除所有短信
|
||||
deleteAllSMS() {
|
||||
fetch(`/cgi-bin/get_atcommand?${new URLSearchParams({ atcmd: "AT+CMGD=,4" })}`)
|
||||
.finally(() => {
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
// 发送短信
|
||||
encodeUCS2(input) {
|
||||
let output = '';
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const hex = input.charCodeAt(i).toString(16).toUpperCase().padStart(4, '0');
|
||||
output += hex;
|
||||
}
|
||||
return output;
|
||||
},
|
||||
|
||||
async sendSMS() {
|
||||
let phoneNumberWithCountryCode;
|
||||
if (this.phoneNumber.length < 11) {
|
||||
phoneNumberWithCountryCode = this.phoneNumber;
|
||||
} else {
|
||||
const serviceCenterPrefix = this.serviceCenters[0].substring(0, 3);
|
||||
phoneNumberWithCountryCode = `${serviceCenterPrefix}${this.phoneNumber}`;
|
||||
}
|
||||
const encodedPhoneNumber = this.encodeUCS2(phoneNumberWithCountryCode);
|
||||
const messageSegments = this.splitMessage(this.messageToSend, 70); // 将消息分段
|
||||
const uid = Math.floor(Math.random() * 256); // 生成随机的UID
|
||||
const totalSegments = messageSegments.length;
|
||||
let allSegmentsSent = true;
|
||||
let errorCode = null;
|
||||
for (let i = 0; i < totalSegments; i++) {
|
||||
const segment = messageSegments[i];
|
||||
const encodedMessage = this.encodeUCS2(segment);
|
||||
const currentSegment = i + 1;
|
||||
const Command = `${uid},${currentSegment},${totalSegments}`;
|
||||
const params = new URLSearchParams({
|
||||
number: encodedPhoneNumber,
|
||||
msg: encodedMessage,
|
||||
Command: Command
|
||||
});
|
||||
try {
|
||||
const response = await fetch(`/cgi-bin/send_sms?${params.toString()}`);
|
||||
const data = await response.text();
|
||||
console.log("Response from server:", data);
|
||||
|
||||
// 检查返回的数据中是否包含 '+CMS ERROR'
|
||||
if (data.includes('+CMS ERROR')) {
|
||||
errorCode = data.match(/\+CMS ERROR: (\d+)/)?.[1];
|
||||
console.error("SMS send error:", data);
|
||||
allSegmentsSent = false;
|
||||
break; // 停止发送剩余的段
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fetch error:", error);
|
||||
allSegmentsSent = false;
|
||||
break; // 停止发送剩余的段
|
||||
}
|
||||
}
|
||||
if (allSegmentsSent) {
|
||||
this.showNotification("SMS sent successfully!");
|
||||
} else {
|
||||
this.showNotification(`SMS sending failed!: ${errorCode}`);
|
||||
}
|
||||
},
|
||||
|
||||
splitMessage(message, length) {
|
||||
const segments = [];
|
||||
for (let i = 0; i < message.length; i += length) {
|
||||
segments.push(message.substring(i, i + length));
|
||||
}
|
||||
return segments;
|
||||
},
|
||||
|
||||
showNotification(message, type) {
|
||||
const notification = document.getElementById('notification');
|
||||
notification.innerText = message;
|
||||
notification.className = `alert alert-${type}`;
|
||||
notification.style.display = 'block';
|
||||
setTimeout(() => {
|
||||
notification.style.display = 'none';
|
||||
}, 3000); // 3秒后自动关闭
|
||||
},
|
||||
|
||||
// 初始化
|
||||
// Initialize
|
||||
init() {
|
||||
this.clearData();
|
||||
this.requestSMS();
|
||||
},
|
||||
|
||||
// 全选/取消全选
|
||||
// Select all/deselect all
|
||||
toggleAll(event) {
|
||||
this.selectedMessages = event.target.checked ? this.messages.map((_, index) => index) : [];
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,133 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>RM5xxx TTL Changer</title>
|
||||
|
||||
<script src="/js/alpinejs.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/css/bulma.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/admin.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- START NAV -->
|
||||
<nav class="navbar is-black" x-data="{ isOpen: false }">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item brand-text" href="/">
|
||||
Quectel 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="/ttl.html">
|
||||
TTL Changer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- END NAV -->
|
||||
<div class="container" x-data="ttlCommands()" x-init="init">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<div class="columns">
|
||||
<div class="column is-8">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
TTL Enabler
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<p>
|
||||
<h2>TTL Status</h2> <br>
|
||||
TTL is <span class="tag is-large" :class="ttldata.isEnabled ? 'is-success' : 'is-danger'" x-text="ttldata.isEnabled == true ? 'ON' : 'OFF'"></span>
|
||||
<br />
|
||||
TTL Set to <span x-text="ttldata.ttl"></span>
|
||||
</p>
|
||||
<div class="field">
|
||||
<label class="label">Set TTL</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" placeholder="64"
|
||||
x-model="newTTL">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button class="button is-link" @click="setTTL()">Set TTL</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Common TTL For Providers
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<ul>
|
||||
<li>Magenta: 65</li>
|
||||
<li>Red: 88</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
|
||||
function ttlCommands() {
|
||||
return {
|
||||
isLoading: false,
|
||||
ttldata: null,
|
||||
newTTL: 0,
|
||||
init() {
|
||||
fetch('/cgi-bin/get_ttl_status')
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.ttldata = data
|
||||
});
|
||||
},
|
||||
setTTL() {
|
||||
fetch('/cgi-bin/set_ttl?' + new URLSearchParams({
|
||||
ttlvalue: this.newTTL,
|
||||
}))
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.ttldata = data
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
275
simpleadmin/www/watchcat.html
Normal file
275
simpleadmin/www/watchcat.html
Normal file
@@ -0,0 +1,275 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- Import all the bootstrap css files from css folder -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Logo -->
|
||||
<link rel="simpleadmin-logo" href="favicon.ico" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
|
||||
<style>
|
||||
.form-switch .form-check-input {
|
||||
width: 2.4em;
|
||||
height: 1.2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="simpleWatchCat()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 ml-4 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/settings.html"
|
||||
aria-current="page"
|
||||
>Simple Settings</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="row mt-3 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="row mt-3 mb-5 align-content-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3">
|
||||
<label> Enable Watchcat </label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="mt-2">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="watchCatSwitch"
|
||||
x-model="watchCatStatus"
|
||||
:disabled="!isFormComplete"
|
||||
x-on:change="setWatchCatSettings"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-3 mb-3 align-items-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Track IP </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Request Timeout </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Failure Amount </label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5">
|
||||
<div class="mt-3 mb-4">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Select Site to Ping"
|
||||
x-model="trackIP"
|
||||
>
|
||||
<option selected>Select IP</option>
|
||||
<option value="1.1.1.1">1.1.1.1</option>
|
||||
<option value="8.8.8.8">8.8.8.8</option>
|
||||
<option value="9.9.9.9">9.9.9.9</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Ping Timeout"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Timeout in Seconds."
|
||||
x-model="pingTimeout"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Sizing example input"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Failure Amount."
|
||||
x-model="pingFailureCount"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
Still under development. Coming soon...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3 mb-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat Logs</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="form-floating">
|
||||
<textarea
|
||||
class="form-control"
|
||||
placeholder="Leave a comment here"
|
||||
id="floatingTextarea2"
|
||||
style="height: 100px"
|
||||
x-text="response"
|
||||
readonly
|
||||
></textarea>
|
||||
<label for="floatingTextarea2">Logs</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
No log is provided when successfully enabling the watchcat.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function simpleWatchCat() {
|
||||
return {
|
||||
watchCatStatus: false, // Initialize as false (not enabled)
|
||||
trackIP: "",
|
||||
pingTimeout: "",
|
||||
pingFailureCount: "",
|
||||
response: "",
|
||||
|
||||
setWatchCatSettings() {
|
||||
fetch(
|
||||
"/cgi-bin/watchcat_maker?" +
|
||||
new URLSearchParams({
|
||||
WATCHCAT_ENABLED: this.watchCatStatus ? "enable" : "disable",
|
||||
TRACK_IP: this.trackIP,
|
||||
PING_TIMEOUT: this.pingTimeout,
|
||||
PING_FAILURE_COUNT: this.pingFailureCount,
|
||||
})
|
||||
)
|
||||
.then((response) => response.text()) // Convert response to text
|
||||
.then((data) => {
|
||||
this.response = data; // Store the response data
|
||||
console.log(data); // Log the response for debugging
|
||||
})
|
||||
.then(() => {
|
||||
this.fetchWatchCatSettings();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error); // Handle any errors
|
||||
this.response = "An error occurred.";
|
||||
});
|
||||
},
|
||||
|
||||
// Computed property to check if the form is complete
|
||||
get isFormComplete() {
|
||||
return (
|
||||
this.trackIP !== "" &&
|
||||
this.pingTimeout !== "" &&
|
||||
this.pingFailureCount !== ""
|
||||
);
|
||||
},
|
||||
|
||||
// Fetch the current watchcat settings
|
||||
fetchWatchCatSettings() {
|
||||
fetch("/cgi-bin/get_watchcat_status")
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return response.json(); // Parse response as JSON
|
||||
})
|
||||
.then((data) => {
|
||||
console.log(data); // Log the parsed data for debugging
|
||||
|
||||
// Check if the JSON is not empty
|
||||
if (data) {
|
||||
this.watchCatStatus = data.enabled === true;
|
||||
this.trackIP = data.track_ip;
|
||||
this.pingTimeout = data.ping_timeout;
|
||||
this.pingFailureCount = data.ping_failure_count;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error); // Handle any errors
|
||||
this.response = "An error occurred.";
|
||||
});
|
||||
},
|
||||
|
||||
init() {
|
||||
this.fetchWatchCatSettings();
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
351
simpleadmin/www/watchcat_backup.html
Normal file
351
simpleadmin/www/watchcat_backup.html
Normal file
@@ -0,0 +1,351 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- <link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
||||
crossorigin="anonymous"
|
||||
/> -->
|
||||
<!-- Import all the bootstrap css files from css folder -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Logo -->
|
||||
<link rel="simpleadmin-logo" href="favicon.ico" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
|
||||
<style>
|
||||
.form-switch .form-check-input {
|
||||
width: 2.4em;
|
||||
height: 1.2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="simpleWatchCat()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 ml-4 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/settings.html"
|
||||
aria-current="page"
|
||||
>Simple Settings</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="row mt-3 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="row mt-3 mb-5 align-content-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3">
|
||||
<label> Enable Watchcat </label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="mt-2">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="watchCatSwitch"
|
||||
x-model="watchCatStatus"
|
||||
:disabled="!isFormComplete"
|
||||
x:onchange="setWatchCatSettings"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-3 mb-3 align-items-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Track IP </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Request Timeout </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Failure Amount </label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5">
|
||||
<div class="mt-3 mb-4">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Select Site to Ping"
|
||||
x-model="trackIP"
|
||||
>
|
||||
<option selected>Select IP</option>
|
||||
<option value="1.1.1.1">1.1.1.1</option>
|
||||
<option value="8.8.8.8">8.8.8.8</option>
|
||||
<option value="9.9.9.9">9.9.9.9</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Ping Timeout"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Timeout in Seconds."
|
||||
x-model="pingTimeout"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Sizing example input"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Failure Amount."
|
||||
x-model="pingFailureCount"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="row mt-3 mb-5 align-content-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3">
|
||||
<label>Sim Auto Switch</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="mt-2">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="simAutoSwitch"
|
||||
x-model="simAutoSwitchStatus"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <div class="row mt-3 mb-3 align-items-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Select Preferred SIM </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> SIM 1 APN </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> SIM 2 APN </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Failover Interval </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Scheduled SIM Hot Swap</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5">
|
||||
<div class="mt-3 mb-3">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Select Sim"
|
||||
x-model="preferredSim"
|
||||
>
|
||||
<option selected>Select SIM</option>
|
||||
<option value="1">SIM 1</option>
|
||||
<option value="2">SIM 2</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="SIM 1 APN"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Input APN for SIM 1. (Optional)"
|
||||
x-model="sim1APN"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="SIM 2 APN"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Input APN for SIM 2. (Optional)"
|
||||
x-model="sim2APN"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3 d-flex align-items-center">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Failover Interval"
|
||||
>
|
||||
<option selected>Failover Interval</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
</select>
|
||||
<label class="mx-3">Minutes</label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<input
|
||||
type="time"
|
||||
class="form-control"
|
||||
aria-label="Scheduled SIM Hot Swap"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
x-model="scheduledSIMHotSwap"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<!-- Setting a low ping timeout and ping failure count may cause
|
||||
intermittent disconnections due to high sensitivity. <br />
|
||||
Select appropriate values for both based on your needs.<br /> -->
|
||||
Still under development. Coming soon...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3 mb-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat Logs</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="form-floating">
|
||||
<textarea
|
||||
class="form-control"
|
||||
placeholder="Leave a comment here"
|
||||
id="floatingTextarea2"
|
||||
style="height: 100px"
|
||||
x-text="response"
|
||||
readonly
|
||||
></textarea>
|
||||
<label for="floatingTextarea2">Logs Here</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function simpleWatchCat() {
|
||||
return {
|
||||
watchCatStatus: false,
|
||||
trackIP: "",
|
||||
pingTimeout: "",
|
||||
pingFailureCount: "",
|
||||
response: "",
|
||||
|
||||
setWatchCatSettings() {
|
||||
fetch(
|
||||
"/cgi-bin/watchcat_maker?" +
|
||||
new URLSearchParams({
|
||||
WATCHCAT_ENABLED: this.watchCatStatus,
|
||||
TRACK_IP: this.trackIP,
|
||||
PING_TIMEOUT: this.pingTimeout,
|
||||
PING_FAILURE_COUNT: this.pingFailureCount,
|
||||
})
|
||||
)
|
||||
.then((response) => response.text()) // Convert response to text
|
||||
.then((data) => {
|
||||
this.response = data; // Store the response data
|
||||
console.log(data); // Log the response for debugging
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error); // Handle any errors
|
||||
this.response = "An error occurred.";
|
||||
});
|
||||
},
|
||||
|
||||
// Computed property to check if the form is complete
|
||||
get isFormComplete() {
|
||||
return (
|
||||
this.trackIP !== "" &&
|
||||
this.pingTimeout !== "" &&
|
||||
this.pingFailureCount !== ""
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1
simplefirewall/.rev
Normal file
1
simplefirewall/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the ports you want to block
|
||||
PORTS=("80" "8080" "8088" "443") # Default ports, will be modified by the install script
|
||||
PORTS=("80" "443") # Default ports, will be modified by the install script
|
||||
|
||||
# First, allow specified ports on bridge0, eth0, and tailscale0
|
||||
for port in "${PORTS[@]}"; do
|
||||
|
||||
1
simpleupdates/.rev
Normal file
1
simpleupdates/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
271
simpleupdates/scripts/update_simpleadmin.sh
Normal file
271
simpleupdates/scripts/update_simpleadmin.sh
Normal file
@@ -0,0 +1,271 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
DIR_NAME="simpleadmin"
|
||||
SERVICE_FILE="/lib/systemd/system/install_simpleadmin.service"
|
||||
SERVICE_NAME="install_simpleadmin"
|
||||
TMP_SCRIPT="/tmp/install_simpleadmin.sh"
|
||||
LOG_FILE="/tmp/install_simpleadmin.log"
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
# Tmp Script dependent constants
|
||||
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Installation Prep
|
||||
remount_rw
|
||||
systemctl daemon-reload
|
||||
rm $SERVICE_FILE > /dev/null 2>&1
|
||||
rm $SERVICE_NAME > /dev/null 2>&1
|
||||
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||
export HOME=/usrdata/root
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
uninstall_simpleadmin() {
|
||||
echo "Uninstalling Simpleadmin..."
|
||||
|
||||
# Check if Lighttpd service is installed and remove it if present
|
||||
if [ -f "/lib/systemd/system/lighttpd.service" ]; then
|
||||
echo "Lighttpd detected, uninstalling Lighttpd webserver and its modules..."
|
||||
systemctl stop lighttpd
|
||||
rm -f /lib/systemd/system/lighttpd.service
|
||||
opkg --force-remove --force-removal-of-dependent-packages remove lighttpd-mod-authn_file lighttpd-mod-auth lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy lighttpd
|
||||
fi
|
||||
echo -e "\e[1;34mUninstalling simpleadmin content...\e[0m"
|
||||
systemctl stop simpleadmin_generate_status
|
||||
systemctl stop simpleadmin_httpd
|
||||
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||
systemctl daemon-reload
|
||||
|
||||
echo -e "\e[1;34mUninstalling ttyd...\e[0m"
|
||||
systemctl stop ttyd
|
||||
rm -rf /usrdata/ttyd
|
||||
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||
rm -f /lib/systemd/system/ttyd.service
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/ttyd.service
|
||||
rm -f /bin/ttyd
|
||||
echo -e "\e[1;32mttyd has been uninstalled.\e[0m"
|
||||
|
||||
echo "Uninstallation process completed."
|
||||
}
|
||||
|
||||
install_lighttpd() {
|
||||
# Check for simpleadmin_httpd service and remove if exists
|
||||
if [ -f "/lib/systemd/system/simpleadmin_httpd.service" ]; then
|
||||
systemctl stop simpleadmin_httpd
|
||||
rm /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm /lib/systemd/system/multi-user.target.wants/simpleadmin_httpd.service
|
||||
fi
|
||||
|
||||
/opt/bin/opkg install sudo lighttpd lighttpd-mod-auth lighttpd-mod-authn_file lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy
|
||||
# Ensure rc.unslung doesn't try to start it
|
||||
# Dynamically find and remove any Lighttpd-related init script
|
||||
for script in /opt/etc/init.d/*lighttpd*; do
|
||||
if [ -f "$script" ]; then
|
||||
echo "Removing existing Lighttpd init script: $script"
|
||||
rm "$script" # Remove the script if it contains 'lighttpd' in its name
|
||||
fi
|
||||
done
|
||||
systemctl stop lighttpd
|
||||
echo -e "\033[0;32mInstalling/Updating Lighttpd...\033[0m"
|
||||
mkdir -p "$SIMPLE_ADMIN_DIR"
|
||||
wget -O "$SIMPLE_ADMIN_DIR/lighttpd.conf" $GITROOT/simpleadmin/lighttpd.conf
|
||||
wget -O "/lib/systemd/system/lighttpd.service" $GITROOT/simpleadmin/systemd/lighttpd.service
|
||||
ln -sf "/lib/systemd/system/lighttpd.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
echo "www-data ALL = (root) NOPASSWD: /usr/sbin/iptables, /usr/sbin/ip6tables, /usrdata/simplefirewall/ttl-override, /bin/echo, /bin/cat" > /opt/etc/sudoers.d/www-data
|
||||
|
||||
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
|
||||
-subj "/C=US/ST=MI/L=Romulus/O=RMIITools/CN=localhost" \
|
||||
-keyout $SIMPLE_ADMIN_DIR/server.key -out $SIMPLE_ADMIN_DIR/server.crt
|
||||
systemctl daemon-reload
|
||||
systemctl start lighttpd
|
||||
|
||||
echo -e "\033[0;32mLighttpd installation/update complete.\033[0m"
|
||||
}
|
||||
|
||||
install_simpleadmin() {
|
||||
remount_rw
|
||||
echo -e "\e[1;31m2) Installing simpleadmin from the $GITTREE branch\e[0m"
|
||||
mkdir $SIMPLE_ADMIN_DIR
|
||||
mkdir $SIMPLE_ADMIN_DIR/systemd
|
||||
mkdir $SIMPLE_ADMIN_DIR/script
|
||||
mkdir $SIMPLE_ADMIN_DIR/console
|
||||
mkdir $SIMPLE_ADMIN_DIR/console/menu
|
||||
mkdir $SIMPLE_ADMIN_DIR/console/services
|
||||
mkdir $SIMPLE_ADMIN_DIR/console/services/systemd
|
||||
mkdir $SIMPLE_ADMIN_DIR/www
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/cgi-bin
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/css
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/js
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/fonts
|
||||
cd $SIMPLE_ADMIN_DIR/systemd
|
||||
wget $GITROOT/simpleadmin/systemd/lighttpd.service
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/script
|
||||
wget $GITROOT/simpleadmin/script/ttl_script.sh
|
||||
wget $GITROOT/simpleadmin/script/remove_watchcat.sh
|
||||
wget $GITROOT/simpleadmin/script/create_watchcat.sh
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/console
|
||||
wget $GITROOT/simpleadmin/console/.profile
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/console/menu
|
||||
wget $GITROOT/simpleadmin/console/menu/start_menu.sh
|
||||
ln -f $SIMPLE_ADMIN_DIR/console/menu/start_menu.sh /usrdata/root/bin/menu
|
||||
wget $GITROOT/simpleadmin/console/menu/sfirewall_settings.sh
|
||||
wget $GITROOT/simpleadmin/console/menu/start_menu.sh
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www
|
||||
wget $GITROOT/simpleadmin/www/deviceinfo.html
|
||||
wget $GITROOT/simpleadmin/www/favicon.ico
|
||||
wget $GITROOT/simpleadmin/www/index.html
|
||||
wget $GITROOT/simpleadmin/www/network.html
|
||||
wget $GITROOT/simpleadmin/www/settings.html
|
||||
wget $GITROOT/simpleadmin/www/sms.html
|
||||
wget $GITROOT/simpleadmin/www/scanner.html
|
||||
wget $GITROOT/simpleadmin/www/watchcat.html
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/js
|
||||
wget $GITROOT/simpleadmin/www/js/alpinejs.min.js
|
||||
wget $GITROOT/simpleadmin/www/js/bootstrap.bundle.min.js
|
||||
wget $GITROOT/simpleadmin/www/js/dark-mode.js
|
||||
wget $GITROOT/simpleadmin/www/js/generate-freq-box.js
|
||||
wget $GITROOT/simpleadmin/www/js/parse-settings.js
|
||||
wget $GITROOT/simpleadmin/www/js/populate-checkbox.js
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/css
|
||||
wget $GITROOT/simpleadmin/www/css/bootstrap.min.css
|
||||
wget $GITROOT/simpleadmin/www/css/styles.css
|
||||
wget $GITROOT/simpleadmin/www/css/all.min.css
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/fonts
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-300italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-300.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-500italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-500.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-600italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-600.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-700italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-700.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-regular.woff2
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/cgi-bin
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_atcommand
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/user_atcommand
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_ping
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_sms
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_ttl_status
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/set_ttl
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/send_sms
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_uptime
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_watchcat_status
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/set_watchcat
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/watchcat_maker
|
||||
sleep 1
|
||||
cd /
|
||||
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/script/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/console/menu/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/console/.profile
|
||||
cp -f $SIMPLE_ADMIN_DIR/console/.profile /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
||||
sleep 1
|
||||
systemctl daemon-reload
|
||||
sleep 1
|
||||
}
|
||||
install_ttyd() {
|
||||
echo -e "\e[1;34mStarting ttyd installation process...\e[0m"
|
||||
cd $SIMPLE_ADMIN_DIR/console
|
||||
curl -L -o ttyd https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.armhf && chmod +x ttyd
|
||||
wget "$GITROOT/simpleadmin/console/ttyd.bash" && chmod +x ttyd.bash
|
||||
cd $SIMPLE_ADMIN_DIR/systemd/
|
||||
wget "$GITROOT/simpleadmin/systemd/ttyd.service"
|
||||
cp -f $SIMPLE_ADMIN_DIR/systemd/ttyd.service /lib/systemd/system/
|
||||
ln -sf /usrdata/simpleadmin/ttyd /bin
|
||||
|
||||
# Enabling and starting ttyd service
|
||||
systemctl daemon-reload
|
||||
ln -sf /lib/systemd/system/ttyd.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl start ttyd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mFailed to start ttyd service. Please check the systemd service file and ttyd binary.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\e[1;32mInstallation Complete! ttyd server is up.\e[0m"
|
||||
}
|
||||
uninstall_simpleadmin
|
||||
install_lighttpd
|
||||
install_simpleadmin
|
||||
install_ttyd
|
||||
remount_ro
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
124
simpleupdates/scripts/update_simplefirewall.sh
Normal file
124
simpleupdates/scripts/update_simplefirewall.sh
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
DIR_NAME="simplefirewall"
|
||||
SERVICE_FILE="/lib/systemd/system/install_simplefirewall.service"
|
||||
SERVICE_NAME="install_simplefirewall"
|
||||
TMP_SCRIPT="/tmp/install_simple_firewall.sh"
|
||||
LOG_FILE="/tmp/install_simplefirewall.log"
|
||||
|
||||
# Tmp Script dependent constants
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
# Function to remove Simple Firewall
|
||||
uninstall_simple_firewall() {
|
||||
echo "Uninstalling Simplefirewall..."
|
||||
systemctl stop simplefirewall
|
||||
systemctl stop ttl-override
|
||||
rm -f /lib/systemd/system/simplefirewall.service
|
||||
rm -f /lib/systemd/system/ttl-override.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_FIREWALL_DIR"
|
||||
echo "Simplefirewall uninstalled."
|
||||
}
|
||||
# Function to install Simple Firewall
|
||||
install_simple_firewall() {
|
||||
systemctl stop simplefirewall
|
||||
systemctl stop ttl-override
|
||||
echo -e "\033[0;32mInstalling/Updating Simple Firewall...\033[0m"
|
||||
mount -o remount,rw /
|
||||
mkdir -p "$SIMPLE_FIREWALL_DIR"
|
||||
mkdir -p "$SIMPLE_FIREWALL_SYSTEMD_DIR"
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/simplefirewall.sh" $GITROOT/simplefirewall/simplefirewall.sh
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/ttl-override" $GITROOT/simplefirewall/ttl-override
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/ttlvalue" $GITROOT/simplefirewall/ttlvalue
|
||||
chmod 666 $SIMPLE_FIREWALL_DIR/ttlvalue
|
||||
chmod +x "$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
chmod +x "$SIMPLE_FIREWALL_DIR/ttl-override"
|
||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" $GITROOT/simplefirewall/systemd/simplefirewall.service
|
||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/ttl-override.service" $GITROOT/simplefirewall/systemd/ttl-override.service
|
||||
cp -rf $SIMPLE_FIREWALL_SYSTEMD_DIR/* /lib/systemd/system
|
||||
ln -sf "/lib/systemd/system/simplefirewall.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
ln -sf "/lib/systemd/system/ttl-override.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
systemctl daemon-reload
|
||||
systemctl start simplefirewall
|
||||
systemctl start ttl-override
|
||||
echo -e "\033[0;32mSimple Firewall installation/update complete.\033[0m"
|
||||
}
|
||||
uninstall_simple_firewall
|
||||
install_simple_firewall
|
||||
remount_ro
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
167
simpleupdates/scripts/update_socat-at-bridge.sh
Normal file
167
simpleupdates/scripts/update_socat-at-bridge.sh
Normal file
@@ -0,0 +1,167 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
# Define filesystem path
|
||||
DIR_NAME="socat-at-bridge"
|
||||
SERVICE_FILE="/lib/systemd/system/install_socat-at-bridge.service"
|
||||
SERVICE_NAME="install_socat-at-bridge"
|
||||
TMP_SCRIPT="/tmp/install_socat-at-bridge.sh"
|
||||
LOG_FILE="/tmp/install_socat-at-bridge.log"
|
||||
|
||||
# Tmp Script dependent constants
|
||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
uninstall_at_socat() {
|
||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||
systemctl daemon-reload > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
install_at_socat() {
|
||||
# Install service units
|
||||
echo -e "\033[0;32mInstalling AT Socat Bridge services...\033[0m"
|
||||
mkdir $SOCAT_AT_DIR
|
||||
cd $SOCAT_AT_DIR
|
||||
mkdir $SOCAT_AT_SYSD_DIR
|
||||
wget $GITROOT/socat-at-bridge/socat-armel-static
|
||||
wget $GITROOT/socat-at-bridge/killsmd7bridge
|
||||
wget $GITROOT/socat-at-bridge/atcmd
|
||||
wget $GITROOT/socat-at-bridge/atcmd11
|
||||
cd $SOCAT_AT_SYSD_DIR
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd11.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd11-from-ttyIN.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd11-to-ttyIN.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-killsmd7bridge.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd7-from-ttyIN2.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd7-to-ttyIN2.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd7.service
|
||||
|
||||
# Set execute permissions
|
||||
cd $SOCAT_AT_DIR
|
||||
chmod +x socat-armel-static
|
||||
chmod +x killsmd7bridge
|
||||
chmod +x atcmd
|
||||
chmod +x atcmd11
|
||||
|
||||
# Link new command for AT Commands from the shell
|
||||
ln -sf $SOCAT_AT_DIR/atcmd /bin
|
||||
ln -sf $SOCAT_AT_DIR/atcmd11 /bin
|
||||
|
||||
# Install service units
|
||||
echo -e "\033[0;32mAdding AT Socat Bridge systemd service units...\033[0m"
|
||||
cp -rf $SOCAT_AT_SYSD_DIR/*.service /lib/systemd/system
|
||||
ln -sf /lib/systemd/system/socat-killsmd7bridge.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11-to-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11-from-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7-to-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7-from-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
systemctl start socat-smd11
|
||||
sleep 2s
|
||||
systemctl start socat-smd11-to-ttyIN
|
||||
systemctl start socat-smd11-from-ttyIN
|
||||
echo -e "\033[0;32mAT Socat Bridge service online: smd11 to ttyOUT\033[0m"
|
||||
systemctl start socat-killsmd7bridge
|
||||
sleep 1s
|
||||
systemctl start socat-smd7
|
||||
sleep 2s
|
||||
systemctl start socat-smd7-to-ttyIN2
|
||||
systemctl start socat-smd7-from-ttyIN2
|
||||
echo -e "\033[0;32mAT Socat Bridge service online: smd7 to ttyOUT2\033[0m"
|
||||
remount_ro
|
||||
cd /
|
||||
echo -e "\033[0;32mAT Socat Bridge services Installed!\033[0m"
|
||||
}
|
||||
uninstall_at_socat
|
||||
install_at_socat
|
||||
remount_ro
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
90
simpleupdates/scripts/update_sshd.sh
Normal file
90
simpleupdates/scripts/update_sshd.sh
Normal file
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
DIR_NAME="simpleupdates"
|
||||
SERVICE_FILE="/lib/systemd/system/install_sshd.service"
|
||||
SERVICE_NAME="install_sshd"
|
||||
TMP_SCRIPT="/tmp/install_sshd.sh"
|
||||
LOG_FILE="/tmp/install_sshd.log"
|
||||
|
||||
# Tmp Script dependent constants
|
||||
|
||||
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
|
||||
install_sshd() {
|
||||
echo -e "\e[1;32mOpenSSH Server\e[0m"
|
||||
remount_rw
|
||||
|
||||
mkdir /usrdata/sshd
|
||||
wget -O /lib/systemd/system/sshd.service "$GITROOT/sshd/sshd.service"
|
||||
ln -sf "/lib/systemd/system/sshd.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
|
||||
opkg install openssh-server-pam
|
||||
for script in /opt/etc/init.d/*sshd*; do
|
||||
if [ -f "$script" ]; then
|
||||
echo "Removing existing sshd init script: $script"
|
||||
rm "$script" # Remove the script if it contains 'sshd' in its name
|
||||
fi
|
||||
done
|
||||
/opt/bin/ssh-keygen -A
|
||||
systemctl daemon-reload
|
||||
systemctl enable sshd
|
||||
|
||||
# Enable PAM and PermitRootLogin
|
||||
sed -i "s/^.*UsePAM .*/UsePAM yes/" "/opt/etc/ssh/sshd_config"
|
||||
sed -i "s/^.*PermitRootLogin .*/PermitRootLogin yes/" "/opt/etc/ssh/sshd_config"
|
||||
|
||||
# Ensure the sshd user exists in the /opt/etc/passwd file
|
||||
grep "sshd:x:106" /opt/etc/passwd || echo "sshd:x:106:65534:Linux User,,,:/opt/run/sshd:/bin/nologin" >> /opt/etc/passwd
|
||||
systemctl start sshd
|
||||
|
||||
echo -e "\e[1;32mOpenSSH installed!!\e[0m"
|
||||
}
|
||||
install_sshd
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
133
simpleupdates/scripts/update_tailscale.sh
Normal file
133
simpleupdates/scripts/update_tailscale.sh
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
# Define filesystem path
|
||||
DIR_NAME="tailscale"
|
||||
SERVICE_FILE="/lib/systemd/system/install_tailscale.service"
|
||||
SERVICE_NAME="install_tailscale"
|
||||
TMP_SCRIPT="/tmp/install_tailscale.sh"
|
||||
LOG_FILE="/tmp/install_tailscale.log"
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
# Tmp Script dependent constants
|
||||
TAILSCALE_DIR="/usrdata/tailscale/"
|
||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Installation Prep
|
||||
remount_rw
|
||||
systemctl daemon-reload
|
||||
rm $SERVICE_FILE > /dev/null 2>&1
|
||||
rm $SERVICE_NAME > /dev/null 2>&1
|
||||
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
export HOME=/usrdata/root
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="http://git.ievo.top/tyk/quectel-rgmii-toolkit/raw/branch/SDXLEMUR"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
# Define filesystem path
|
||||
TAILSCALE_DIR="/usrdata/tailscale/"
|
||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
install_update_tailscale() {
|
||||
echo "Checking if Tailscale is already installed..."
|
||||
if [ -f "$TAILSCALE_DIR/tailscale" ]; then
|
||||
echo "Tailscale binary found. Updating Tailscale..."
|
||||
ln -sf "$TAILSCALE_DIR/tailscale" "/usrdata/root/bin/tailscale"
|
||||
echo y | $TAILSCALE_DIR/tailscale update
|
||||
echo -e "\e[32mTailscale updated!\e[0m"
|
||||
remount_ro
|
||||
exit 0
|
||||
else
|
||||
echo "Installing Tailscale..."
|
||||
mkdir -p "$TAILSCALE_DIR" "$TAILSCALE_SYSD_DIR"
|
||||
echo "Downloading binary files..."
|
||||
cd /usrdata
|
||||
curl -O https://pkgs.tailscale.com/stable/tailscale_1.76.1_arm.tgz
|
||||
tar -xzf tailscale_1.76.1_arm.tgz
|
||||
rm tailscale_1.76.1_arm.tgz
|
||||
cd /usrdata/tailscale_1.76.1_arm
|
||||
mv tailscale tailscaled "$TAILSCALE_DIR/"
|
||||
rm -rf /usrdata/tailscale_1.76.1_arm
|
||||
echo "Downloading systemd files..."
|
||||
cd "$TAILSCALE_SYSD_DIR"
|
||||
wget $GITROOT/tailscale/systemd/tailscaled.service
|
||||
wget $GITROOT/tailscale/systemd/tailscaled.defaults
|
||||
sleep 2s
|
||||
echo "Setting Permissions..."
|
||||
chmod +x "$TAILSCALE_DIR/tailscaled" "$TAILSCALE_DIR/tailscale"
|
||||
echo "Copying systemd units..."
|
||||
cp -rf "$TAILSCALE_SYSD_DIR"/* /lib/systemd/system/
|
||||
ln -sf /lib/systemd/system/tailscaled.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
echo "Starting Tailscaled..."
|
||||
systemctl start tailscaled
|
||||
cd /
|
||||
ln -sf /usrdata/tailscale/tailscale /usrdata/root/bin
|
||||
remount_ro
|
||||
echo -e "\e[32mTailscale installed successfully.\e[0m"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute the function
|
||||
install_update_tailscale
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
12
simpleupdates/simpleadmin.conf
Normal file
12
simpleupdates/simpleadmin.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
# Enable or disable update checks
|
||||
CONF_ENABLED=no
|
||||
# Check for updates at boot
|
||||
CHECK_AT_BOOT=no
|
||||
# Update frequency: daily, weekly, monthly, or none
|
||||
UPDATE_FREQUENCY=none
|
||||
# Scheduled time for updates (24-hour UTC format)
|
||||
SCHEDULED_TIME=00:00
|
||||
# Day for weekly updates (e.g., Mon, Tues, Wed, Thurs, Fri)
|
||||
WEEKLY_DAY=
|
||||
# Date for monthly updates (e.g., 15 for the 15th of the month)
|
||||
MONTHLY_DATE=
|
||||
255
simpleupdates/simpleupdate
Normal file
255
simpleupdates/simpleupdate
Normal file
@@ -0,0 +1,255 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configuration and directories
|
||||
CONFIG_FILE="/usrdata/simpleupdates/simpleupdate.conf"
|
||||
GITUSER="iamromulan"
|
||||
GITTREE="main"
|
||||
DIRECTORIES=("simpleadmin" "socat-at-bridge" "simplefirewall" "tailscale" "ttyd")
|
||||
BASE_URL="https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE"
|
||||
LOG_FILE="/tmp/simpleupdate.log"
|
||||
|
||||
# Load configuration
|
||||
load_config() {
|
||||
if [[ -f "$CONFIG_FILE" ]]; then
|
||||
source "$CONFIG_FILE"
|
||||
else
|
||||
echo "Configuration file ($CONFIG_FILE) not found."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to trim the log file to the last 100 lines
|
||||
trim_log_file() {
|
||||
tail -n 100 "$LOG_FILE" > "$LOG_FILE.tmp" && mv "$LOG_FILE.tmp" "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to check for updates
|
||||
check_for_updates() {
|
||||
echo "$(date): Checking for updates..."
|
||||
for dir in "${DIRECTORIES[@]}"; do
|
||||
local remote_rev=$(wget -qO- "$BASE_URL/$dir/.rev")
|
||||
local local_rev_file="/usrdata/$dir/.rev"
|
||||
|
||||
if [[ ! -f "$local_rev_file" ]]; then
|
||||
echo "No local revision file found for $dir, skipping."
|
||||
continue
|
||||
fi
|
||||
|
||||
local local_rev=$(cat "$local_rev_file")
|
||||
|
||||
if [[ "$remote_rev" -gt "$local_rev" ]]; then
|
||||
echo "Update available for $dir, updating..."
|
||||
wget -qO "/tmp/update_${dir}.sh" "$BASE_URL/simpleupdates/scripts/update_${dir}.sh"
|
||||
chmod +x "/tmp/update_${dir}.sh"
|
||||
"/tmp/update_${dir}.sh"
|
||||
else
|
||||
echo "$dir is up to date."
|
||||
fi
|
||||
done
|
||||
trim_log_file
|
||||
wait_to_update
|
||||
}
|
||||
|
||||
# Function to wait and trigger updates based on scheduling
|
||||
wait_to_update() {
|
||||
echo "Waiting for the next update check according to schedule..."
|
||||
while true; do
|
||||
local current_time=$(date "+%H:%M")
|
||||
local current_day=$(date "+%a")
|
||||
local current_date=$(date "+%d")
|
||||
|
||||
case $UPDATE_FREQUENCY in
|
||||
daily)
|
||||
if [[ "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||
check_for_updates
|
||||
fi
|
||||
;;
|
||||
weekly)
|
||||
if [[ "$current_day" == "$WEEKLY_DAY" && "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||
check_for_updates
|
||||
fi
|
||||
;;
|
||||
monthly)
|
||||
if [[ "$current_date" == "$MONTHLY_DATE" && "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||
check_for_updates
|
||||
fi
|
||||
;;
|
||||
none)
|
||||
echo "Update checking is disabled by frequency setting."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
sleep 30 # Sleep for 30 seconds for more granular checks
|
||||
trim_log_file
|
||||
done
|
||||
}
|
||||
|
||||
# Daemon mode to wait and trigger updates based on scheduling
|
||||
daemon_mode() {
|
||||
load_config
|
||||
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||
echo "Daemon mode started."
|
||||
# Validate only one update frequency is defined
|
||||
frequency_count=0
|
||||
[[ "$UPDATE_FREQUENCY" == "daily" ]] && ((frequency_count++))
|
||||
[[ "$UPDATE_FREQUENCY" == "weekly" ]] && ((frequency_count++))
|
||||
[[ "$UPDATE_FREQUENCY" == "monthly" ]] && ((frequency_count++))
|
||||
|
||||
if [[ $frequency_count -gt 1 ]]; then
|
||||
echo "Error: More than one update frequency is defined. Exiting."
|
||||
exit 1
|
||||
elif [[ $frequency_count -eq 0 && "$UPDATE_FREQUENCY" != "none" ]]; then
|
||||
echo "Error: No valid update frequency defined. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$CONF_ENABLED" == "no" ]]; then
|
||||
echo "Updates are disabled in the configuration."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$CHECK_AT_BOOT" == "yes" ]]; then
|
||||
check_for_updates
|
||||
else
|
||||
wait_to_update
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check for updates
|
||||
force_check_for_updates() {
|
||||
echo "$(date): Checking for updates..."
|
||||
for dir in "${DIRECTORIES[@]}"; do
|
||||
local remote_rev=$(wget -qO- "$BASE_URL/$dir/.rev")
|
||||
local local_rev_file="/usrdata/$dir/.rev"
|
||||
|
||||
if [[ ! -f "$local_rev_file" ]]; then
|
||||
echo "No local revision file found for $dir, skipping."
|
||||
continue
|
||||
fi
|
||||
|
||||
local local_rev=$(cat "$local_rev_file")
|
||||
|
||||
if [[ "$remote_rev" -gt "$local_rev" ]]; then
|
||||
echo "Update available for $dir, updating..."
|
||||
wget -qO "/tmp/update_${dir}.sh" "$BASE_URL/simpleupdates/scripts/update_${dir}.sh"
|
||||
chmod +x "/tmp/update_${dir}.sh"
|
||||
"/tmp/update_${dir}.sh"
|
||||
else
|
||||
echo "$dir is up to date."
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Helper function to load and update the configuration
|
||||
update_config() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if grep -q "^$key=" "$CONFIG_FILE"; then
|
||||
sed -i "s|^$key=.*|$key=$value|" "$CONFIG_FILE"
|
||||
else
|
||||
echo "$key=$value" >> "$CONFIG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Display the current configuration status
|
||||
status() {
|
||||
echo "Current Configuration Status:"
|
||||
if [[ -f "$CONFIG_FILE" ]]; then
|
||||
while IFS= read -r line; do
|
||||
echo "$line"
|
||||
done < "$CONFIG_FILE"
|
||||
else
|
||||
echo "Configuration file not found."
|
||||
fi
|
||||
}
|
||||
|
||||
# Enable automatic updates
|
||||
enable_updates() {
|
||||
update_config "CONF_ENABLED" "yes"
|
||||
echo "Automatic updates have been enabled."
|
||||
}
|
||||
|
||||
# Disable automatic updates
|
||||
disable_updates() {
|
||||
update_config "CONF_ENABLED" "no"
|
||||
echo "Automatic updates have been disabled."
|
||||
}
|
||||
|
||||
# Interactive setup for the update configuration
|
||||
setup() {
|
||||
read -p "Enable automatic updates? [yes/no]: " enable_updates
|
||||
if [[ "$enable_updates" == "yes" ]]; then
|
||||
enable_updates
|
||||
else
|
||||
disable_updates
|
||||
fi
|
||||
|
||||
read -p "Check for updates at boot? [yes/no]: " check_boot
|
||||
update_config "CHECK_AT_BOOT" "$check_boot"
|
||||
|
||||
read -p "Update frequency (none, daily, weekly, monthly): " frequency
|
||||
update_config "UPDATE_FREQUENCY" "$frequency"
|
||||
|
||||
case $frequency in
|
||||
daily)
|
||||
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||
update_config "SCHEDULED_TIME" "$time"
|
||||
;;
|
||||
weekly)
|
||||
echo "Please enter the day of the week."
|
||||
read -p "Day (full name or abbreviation, e.g., Monday or Mon): " day_input
|
||||
# Normalize input to abbreviated form
|
||||
day_abbr=$(date -d "$day_input" +%a 2>/dev/null)
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Invalid day of the week. Please try again."
|
||||
return 1
|
||||
fi
|
||||
update_config "WEEKLY_DAY" "$day_abbr"
|
||||
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||
update_config "SCHEDULED_TIME" "$time"
|
||||
;;
|
||||
monthly)
|
||||
read -p "Date of the month (1-31): " date
|
||||
update_config "MONTHLY_DATE" "$date"
|
||||
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||
update_config "SCHEDULED_TIME" "$time"
|
||||
;;
|
||||
*)
|
||||
echo "No scheduling will be set."
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Update configuration has been set."
|
||||
}
|
||||
|
||||
# Command operations: status, enable, disable, update, setup
|
||||
case "$1" in
|
||||
d)
|
||||
daemon_mode
|
||||
;;
|
||||
update)
|
||||
load_config
|
||||
force_check_for_updates
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
enable)
|
||||
enable_updates
|
||||
;;
|
||||
disable)
|
||||
disable_updates
|
||||
;;
|
||||
setup)
|
||||
setup
|
||||
;;
|
||||
*)
|
||||
echo "Usage:"
|
||||
echo "d: Run as a background check daemon"
|
||||
echo "update: Force check for and install updates"
|
||||
echo "status: Display current set update schedule"
|
||||
echo "enable: Enable automatic updates"
|
||||
echo "disable: Disable automatic updates"
|
||||
echo "setup: Set up an automatic update schedule"
|
||||
;;
|
||||
esac
|
||||
10
simpleupdates/systemd/simpleupdated.service
Normal file
10
simpleupdates/systemd/simpleupdated.service
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Simple Update Daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usrdata/simpleupdates/simpleupdate d
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
1
socat-at-bridge/.rev
Normal file
1
socat-at-bridge/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
@@ -10,24 +10,15 @@ setup_device() {
|
||||
-echoctl -echoke noflsh -ixon -crtscts
|
||||
}
|
||||
|
||||
# Prepare the device for communication
|
||||
setup_device
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
echo -e "$user_input\r" > $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)
|
||||
@@ -52,4 +43,27 @@ while true; do
|
||||
|
||||
# Clean up
|
||||
rm "$tmpfile"
|
||||
done
|
||||
}
|
||||
|
||||
# Prepare the device for communication
|
||||
setup_device
|
||||
|
||||
# Check if an AT command is provided as an argument
|
||||
if [ $# -gt 0 ]; then
|
||||
# Concatenate all arguments to handle commands with spaces and/or quotes correctly
|
||||
FULL_CMD="$*"
|
||||
send_at_command "$FULL_CMD"
|
||||
else
|
||||
echo -e "\033[0;36mType 'exit' to end the session.\033[0m"
|
||||
while true; do
|
||||
echo -en "\033[0;36mEnter AT Command: \033[0m"
|
||||
read user_input
|
||||
|
||||
if [[ "$user_input" == "exit" ]]; then
|
||||
echo -e "\033[0;32mExiting...\033[0m"
|
||||
break
|
||||
fi
|
||||
|
||||
send_at_command "$user_input"
|
||||
done
|
||||
fi
|
||||
|
||||
69
socat-at-bridge/atcmd11
Normal file
69
socat-at-bridge/atcmd11
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEVICE=/dev/ttyOUT
|
||||
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
|
||||
@@ -3,7 +3,7 @@ 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
|
||||
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN,raw,echo=0,group=20,perm=660 pty,link=/dev/ttyOUT,raw,echo=1,group=20,perm=660
|
||||
# Add a delay to prevent the clients from starting too early
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
Restart=always
|
||||
|
||||
@@ -3,7 +3,7 @@ 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
|
||||
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN2,raw,echo=0,group=20,perm=660 pty,link=/dev/ttyOUT2,raw,echo=1,group=20,perm=660
|
||||
# Add a delay to prevent the clients from starting too early
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
Restart=always
|
||||
|
||||
17
sshd/sshd.service
Normal file
17
sshd/sshd.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=OpenBSD Secure Shell server
|
||||
Documentation=man:sshd(8) man:sshd_config(5)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
PIDFile=/opt/var/run/sshd.pid
|
||||
ExecStartPre=/opt/sbin/sshd -t
|
||||
ExecStart=/opt/sbin/sshd -D
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=sshd.service
|
||||
1
tailscale/.rev
Normal file
1
tailscale/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,101 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Configuration
|
||||
DEVICE_FILE="/dev/smd7"
|
||||
ICCID_FILE="/path/to/iccid_master_file" # Path to the ICCID-APN-IPType master file
|
||||
TMP_DIR="/tmp"
|
||||
TIMEOUT=4
|
||||
|
||||
# Start listening to device file
|
||||
start_listening() {
|
||||
cat "$DEVICE_FILE" > "$TMP_DIR/device_readout" &
|
||||
CAT_PID=$!
|
||||
}
|
||||
|
||||
# Send AT command
|
||||
send_at_command() {
|
||||
local command=$1
|
||||
echo -e "${command}\r" > "$DEVICE_FILE"
|
||||
}
|
||||
|
||||
# Wait for and process response
|
||||
wait_for_response() {
|
||||
local start_time=$(date +%s)
|
||||
local current_time
|
||||
local elapsed_time
|
||||
|
||||
while true; do
|
||||
if grep -q "OK" "$TMP_DIR/device_readout" || grep -q "ERROR" "$TMP_DIR/device_readout"; then
|
||||
RESPONSE=$(cat "$TMP_DIR/device_readout")
|
||||
echo "Response received: $RESPONSE"
|
||||
return 0
|
||||
fi
|
||||
current_time=$(date +%s)
|
||||
elapsed_time=$((current_time - start_time))
|
||||
if [ "$elapsed_time" -ge "$TIMEOUT" ]; then
|
||||
echo "Error: Response timed out."
|
||||
return 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
kill "$CAT_PID"
|
||||
wait "$CAT_PID" 2>/dev/null
|
||||
rm -f "$TMP_DIR/device_readout"
|
||||
}
|
||||
|
||||
# Function to send AT command and wait for response
|
||||
send_and_wait() {
|
||||
send_at_command "$1"
|
||||
wait_for_response
|
||||
}
|
||||
|
||||
# Function to update the APN
|
||||
update_apn() {
|
||||
local slot=$1
|
||||
local apn=$2
|
||||
local iptype=$3
|
||||
send_and_wait "AT+CGDCONT=$slot,\"$iptype\",\"$apn\""
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "APN updated successfully."
|
||||
else
|
||||
echo "Failed to update APN."
|
||||
fi
|
||||
}
|
||||
|
||||
# Main Execution
|
||||
if [ -c "$DEVICE_FILE" ]; then
|
||||
start_listening
|
||||
|
||||
# Get ICCID
|
||||
send_and_wait "AT+CCID"
|
||||
ICCID=$(echo "$RESPONSE" | grep "+CCID" | cut -d ':' -f2 | tr -d '[:space:]')
|
||||
echo "ICCID: $ICCID"
|
||||
|
||||
# Check ICCID in master file
|
||||
if grep -q "$ICCID" "$ICCID_FILE"; then
|
||||
APN=$(grep "$ICCID" "$ICCID_FILE" | cut -d ',' -f2)
|
||||
IP_TYPE=$(grep "$ICCID" "$ICCID_FILE" | cut -d ',' -f3)
|
||||
IP_TYPE=${IP_TYPE:-"IPV4V6"} # Default to IPV4V6 if not specified
|
||||
|
||||
# Get current APN settings
|
||||
send_and_wait "AT+CGDCONT?"
|
||||
CURRENT_APN=$(echo "$RESPONSE" | grep "+CGDCONT: 1" | cut -d ',' -f3 | tr -d '"')
|
||||
|
||||
# Compare and update APN if necessary
|
||||
if [ "$APN" != "$CURRENT_APN" ]; then
|
||||
update_apn 1 "$APN" "$IP_TYPE"
|
||||
else
|
||||
echo "No APN update needed."
|
||||
fi
|
||||
else
|
||||
echo "ICCID not found in the master file."
|
||||
fi
|
||||
|
||||
cleanup
|
||||
else
|
||||
echo "Error: Device $DEVICE_FILE does not exist or is not a character special file."
|
||||
fi
|
||||
@@ -1,21 +0,0 @@
|
||||
edit_iccid_file() {
|
||||
local iccid_file="/path/to/iccid_master_file" # Path to the ICCID-APN-IPType master file
|
||||
|
||||
echo "Enter ICCID to add or edit:"
|
||||
read iccid
|
||||
echo "Enter APN for $iccid:"
|
||||
read apn
|
||||
echo "Enter IP Type (IPV4, IPV6, IPV4V6) for $iccid [Default: IPV4V6]:"
|
||||
read iptype
|
||||
iptype=${iptype:-"IPV4V6"} # Default to IPV4V6 if not specified
|
||||
|
||||
# Check if ICCID already exists
|
||||
if grep -q "$iccid" "$iccid_file"; then
|
||||
# Update existing ICCID's APN and IP Type
|
||||
sed -i "/$iccid/c\\$iccid,$apn,$iptype" "$iccid_file"
|
||||
else
|
||||
# Add new ICCID, APN, and IP Type
|
||||
echo "$iccid,$apn,$iptype" >> "$iccid_file"
|
||||
fi
|
||||
echo "ICCID file updated."
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
[Unit]
|
||||
Description=TTYD Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usrdata/ttyd/ttyd -p 443 -t 'theme={"foreground":"white","background":"black"}' -t fontSize=25 --writable /usrdata/ttyd/scripts/ttyd.bash
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user