Edit Install/Uninstall scripts; Update README.md

Edited Install and Uninstall scripts to handle both at_telnet_daemon and simpleadmin
This commit is contained in:
iamromulan
2023-09-20 00:35:38 -04:00
parent a7b156ab4e
commit 7f80364ac0
39 changed files with 132 additions and 7 deletions

View File

@@ -0,0 +1,16 @@
#!/bin/bash
while true; do
# 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 3000 /dev/ttyOUT > /tmp/modemstatus.txt
if [ $? -eq 0 ]
then
# Parse
if [ -f /tmp/modemstatus.txt ]
then
/usrdata/simpleadmin/scripts/modemstatus_parse.sh
fi
fi
sleep 25 # Add a sleep to avoid CPU overload
done

View File

@@ -0,0 +1,31 @@
#!/usrdata/micropython/micropython
# Add the /usrdata/micropython directory to sys.path so we can find the external modules.
# TODO: Move external modules to lib?
# TODO: Recompile Micropython with a syspath set up for our use case.
import sys
# Remove the home directory from sys.path.
if "~/.micropython/lib" in sys.path:
sys.path.remove("~/.micropython/lib")
sys.path.append("/usrdata/micropython")
import serial
import uos
atcmd = sys.argv[1]
ser = serial.Serial("/dev/ttyOUT", baudrate=115200)
ser.write(atcmd + "\r\n")
uos.system("sleep 0.025s")
# wait for an OK
out=r''
while ser.in_waiting > 0:
out += ser.read(1)
if "OK" not in str(out):
print('Error NOT OK')
print(out.decode('utf-8'))
ser.close()

View File

@@ -0,0 +1,470 @@
#!/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
}
if [ ! -f /tmp/modemstatus.txt ]
then
/usrdata/simpleadmin/scripts/get_modem_data.py > /dev/null
fi
# 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-)
PROVIDER=$(echo $QSPN | cut -d, -f1 | tr -d '"')
PROVIDER_ID=$(echo $QSPN | cut -d, -f5 | tr -d '"')
CSQ=$(echo $OX | grep -o "+CSQ: [0-9]\{1,2\}" | grep -o "[0-9]\{1,2\}")
if [ "$CSQ" = "99" ]; then
CSQ=""
fi
if [ -n "$CSQ" ]; then
CSQ_PER=$(($CSQ * 100/31))"%"
CSQ_RSSI=$((2 * CSQ - 113))" dBm"
else
CSQ="-"
CSQ_PER="-"
CSQ_RSSI="-"
fi
NR_NSA=$(echo $OX | grep -o "+QENG:[ ]\?\"NR5G-NSA\",")
NR_SA=$(echo $OX | grep -o "+QENG: \"SERVINGCELL\",[^,]\+,\"NR5G-SA\",\"[DFT]\{3\}\",")
if [ -n "$NR_NSA" ]; then
QENG=",,"$(echo $OX" " | grep -o "+QENG: \"LTE\".\+\"NR5G-NSA\"," | tr " " ",")
if [ -z "$QENG5" ]; then
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\}")
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
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" ] && [ -n "$LBAND" ] && [ "$RSCP" != "-" ] && [ "$ECIO" != "-" ]; then
PCI="$PCI, "$(echo $QENG5 | cut -d, -f4)
SCHV=$(echo $QENG5 | cut -d, -f8)
SLBV=$(echo $QENG5 | cut -d, -f9)
BW=$(echo $QENG5 | cut -d, -f10 | grep -o "[0-9]\{1,3\}")
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
LBAND=$LBAND"<br />nxx (unknown NR5G band)"
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)
BW=$(echo $QENG5 | cut -d, -f12)
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 '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 '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

View File

@@ -0,0 +1,22 @@
#!/bin/bash
# sarav (hello@grity.com)
# convert key=value to json
# Created at Gritfy ( Devops Junction )
#
file_name=$1
last_line=$(wc -l < $file_name)
current_line=0
echo "{"
while read line
do
current_line=$(($current_line + 1))
if [[ $current_line -ne $last_line ]]; then
[ -z "$line" ] && continue
echo $line|awk -F'=' '{ print " \""$1"\" : "$2","}'|grep -iv '\"#'
else
echo $line|awk -F'=' '{ print " \""$1"\" : "$2""}'|grep -iv '\"#'
fi
done < $file_name
echo "}"

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Simpleadmin service to generate status from modem
Requires=socat-smd11.service
[Service]
ExecStart=/usrdata/simpleadmin/scripts/build_modem_status
Restart=always
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,11 @@
[Unit]
Description=SimpleAdmin httpd service
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/httpd -f -h /usrdata/simpleadmin/www -p 8080
ExecStop=/bin/kill -WINCH ${MAINPID}
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,12 @@
[Unit]
Description=TTL Override
After=ql-netd.service
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/usrdata/simpleadmin/ttl/ttl-override start
User=root
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,53 @@
#! /bin/bash
# Adapted from https://github.com/natecarlson/quectel-rgmii-configuration-notes/blob/main/files/ttl-override
# Uses ttlvalue file to read what ttl should be set to
if [ -f /usrdata/simpleadmin/ttl/ttlvalue ];
then
ttlfile=$(</usrdata/simpleadmin/ttl/ttlvalue)
TTLVALUE=$(echo $ttlfile | grep -o "[0-9]\{1,3\}")
if [ -z "${TTLVALUE}" ]; then
echo "Couldnt get proper ttl value from file" >&2
exit 1
fi
else
# Couldnt find ttlvalue file, lets generate one with 0 ttlvalue (0 = disabled)
touch /usrdata/simpleadmin/ttl/ttlvalue && echo '0' > /usrdata/simpleadmin/ttl/ttlvalue
exit 1
fi
case "$1" in
start)
if (( $TTLVALUE > 0 )); then
echo "Adding TTL override rules: "
iptables -t mangle -I POSTROUTING -o rmnet+ -j TTL --ttl-set ${TTLVALUE}
ip6tables -t mangle -I POSTROUTING -o rmnet+ -j HL --hl-set ${TTLVALUE}
else
echo "TTLVALUE set to 0, nothing to do..."
fi
echo "done"
;;
stop)
if (( $TTLVALUE > 0 )); then
echo "Removing TTL override rules: "
iptables -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set ${TTLVALUE} &>/dev/null || true
ip6tables -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set ${TTLVALUE} &>/dev/null || true
else
echo "TTLVALUE set to 0, nothing to do..."
fi
echo "done"
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage ttl-override { start | stop | restart }" >&2
exit 1
;;
esac
exit 0

1
simpleadmin/ttl/ttlvalue Normal file
View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1,123 @@
<!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>Quectel Simple Admin</title>
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css">
<link rel="stylesheet" type="text/css" href="/css/admin.css">
</head>
<body>
<!-- START NAV -->
<nav class="navbar is-white" 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="/">
Home
</a>
<a class="navbar-item" href="/atcommander.html">
ATI Commander
</a>
<a class="navbar-item" href="/ttl.html">
TTL Enabler
</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>
<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>

View File

@@ -0,0 +1,30 @@
#!/bin/bash
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
if [ "${QUERY_STRING}" ]; then
export IFS="&"
for cmd in ${QUERY_STRING}; do
if [ "$(echo $cmd | grep '=')" ]; then
key=$(echo $cmd | awk -F '=' '{print $1}')
value=$(echo $cmd | awk -F '=' '{print $2}')
eval $key=$value
fi
done
fi
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
if [ -n "${MYATCMD}" ]; then
x=$(urldecode "$atcmd")
runcmd=$(echo -en "$x\r\n" | microcom -t 2000 /dev/ttyOUT)
# runcmd=$(/usrdata/simpleadmin/scripts/doAT.py "$MYATCMD")
fi
echo "Content-type: text/plain"
echo $x
echo ""
echo $runcmd

View File

@@ -0,0 +1,13 @@
#!/bin/bash
if [ ! -f /tmp/modemstatus.json ]
then
/usrdata/simpleadmin/scripts/modemstatus_parse.sh > /dev/null
fi
runcmd=$(</tmp/modemstatus.json)
echo "Content-type: text/json"
echo ""
cat <<EOT
$runcmd

View File

@@ -0,0 +1,19 @@
#!/bin/bash
# Check iptables for ttlvalue
ttlvalue=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
ttlenabled=true;
# Set Variables
if [ -z "${ttlvalue}" ]; then
ttlvalue=0
ttlenabled=false
fi
echo "Content-type: text/json"
echo ""
cat <<EOT
{
"isEnabled": $ttlenabled,
"ttl": $ttlvalue
}

View File

@@ -0,0 +1,61 @@
#!/bin/bash
# Get query
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
if [ "${QUERY_STRING}" ]; then
export IFS="&"
for cmd in ${QUERY_STRING}; do
if [ "$(echo $cmd | grep '=')" ]; then
key=$(echo $cmd | awk -F '=' '{print $1}')
value=$(echo $cmd | awk -F '=' '{print $2}')
eval $key=$value
fi
done
fi
setTTL=$(printf '%b\n' "${ttlvalue//%/\\x}")
if [ -n "${setTTL}" ]; then
# Stop Service To Remove Rules
/usrdata/simpleadmin/ttl/ttl-override stop
# Check iptables is still set
ttlcheck=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
# If TTL is still set manually remove values
if [ !-z "${ttlcheck}" ]; then
iptables -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set ${ttlcheck} &>/dev/null || true
ip6tables -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set ${ttlcheck} &>/dev/null || true
fi
# Echo TTL to file
echo $setTTL > /usrdata/simpleadmin/ttl/ttlvalue
# Set Start Service
/usrdata/simpleadmin/ttl/ttl-override start
fi
# Check iptables for ttlvalue
ttlvalue=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}')
ttlenabled=true;
# Set Variables
if [ -z "${ttlvalue}" ]; then
ttlvalue=0
ttlenabled=false
fi
echo "Content-type: text/json"
echo ""
cat <<EOT
{
"isEnabled": $ttlenabled,
"ttl": $ttlvalue
}

View File

@@ -0,0 +1,86 @@
:root{
::-webkit-scrollbar{height:10px;width:10px}::-webkit-scrollbar-track{background:#efefef;border-radius:6px}::-webkit-scrollbar-thumb{background:#d5d5d5;border-radius:6px}::-webkit-scrollbar-thumb:hover{background:#c4c4c4}
}
html, body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
font-size: 16px;
line-height: 1.5;
height: 100%;
background: #ECF0F3;
}
nav.navbar {
border-top: 4px solid #276cda;
margin-bottom: 1rem;
}
.navbar-item.brand-text {
font-weight: 300;
}
.navbar-item, .navbar-link {
font-size: 14px;
font-weight: 700;
}
.columns {
width: 100%;
height: 100%;
margin-left: 0;
}
.menu-label {
color: #8F99A3;
letter-spacing: 1.3;
font-weight: 700;
}
.menu-list a {
color: #0F1D38;
font-size: 14px;
font-weight: 700;
}
.menu-list a:hover {
background-color: transparent;
color: #276cda;
}
.menu-list a.is-active {
background-color: transparent;
color: #276cda;
font-weight: 700;
}
.card {
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.18);
margin-bottom: 2rem;
}
.card-header-title {
color: #8F99A3;
font-weight: 400;
}
.info-tiles {
margin: 1rem 0;
}
.info-tiles .subtitle {
font-weight: 300;
color: #8F99A3;
}
.hero.welcome.is-info {
background: #36D1DC;
background: -webkit-linear-gradient(to right, #5B86E5, #36D1DC);
background: linear-gradient(to right, #5B86E5, #36D1DC);
}
.hero.welcome .title, .hero.welcome .subtitle {
color: hsl(192, 17%, 99%);
}
.card .content {
font-size: 14px;
}
.card-footer-item {
font-size: 14px;
font-weight: 700;
color: #8F99A3;
}
.card-footer-item:hover {
}
.card-table .table {
margin-bottom: 0;
}
.events-card .card-table {
height: 330px;
overflow-y: scroll;
}

1
simpleadmin/www/css/bulma.css vendored Normal file

File diff suppressed because one or more lines are too long

232
simpleadmin/www/index.html Normal file
View File

@@ -0,0 +1,232 @@
<!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>Quectel Simple Admin</title>
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css">
<link rel="stylesheet" type="text/css" href="/css/admin.css">
</head>
<body>
<!-- START NAV -->
<nav class="navbar is-white" 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="/">
Home
</a>
<a class="navbar-item" href="/atcommander.html">
ATI Commander
</a>
<a class="navbar-item" href="/ttl.html">
TTL Enabler
</a>
</div>
</div>
</div>
</nav>
<!-- END NAV -->
<div class="container">
<div class="columns">
<div class="column is-12" x-data="getSignalData()" x-init="init()">
<section class="hero is-info welcome is-small">
<div class="hero-body">
<div class="container">
<h1 class="title">
Welcome to Quectel RJ45 Board Simple Admin
</h1>
<h2 class="subtitle">
Data Updated: <span x-text="lastUpdate"></span>
</h2>
</div>
</div>
</section>
<section class="info-tiles">
<div class="tile is-ancestor has-text-centered">
<div class="tile is-parent">
<article class="tile is-child box">
<p class="title" x-text="csqData.MODE"></p>
<p class="subtitle">Network</p>
</article>
</div>
<div class="tile is-parent">
<article class="tile is-child box">
<p class="title" x-text="csqData.CSQ_PER"></p>
<p class="subtitle">Signal Strength</p>
</article>
</div>
<div class="tile is-parent">
<article class="tile is-child box">
<p class="title" x-text="csqData.TEMP"></p>
<p class="subtitle">Modem Temperature</p>
</article>
</div>
<div class="tile is-parent">
<article class="tile is-child box">
<p class="title" x-html="csqData.LBAND"></p>
<p class="subtitle">Band</p>
</article>
</div>
</div>
</section>
<div class="columns">
<div class="column is-6">
<div class="card events-card">
<header class="card-header">
<p class="card-header-title">
Signal Information
</p>
</header>
<div class="card-table">
<div class="content">
<table class="table is-fullwidth is-striped">
<tbody>
<tr>
<th>Provider</th>
<td x-text="csqData.PROVIDER">
</td>
</tr>
<tr>
<th>CSQ</th>
<td x-text="csqData.CSQ">
</td>
</tr>
<tr>
<th>Signal Strength</th>
<td x-text="csqData.CSQ_PER">
</td>
</tr>
<tr>
<th>RSSI</th>
<td x-text="csqData.CSQ_RSSI">
</td>
</tr>
<tr>
<th>ECIO<sup>3G</sup>/RSRQ<sup>4G</sup>/SS_RSRQ<sup>5G</sup></th>
<td x-html="csqData.ECIO">
</td>
</tr>
<tr>
<th>RSCP<sup>3G</sup>/RSRP<sup>4G</sup>/SS_RSRP<sup>5G</sup></th>
<td x-html="csqData.RSCP">
</td>
</tr>
<tr>
<th>SINR</th>
<td x-html="csqData.SINR">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="column is-6">
<div class="card events-card">
<header class="card-header">
<p class="card-header-title">
Cell Information
</p>
</header>
<div class="card-table">
<div class="content">
<table class="table is-fullwidth is-striped">
<tbody>
<tr>
<th>MCC MNC</th>
<td>
<span x-text="csqData.COPS_MCC"></span>
/
<span x-text="csqData.COPS_MNC"></span>
</td>
</tr>
<tr>
<th>RNC<sup>3G</sup>/eNB ID<sup>4G/5G</sup></th>
<td>
<span x-text="csqData.RNC"></span>
<span x-text="csqData.RNC_NUM"></span>
</td>
</tr>
<tr>
<th>Lag<sup>3G</sup>/TAC<sup>4G/5G</sup></th>
<td>
<span x-text="csqData.LAC"></span>
<span x-text="csqData.LAC_NUM"></span>
</td>
</tr>
<tr>
<th>Cell ID</th>
<td x-text="csqData.CID">
</td>
</tr>
<tr>
<th>Band</th>
<td x-html="csqData.LBAND">
</td>
</tr>
<tr>
<th>Channel</th>
<td x-text="csqData.CHANNEL">
</td>
</tr>
<tr>
<th>PCI</th>
<td x-text="csqData.PCI">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function getSignalData() {
return {
csqData: {},
lastUpdate: new Date().toLocaleString(),
getcsq() {
fetch('/cgi-bin/get_csq')
.then((res) => res.json())
.then((data) => {
this.csqData = data;
this.lastUpdate = new Date(data.LASTUPDATE * 1000).toLocaleString();
});
},
init() {
this.getcsq();
setInterval(() => {
this.getcsq();
}, 30000);
}
}
}
</script>
</body>
</html>

5
simpleadmin/www/js/alpinejs.min.js vendored Normal file

File diff suppressed because one or more lines are too long

134
simpleadmin/www/ttl.html Normal file
View File

@@ -0,0 +1,134 @@
<!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>Quectel Simple Admin</title>
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css">
<link rel="stylesheet" type="text/css" href="/css/admin.css">
</head>
<body>
<!-- START NAV -->
<nav class="navbar is-white" 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="/">
Home
</a>
<a class="navbar-item" href="/atcommander.html">
ATI Commander
</a>
<a class="navbar-item" href="/ttl.html">
TTL Enabler
</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>
</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>