diff --git a/RMxxx_rgmii_toolkit.sh b/RMxxx_rgmii_toolkit_dev.sh similarity index 58% rename from RMxxx_rgmii_toolkit.sh rename to RMxxx_rgmii_toolkit_dev.sh index 6228dd3..c424acf 100644 --- a/RMxxx_rgmii_toolkit.sh +++ b/RMxxx_rgmii_toolkit_dev.sh @@ -1,29 +1,37 @@ #!/bin/sh -# Define paths -USRDATA_DIR="/usrdata" -MICROPYTHON_DIR="/usrdata/micropython" -AT_TELNET_DIR="/usrdata/at-telnet" -AT_TELNET_SYSD_DIR="/usrdata/at-telnet/systemd_units" -AT_TELNET_SMD7_SYSD_DIR="/usrdata/at-telnet/smd7_systemd_units" -SIMPLE_ADMIN_DIR="/usrdata/simpleadmin" +# Define toolkit paths +GITTREE="development" TMP_DIR="/tmp" -GITHUB_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/main.zip" -GITHUB_SIMPADMIN_FULL_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/simpleadminfull.zip" -GITHUB_SIMPADMIN_NOCMD_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/simpleadminnoatcmds.zip" -GITHUB_SIMPADMIN_TTL_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/simpleadminttlonly.zip" -GITHUB_SIMPADMIN_TEST_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/simpleadmintest.zip" -TAILSCALE_DIR="/usrdata/tailscale/" -TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd" +USRDATA_DIR="/usrdata" +SOCAT_AT_DIR="/usrdata/socat-at-bridge" +SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units" +SOCAT_AT_SMD7_SYSD_DIR="/usrdata/socat-at-bridge/smd7_systemd_units" +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/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/$GITTREE.zip" +GITHUB_SIMPADMIN_FULL_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/simpleadminfullatcmds.zip" +GITHUB_SIMPADMIN_TTL_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/simpleadminttlonly.zip" +GITHUB_SIMPADMIN_TEST_URL="https://github.com/iamromulan/quectel-rgmii-toolkit/archive/refs/heads/simpleadmintest.zip" +TAILSCALE_DIR="/usrdata/tailscale/" +TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd" # AT Command Script Variables and Functions DEVICE_FILE="/dev/smd7" TIMEOUT=4 # Set a timeout for the response +# 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 / +} + +# Basic AT commands without socat bridge for fast responce commands only start_listening() { cat "$DEVICE_FILE" > /tmp/device_readout & CAT_PID=$! @@ -93,195 +101,40 @@ send_at_commands() { fi } -# 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 / -} - -# Check if AT Telnet Daemon is installed -is_at_telnet_installed() { - [ -d "$MICROPYTHON_DIR" ] && return 0 || return 1 - [ -d "$AT_TELNET_DIR" ] && return 0 || return 1 -} - -# Function to check if Simple Firewall is installed -is_simple_firewall_installed() { - if [ -d "$SIMPLE_FIREWALL_DIR" ]; then - return 0 - else - return 1 - fi -} - # Check if Simple Admin is installed is_simple_admin_installed() { [ -d "$SIMPLE_ADMIN_DIR" ] && return 0 || return 1 } -# Function to install/update Simple Firewall -install_update_simple_firewall() { - echo "Installing/Updating Simple Firewall..." - mount -o remount,rw / - mkdir -p "$SIMPLE_FIREWALL_DIR" - mkdir -p "$SIMPLE_FIREWALL_SYSTEMD_DIR" - wget -O "$SIMPLE_FIREWALL_SCRIPT" https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/simplefirewall/simplefirewall.sh - chmod +x "$SIMPLE_FIREWALL_SCRIPT" - wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/simplefirewall/systemd/simplefirewall.service - cp -f "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" "$SIMPLE_FIREWALL_SERVICE" - ln -sf "$SIMPLE_FIREWALL_SERVICE" "/lib/systemd/system/multi-user.target.wants/" - systemctl daemon-reload - systemctl restart simplefirewall - mount -o remount,ro / - echo "Simple Firewall installation/update complete." -} - -# Function to uninstall Simple Firewall -uninstall_simple_firewall() { - echo "Uninstalling Simple Firewall..." - mount -o remount,rw / - systemctl stop simplefirewall - rm -f "/lib/systemd/system/multi-user.target.wants/simplefirewall.service" - rm -f "$SIMPLE_FIREWALL_SERVICE" - rm -rf "$SIMPLE_FIREWALL_DIR" - systemctl daemon-reload - mount -o remount,ro / - echo "Simple Firewall uninstalled." -} - -# Function to configure Simple Firewall -configure_simple_firewall() { - if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then - echo "Simple Firewall script not found." - return - fi - - # Extract current ports configuration - 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 "$ports" | awk '{print NR") "$0}' - - while true; do - echo "Enter a port number to add/remove, or type 'done' to finish:" - read port - if [ "$port" = "done" ]; then - break - elif ! echo "$port" | grep -qE '^[0-9]+$'; then - echo "Invalid input: Please enter a numeric value." - elif echo "$ports" | grep -q "^$port\$"; then - # Remove port - ports=$(echo "$ports" | grep -v "^$port\$") - echo "Port $port removed." - else - # Add port - ports=$(echo "$ports"; echo "$port" | grep -o '[0-9]\+') - echo "Port $port added." - fi - done - - # Prepare updated ports line - new_ports_line="PORTS=($(echo "$ports" | tr '\n' ' '))" - - # Update the script with new ports - sed -i "s/$current_ports_line/$new_ports_line/" "$SIMPLE_FIREWALL_SCRIPT" - systemctl restart simplefirewall - echo "Firewall configuration updated." -} - - - - -# Function for Simplefirewall Submenu -simplefirewall_menu() { -while true; do - echo "Simple Firewall Management" - echo "1) Install/Update/Uninstall Simple Firewall" - echo "2) Configure Simple Firewall" - echo "3) Exit" - read -p "Enter your choice: " choice - - case $choice in - 1) - if is_simple_firewall_installed; then - echo "Simple Firewall is already installed." - echo "1) Update Simple Firewall" - echo "2) Uninstall Simple Firewall" - read -p "Enter your choice: " update_uninstall_choice - case $update_uninstall_choice in - 1) install_update_simple_firewall;; - 2) uninstall_simple_firewall;; - *) echo "Invalid option";; - esac - else - install_update_simple_firewall - fi - ;; - 2) - configure_simple_firewall - ;; - 3) - echo "Exiting..." - break - ;; - *) - echo "Invalid option" - ;; - esac -done -} - - -# Function to install/update AT Telnet Daemon -install_update_at_telnet() { +# Function to install/update AT Socat Bridge +install_update_at_socat() { remount_rw - mkdir $MICROPYTHON_DIR - mkdir $AT_TELNET_DIR - cd $MICROPYTHON_DIR - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/errno.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/fcntl.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/ffilib.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/logging.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/micropython - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/os_compat.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/serial.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/stat.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/time.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/micropython/traceback.mpy - cd $AT_TELNET_DIR - mkdir $AT_TELNET_SYSD_DIR - mkdir $AT_TELNET_SMD7_SYSD_DIR - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/modem-multiclient.py - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/picocom + mkdir "$SOCAT_AT_DIR" + cd "$SOCAT_AT_DIR" + mkdir $SOCAT_AT_SYSD_DIR + mkdir $SOCAT_AT_SMD7_SYSD_DIR wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/socat-armel-static cd $AT_TELNET_SYSD_DIR wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/systemd_units/socat-smd11.service - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/systemd_units/at-telnet-daemon.service wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/systemd_units/socat-smd11-from-ttyIN.service wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/systemd_units/socat-smd11-to-ttyIN.service cd $AT_TELNET_SMD7_SYSD_DIR - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/smd7_systemd_units/at-telnet-daemon.service wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/smd7_systemd_units/socat-smd7-from-ttyIN.service wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/smd7_systemd_units/socat-smd7-to-ttyIN.service wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/attelnetdaemon/at-telnet/smd7_systemd_units/socat-smd7.service # Set execute permissions - chmod +x $MICROPYTHON_DIR/micropython - chmod +x $AT_TELNET_DIR/modem-multiclient.py - chmod +x $AT_TELNET_DIR/socat-armel-static - chmod +x $AT_TELNET_DIR/picocom + chmod +x "$SOCAT_AT_DIR"/socat-armel-static # User prompt for selecting device - echo "Which device should AT over Telnet use?" + echo "Which device should Simpleadmin use?" echo "This will create virtual tty ports (serial ports) that will use either smd11 or smd7" echo "1) Use smd11 (default)" - echo "2) Use smd7 (use this if another application is using smd11)" + echo "2) Use smd7 (use this if another application is using smd11 already)" read -p "Enter your choice (1 or 2): " device_choice # Stop and disable existing services before installing new ones + echo -e "\033[0;32mThese errors are OK, script tries to remove all first in case you are updating\033[0m" systemctl stop at-telnet-daemon systemctl disable at-telnet-daemon systemctl stop socat-smd11 @@ -298,7 +151,8 @@ install_update_at_telnet() { rm /lib/systemd/system/socat-smd7-to-ttyIN.service rm /lib/systemd/system/socat-smd7-from-ttyIN.service systemctl daemon-reload - + echo -e "\033[0;32mThese errors are OK, script tries to remove all first in case you are updating\033[0m" + # Depending on the choice, copy the respective systemd unit files case $device_choice in 2) @@ -311,6 +165,7 @@ install_update_at_telnet() { sleep 2s systemctl start socat-smd7-to-ttyIN systemctl start socat-smd7-from-ttyIN + cd / ;; 1) cp -f $AT_TELNET_SYSD_DIR/*.service /lib/systemd/system @@ -322,195 +177,203 @@ install_update_at_telnet() { sleep 2s systemctl start socat-smd11-to-ttyIN systemctl start socat-smd11-from-ttyIN + cd / ;; esac - - - - # User prompt for enabling Telnet server - echo "-Telnet server is not required for simpleadmin" - echo "-Simpleadmin uses the tty port created in the previous step" - echo "-If enabled a telnet server will listen on the gateway address on port 5000" - echo "-It isn't password protceted though so it is recommended to only enable if you need it" - echo "Enable Telnet server?" - echo "1) Yes" - echo "2) No" - read -p "Enter your choice (1 or 2): " telnet_choice - - # Link or remove systemd files based on user choice - if [ "$telnet_choice" = "1" ]; then - ln -sf /lib/systemd/system/at-telnet-daemon.service /lib/systemd/system/multi-user.target.wants/ - - # Start Services - systemctl start at-telnet-daemon - remount_ro - else - remount_ro - fi } -# Function to remove AT Telnet Daemon -remove_at_telnet() { - remount_rw - # Stop and disable all possible services related to AT Telnet Daemon - systemctl stop at-telnet-daemon - systemctl disable at-telnet-daemon - systemctl stop socat-smd11 - systemctl stop socat-smd11-to-ttyIN - systemctl stop socat-smd11-from-ttyIN - systemctl stop socat-smd7 - systemctl stop socat-smd7-to-ttyIN - systemctl stop socat-smd7-from-ttyIN - - # Remove all systemd service files for both smd11 and smd7 configurations - rm /lib/systemd/system/at-telnet-daemon.service - rm /lib/systemd/system/socat-smd11.service - rm /lib/systemd/system/socat-smd11-to-ttyIN.service - rm /lib/systemd/system/socat-smd11-from-ttyIN.service - rm /lib/systemd/system/socat-smd7.service - rm /lib/systemd/system/socat-smd7-to-ttyIN.service - rm /lib/systemd/system/socat-smd7-from-ttyIN.service - - # Reload systemd to apply changes +# Function to install Simple Firewall +install_simple_firewall() { + systemctl stop simplefirewall + systemctl stop ttl-overide + 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/iamromulan/quectel-rgmii-toolkit/$GITTREE/simplefirewall/simplefirewall.sh + wget -O "$SIMPLE_FIREWALL_DIR/ttl-overide" https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttl-overide + wget -O "$SIMPLE_FIREWALL_DIR/ttlvalue" https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/$GITTREE/simplefirewall/ttlvalue + chmod +x "$SIMPLE_FIREWALL_DIR/simplefirewall.sh" + chmod +x "$SIMPLE_FIREWALL_DIR/ttl-overide" + wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/simplefirewall.service + wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/ttl-overide.service" https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/$GITTREE/simplefirewall/systemd/ttl-overide.service + cp -f $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-overide.service" "/lib/systemd/system/multi-user.target.wants/" systemctl daemon-reload - - # Prompt user before removing micropython - echo "Do you want to remove MicroPython?" - echo "1) Yes" - echo "2) No" - read -p "Enter your choice: " choice - - case $choice in - 1 ) - rm -rf $MICROPYTHON_DIR - echo "MicroPython directory removed." - ;; - 2 ) - echo "MicroPython directory not removed." - ;; - * ) - echo "Invalid choice. MicroPython directory not removed." - ;; - esac - - # Remove the AT Telnet Daemon directory - rm -rf $AT_TELNET_DIR + systemctl start simplefirewall + systemctl start ttl-overide remount_ro - echo "AT Telnet Daemon removed successfully." + echo -e "\033[0;32mSimple Firewall installation/update complete.\033[0m" } +configure_simple_firewall() { + if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then + echo "Simple Firewall script not found." + return + fi + + echo "Configuring Simple Firewall:" + echo "1) Configure incoming port block" + echo "2) Configure TTL" + read -p "Enter your choice (1-2): " menu_choice + + case $menu_choice in + 1) + # Original ports configuration code with exit option + 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 "Current configured ports:" + echo "$ports" | awk '{print NR") "$0}' + + while true; do + echo "Enter a port number to add/remove, or type 'done' or 'exit' to finish:" + read port + if [ "$port" = "done" ] || [ "$port" = "exit" ]; then + if [ "$port" = "exit" ]; then + echo "Exiting without making changes..." + return + fi + break + elif ! echo "$port" | grep -qE '^[0-9]+$'; then + echo "Invalid input: Please enter a numeric value." + elif echo "$ports" | grep -q "^$port\$"; then + ports=$(echo "$ports" | grep -v "^$port\$") + echo "Port $port removed." + else + ports=$(echo "$ports"; echo "$port" | grep -o '[0-9]\+') + echo "Port $port added." + 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 + ;; + 2) + # TTL configuration code + ttl_value=$(cat /usrdata/simplefirewall/ttlvalue) + if [ "$ttl_value" -eq 0 ]; then + echo "TTL is not set." + else + echo "TTL value is set to $ttl_value." + fi + + echo "Type 'exit' to cancel." + read -p "What do you want the TTL value to be: " new_ttl_value + if [ "$new_ttl_value" = "exit" ]; then + echo "Exiting TTL configuration..." + return + elif ! echo "$new_ttl_value" | grep -qE '^[0-9]+$'; then + echo "Invalid input: Please enter a numeric value." + return + else + echo "$new_ttl_value" > /usrdata/simplefirewall/ttlvalue + echo "TTL value updated to $new_ttl_value." + fi + ;; + *) + echo "Invalid choice. Please select either 1 or 2." + ;; + esac + + systemctl restart simplefirewall + echo "Firewall configuration updated." +} # Function to install/update Simple Admin -install_update_simple_admin() { +install_simple_admin() { while true; do - echo "Make sure to Install AT Telnet Daemon first. You don't need to Enable the Telnet Server if you don't need it" - echo "What version of Simple Admin do you want to install? This will start a webserver on port 8080" + echo "What version of Simple Admin do you want to install? This will start a webserver on port 8080" echo "1) Full Install" - echo "2) No AT Commands, List only (for use with firmware that already has a web UI)" + echo "2) No AT Commands, List only " echo "3) TTL Only" - echo "4) Install Test Build (work in progress/not ready yet)" + echo "4) Install Test Build (work in progress/not ready yet)" echo "5) Return to Main Menu" echo "Select your choice: " 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/* - chmod +x $SIMPLE_ADMIN_DIR/ttl/ttl-override - cp -f $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/ - ln -sf /lib/systemd/system/ttl-override.service /lib/systemd/system/multi-user.target.wants/ - systemctl start simpleadmin_generate_status systemctl start simpleadmin_httpd - systemctl start ttl-override 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/* - chmod +x $SIMPLE_ADMIN_DIR/ttl/ttl-override - cp -f $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/ - ln -sf /lib/systemd/system/ttl-override.service /lib/systemd/system/multi-user.target.wants/ - systemctl start simpleadmin_generate_status systemctl start simpleadmin_httpd - systemctl start ttl-override remount_ro - echo "Cleaning up..." - rm /tmp/simpleadminnoatcmds.zip - rm -rf /tmp/quectel-rgmii-toolkit-simpleadminnoatcmds/ + 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/* - chmod +x $SIMPLE_ADMIN_DIR/ttl/ttl-override - + chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/* cp -f $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/ttl-override.service /lib/systemd/system/multi-user.target.wants/ - systemctl start simpleadmin_httpd - systemctl start ttl-override remount_ro - echo "Cleaning up..." - rm /tmp/simpleadminttlonly.zip - rm -rf /tmp/quectel-rgmii-toolkit-simpleadminttlonly/ + echo "Cleaning up..." + rm /tmp/simpleadminttlonly.zip + rm -rf /tmp/quectel-rgmii-toolkit-simpleadminttlonly/ break ;; 4) - remount_rw + install_update_at_socat + install_simple_firewall + remount_rw cd $TMP_DIR - wget $GITHUB_SIMPADMIN_TEST_URL -O simpleadmintest.zip + wget $GITHUB_SIMPADMIN_FULL_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/* - chmod +x $SIMPLE_ADMIN_DIR/ttl/ttl-override - cp -f $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/ - ln -sf /lib/systemd/system/ttl-override.service /lib/systemd/system/multi-user.target.wants/ - systemctl start simpleadmin_generate_status systemctl start simpleadmin_httpd - systemctl start ttl-override remount_ro break ;; @@ -525,23 +388,70 @@ install_update_simple_admin() { done } +# Function to Uninstall Simpleadmin and dependencies +uninstall_simpleadmin_components() { + echo "Starting the uninstallation process for Simpleadmin components." + echo "Note: Uninstalling certain components may affect the functionality of others." + # Uninstall Simple Firewall + echo "Do you want to uninstall Simplefirewall?" + echo "If you do, the TTL part of simpleadmin will no longer work." + echo "1) Yes" + echo "2) No" + read -p "Enter your choice (1 or 2): " choice_simplefirewall + if [ "$choice_simplefirewall" -eq 1 ]; then + echo "Uninstalling Simplefirewall..." + systemctl stop simplefirewall + systemctl stop ttl-overide + rm -f /lib/systemd/system/simplefirewall.service + rm -f /lib/systemd/system/ttl-overide.service + systemctl daemon-reload + rm -rf "$SIMPLE_FIREWALL_DIR" + echo "Simplefirewall uninstalled." + fi -# Function to remove Simple Admin -remove_simple_admin() { - remount_rw - systemctl stop simpleadmin_generate_status - systemctl stop ttl-override - systemctl stop simpleadmin_httpd - systemctl disable simpleadmin_httpd - systemctl disable ttl-override - systemctl disable simpleadmin_httpd - rm -rf $SIMPLE_ADMIN_DIR - rm /lib/systemd/system/simpleadmin_httpd.service - rm /lib/systemd/system/simpleadmin_generate_status.service - rm /lib/systemd/system/ttl-override.service - systemctl daemon-reload - remount_ro + # Uninstall socat-at-bridge + echo "Do you want to uninstall socat-at-bridge?" + echo "If you do, AT commands and the stat page will no longer work." + echo "1) Yes" + echo "2) No" + read -p "Enter your choice (1 or 2): " choice_socat_at_bridge + if [ "$choice_socat_at_bridge" -eq 1 ]; then + echo "Uninstalling socat-at-bridge..." + systemctl stop socat-smd11 + systemctl stop socat-smd11-to-ttyIN + systemctl stop socat-smd11-from-ttyIN + systemctl stop socat-smd7 + systemctl stop socat-smd7-to-ttyIN + systemctl stop socat-smd7-from-ttyIN + rm -f /lib/systemd/system/socat-smd11.service + rm -f /lib/systemd/system/socat-smd11-to-ttyIN.service + rm -f /lib/systemd/system/socat-smd11-from-ttyIN.service + rm -f /lib/systemd/system/socat-smd7.service + rm -f /lib/systemd/system/socat-smd7-to-ttyIN.service + rm -f /lib/systemd/system/socat-smd7-from-ttyIN.service + systemctl daemon-reload + rm -rf "$SOCAT_AT_DIR" + echo "socat-at-bridge uninstalled." + fi + + # Uninstall the rest of Simpleadmin + echo "Do you want to uninstall the rest of Simpleadmin?" + echo "1) Yes" + echo "2) No" + 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." + fi + + echo "Uninstallation process completed." } # Function for Tailscale Submenu @@ -572,41 +482,12 @@ install_update_remove_tailscale() { case $tailscale_update_remove_choice in 1) - echo "Updating Tailscale..." - remount_rw - $TAILSCALE_DIR/tailscale down - $TAILSCALE_DIR/tailscale logout - systemctl stop tailscaled - # Follow the installation steps with force overwrite - echo "Downloading the latest Tailscale binaries..." - wget -O $TAILSCALE_DIR/tailscaled https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/tailscaled - wget -O $TAILSCALE_DIR/tailscale https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/tailscale - - echo "Setting permissions for the new binaries..." - chmod +x $TAILSCALE_DIR/tailscaled - chmod +x $TAILSCALE_DIR/tailscale - - echo "Downloading the latest systemd files..." - wget -O $TAILSCALE_SYSD_DIR/tailscaled.service https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.service - wget -O $TAILSCALE_SYSD_DIR/tailscaled.defaults https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.defaults - - echo "Copying the new systemd units..." - cp -f $TAILSCALE_SYSD_DIR/* /lib/systemd/system - systemctl daemon-reload - - echo "Restarting Tailscaled service..." - systemctl restart tailscaled - - echo "Tailscale updated successfully." - - remount_ro - echo "Tailscale updated successfully." - echo "You will need to reconnect and Log back in" - read -p "Press Enter to continue..." + echo "Updating Tailscale..." + /usrdata/tailscale/tailscale update ;; 2) echo "Removing Tailscale..." - remount_rw + remount_rw $TAILSCALE_DIR/tailscale down $TAILSCALE_DIR/tailscale logout systemctl stop tailscaled @@ -623,82 +504,81 @@ install_update_remove_tailscale() { else echo "Installing Tailscale..." remount_rw - echo "Creating /usrdata/tailscale/" - mkdir $TAILSCALE_DIR - mkdir $TAILSCALE_SYSD_DIR + echo "Creating /usrdata/tailscale/" + mkdir $TAILSCALE_DIR + mkdir $TAILSCALE_SYSD_DIR cd $TAILSCALE_DIR - echo "Downloading binary: /usrdata/tailscale/tailscaled" + echo "Downloading binary: /usrdata/tailscale/tailscaled" wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/tailscaled - echo "Downloading binary: /usrdata/tailscale/tailscale" - wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/tailscale + echo "Downloading binary: /usrdata/tailscale/tailscale" + wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/tailscale echo "Downloading systemd files..." cd $TAILSCALE_SYSD_DIR wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.service wget https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/systemd/tailscaled.defaults - sleep 2s - echo "Setting Permissions..." + sleep 2s + echo "Setting Permissions..." chmod +x /usrdata/tailscale/tailscaled chmod +x /usrdata/tailscale/tailscale - echo "Copy systemd units..." + echo "Copy systemd units..." cp -f /usrdata/tailscale/systemd/* /lib/systemd/system - ln -sf /lib/systemd/system/tailscaled.service /lib/systemd/system/multi-user.target.wants/ + ln -sf /lib/systemd/system/tailscaled.service /lib/systemd/system/multi-user.target.wants/ systemctl daemon-reload - echo "Starting Tailscaled..." + echo "Starting Tailscaled..." systemctl start tailscaled - cd / + cd / remount_ro echo "Tailscale installed successfully." fi } - # Function to Configure Tailscale configure_tailscale() { while true; do - echo "Configure Tailscale" - echo "1) Enable Tailscale Web UI at http://192.168.225.1:8088 (Gateway on port 8088)" + echo "Configure Tailscale" + echo "1) Enable Tailscale Web UI at http://192.168.225.1:8088 (Gateway on port 8088)" echo "2) Disable Tailscale Web UI" echo "3) Connect to Tailnet" - echo "4) Connect to Tailnet with SSH ON" - echo "5) Connect to Tailnet with SSH OFF (reset flag)" + echo "4) Connect to Tailnet with SSH ON" + echo "5) Reconnect to Tailnet with SSH OFF" echo "6) Disconnect from Tailnet (reconnects at reboot)" - echo "7) Logout from tailscale account" + echo "7) Logout from tailscale account" echo "8) Return to Tailscale Menu" read -p "Enter your choice: " config_choice case $config_choice in - 1) + 1) remount_rw cd /lib/systemd/system/ wget -O tailscale-webui.service https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/tailscale/systemd/tailscale-webui.service wget -O tailscale-webui-trigger.service https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/main/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" + ln -sf /lib/systemd/system/tailscale-webui-trigger.service /lib/systemd/system/multi-user.target.wants/ + systemctl daemon-reload + echo "Tailscale Web UI Enabled" echo "Starting Web UI..." - systemctl start tailscale-webui - echo "Web UI started!" - remount_ro + systemctl start tailscale-webui + echo "Web UI started!" + remount_ro ;; 2) remount_rw systemctl stop tailscale-webui - systemctl disable tailscale-webui-trigger + systemctl disable tailscale-webui-trigger rm /lib/systemd/system/multi-user.target.wants/tailscale-webui.service - rm /lib/systemd/system/multi-user.target.wants/tailscale-webui-trigger.service - rm /lib/systemd/system/tailscale-webui.service - rm /lib/systemd/system/tailscale-webui-trigger.service - systemctl daemon-reload - echo "Tailscale Web UI Stopped and Disabled" - remount_ro + rm /lib/systemd/system/multi-user.target.wants/tailscale-webui-trigger.service + rm /lib/systemd/system/tailscale-webui.service + rm /lib/systemd/system/tailscale-webui-trigger.service + systemctl daemon-reload + echo "Tailscale Web UI Stopped and Disabled" + remount_ro ;; - 3) $TAILSCALE_DIR/tailscale up;; - 4) $TAILSCALE_DIR/tailscale up --ssh;; - 5) $TAILSCALE_DIR/tailscale up --reset;; - 6) $TAILSCALE_DIR/tailscale down;; - 7) $TAILSCALE_DIR/tailscale logout;; - 8) break;; - *) echo "Invalid option";; + 3) $TAILSCALE_DIR/tailscale up --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;; + 8) break;; + *) echo "Invalid option";; esac done } @@ -773,7 +653,7 @@ manage_reboot_timer() { mount -o remount,ro / } -# Function to create systemd service and timer files with the user-specified time +# Function to create systemd service and timer files with the user-specified time for the reboot timer create_service_and_timer() { remount_rw # Define the path for the modem reboot script @@ -880,20 +760,17 @@ WantedBy=multi-user.target" > "$cfun_service_path" fi } - - # Main menu while true; do echo "Welcome to iamromulan's RGMII Toolkit script for Quectel RMxxx Series modems!" echo "Select an option:" echo "1) Send AT Commands" - echo "2) Install/Update/Uninstall or Configure Simple Firewall" - echo "3) Install/Update or remove AT Telnet Daemon" - echo "4) Install/Update or remove Simple Admin" - echo "5) Tailscale Management" - echo "6) Install/Change or remove Daily Reboot Timer" - echo "7) Install/Uninstall CFUN 0 Fix" - echo "8) Exit" + echo "2) Install/Update/Uninstall Simple Admin" + echo "3) Simple Firewall Management" + echo "4) Tailscale Management" + echo "5) Install/Change or remove Daily Reboot Timer" + echo "6) Install/Uninstall CFUN 0 Fix" + echo "7) Exit" read -p "Enter your choice: " choice case $choice in @@ -901,53 +778,38 @@ while true; do send_at_commands ;; 2) - simplefirewall_menu - ;; - 3) - if is_at_telnet_installed; then - echo "AT Telnet Daemon is already installed." - echo "1) Update" - echo "2) Remove" - read -p "Enter your choice: " at_telnet_choice - case $at_telnet_choice in - 1) install_update_at_telnet;; - 2) remove_at_telnet;; - *) echo "Invalid option";; - esac - else - echo "Installing AT Telnet Daemon..." - install_update_at_telnet - fi - ;; - 4) if is_simple_admin_installed; then - echo "Simple Admin is already installed." - echo "1) Update" - echo "2) Remove" + echo "Simple Admin is already installed. It must be removed first" + echo "1) Remove" + echo "2) Return to main menu" read -p "Enter your choice: " simple_admin_choice case $simple_admin_choice in - 1) install_update_simple_admin;; - 2) remove_simple_admin;; + 1) uninstall_simpleadmin_components;; + 2) break;; *) echo "Invalid option";; esac else echo "Installing Simple Admin..." - install_update_simple_admin + install_simple_admin fi ;; - 5) - tailscale_menu - ;; - 6) + 3) + configure_simple_firewall + ;; + + 4) + tailscale_menu + ;; + 5) manage_reboot_timer ;; - 7) + 6) manage_cfun_fix ;; - 8) - echo "Goodbye!" + 7) + echo "Goodbye!" break - ;; + ;; *) echo "Invalid option" ;; diff --git a/attelnetdaemon/at-telnet/modem-multiclient.py b/attelnetdaemon/at-telnet/modem-multiclient.py deleted file mode 100644 index 7f648e9..0000000 --- a/attelnetdaemon/at-telnet/modem-multiclient.py +++ /dev/null @@ -1,281 +0,0 @@ -#!/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/lib") -sys.path.append("/usrdata/micropython") - -import uos -import usocket as socket -import _thread as thread -import serial -import select -import traceback -import logging -import re -import time - -# Set up logging -logging.basicConfig(level=logging.INFO, format='[%(asctime)s: %(levelname)s/%(msecs)ims] %(message)s', datefmt='%Y-%m-%d %H:%M:%S') -# Globally define client_sockets and serialport. That way, we can access them from handle_output and make it a separate thread, so responses (and unsolicited responses) can come in while we're waiting for input. -global client_sockets, serialport -client_sockets = [] -# We are referencing one of the two ports exposed by our socat command. The other one is /dev/ttyIN, and two running "cat" commands are keeping it sync'd with /dev/smd11. -serialport = serial.Serial("/dev/ttyOUT", baudrate=115200) - -# These will be set in the main routine. -global firewall_is_setup, fwpublicinterface, port -firewall_is_setup = 0 - -# Make these configurable via /etc/default or similar -port = 5000 -fwpublicinterface = "rmnet+" - -# Block access to port 5000 via ipv4 and ipv6 on public-facing interfaces. -def add_firewll_rules(port=port, fwpublicinterface=fwpublicinterface): - if not port or not fwpublicinterface: - logging.error(f"Port or fwpublicinterface not set. Values: fwpublicinterface: {fwpublicinterface} port: {port}") - exit(1) - - logging.info(f"Adding firewall rules for port {port} on interface {fwpublicinterface}.") - - # Check if the rule already exists in iptables - iptables_check_cmd = f"iptables -C INPUT -i {fwpublicinterface} -p tcp --dport {port} -j REJECT &> /dev/null" - iptables_check_result = uos.system(iptables_check_cmd) - if iptables_check_result != 0: - # Rule doesn't exist, add it to iptables - iptables_add_cmd = f"iptables -A INPUT -i {fwpublicinterface} -p tcp --dport {port} -j REJECT" - iptables_add_result = uos.system(iptables_add_cmd) - if iptables_add_result: - logging.error(f"ERROR: Failed to add iptables rule - input interface {fwpublicinterface} port {port}") - # Treat this as fatal. - sys.exit(1) - else: - logging.debug(f"Added iptables rule - input interface {fwpublicinterface} port {port}") - - # Check if the rule already exists in ip6tables - ip6tables_check_cmd = f"ip6tables -C INPUT -i {fwpublicinterface} -p tcp --dport {port} -j REJECT &> /dev/null" - ip6tables_check_result = uos.system(ip6tables_check_cmd) - if ip6tables_check_result != 0: - # Rule doesn't exist, add it to ip6tables - ip6tables_add_cmd = f"ip6tables -A INPUT -i {fwpublicinterface} -p tcp --dport {port} -j REJECT" - ip6tables_add_result = uos.system(ip6tables_add_cmd) - if ip6tables_add_result: - logging.error(f"ERROR: Failed to add ip6tables rule - input interface {fwpublicinterface} port {port}") - # Treat this as fatal. - sys.exit(1) - else: - logging.debug(f"Added ip6tables rule - input interface {fwpublicinterface} port {port}") - - global firewall_is_setup - firewall_is_setup = 1 - - logging.info(f"Successfully firewall rules for port {port} on interface {fwpublicinterface}.") - - -def remove_firewall_rules(port=port, fwpublicinterface=fwpublicinterface): - if firewall_is_setup: - iptables_del_cmd = f"iptables -D INPUT -i {fwpublicinterface} -p tcp --dport {port} -j REJECT" - ip6tables_del_cmd = f"ip6tables -D INPUT -i {fwpublicinterface} -p tcp --dport {port} -j REJECT" - iptables_del_result = uos.system(iptables_del_cmd) - ip6tables_del_result = uos.system(ip6tables_del_cmd) - - if iptables_del_result or ip6tables_del_result: - logging.error(f"ERROR: Failed to remove iptables or ip6tables rule - input interface {fwpublicinterface} port {port}") - else: - logging.info(f"Removed iptables and ip6tables rule - input interface {fwpublicinterface} port {port}") - - else: - logging.info(f"Firewall rules not set up; not removing.") - -# This routine pulls data from the serial port and sends it to all connected clients. -def handle_output(): - while True: - # Make data an empty bytes list - data = b'' - - try: - while serialport.in_waiting > 0: - data += serialport.read(1) - except Exception as e: - # This will keep trying. - print(f"Exception reading data from serialport: {e}") - traceback.print_exc() - - if data: - logging.info(f"Got data from modem: {data}") - for client_socket in client_sockets: - client_socket.send(data) - -# Start the server on the specified port, listen for clients, etc. -def start_at_server(port): - - # Server initialization stuff - # NOTE: This now supports IPv6. And means that on many connections it'll be directly exposed - # to the internet. So we're adding firewall rules to block access to it via rmnet+. - try: - server_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) - server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - addr_info = socket.getaddrinfo("::", port) - addr = addr_info[0][4] - server_socket.bind(addr) - server_socket.listen(1) - - logging.info(f"AT Server listening on TCP port {port}") - - # Disable echo so user doesn't see a second copy of all their commands. - serialport.write("ATE0\r\n") - # time.sleep() segfaults?! ugh. - uos.system("sleep 0.025s") - # wait for an OK - out=b'' - while serialport.in_waiting > 0: - out += serialport.read(1) - - if "OK" not in str(out): - logging.warning(f"Did not get expected OK when running ATE0. Result: {str(out)}") - - except Exception as e: - logging.error(f"Error initializing server: {e}") - traceback.print_exc() - raise - - # Start the output handler in its own thread - try: - thread.start_new_thread(handle_output, ()) - except Exception as e: - print("Error with output handler:", e) - traceback.print_exc() - raise - - # Set up a select.poll object to listen for input from the server socket and all client sockets. - # Logic mostly from https://pymotw.com/2/select/ - try: - poll_obj = select.poll() - poll_obj.register(server_socket, select.POLLIN) - - # Register the server socket in the fd_to_socket dict; this will also be used to register the rest of the clients. - fd_to_socket = { server_socket.fileno(): server_socket, - } - - while True: - events = poll_obj.poll() - - for fd, flag in events: - logging.debug(f"Pool loop event. fd: {fd} flag: {flag} fd_to_socket.keys(): {fd_to_socket.keys()}") - - # Check if the client already exists in the fd_to_socket dict. - if fd.fileno() in fd_to_socket.keys(): - s = fd_to_socket[fd.fileno()] - logging.debug("Event matches existing socket.") - else: - s = fd - logging.debug(f"Event doesn't match existing socket. fd: {fd} fd_to_socket: {fd_to_socket}") - - # If the flag is POLLIN, then we have data to process. - if flag & (select.POLLIN): - # If the server socket is ready to read, then we have a new client connection. - if s is server_socket: - # Accept the connection. - client_socket, client_address = s.accept() - # TODO: This gives a garbled IP. Figure it out. - #client_address_translated = socket.inet_ntop(socket.AF_INET, client_address) - logging.info(f"New connection") - - # Set the client socket to non-blocking, and add it to the list of client sockets. - # TODO: trim down to just storing one copy of the client sockets.. - client_socket.setblocking(0) - fd_to_socket[ client_socket.fileno() ] = client_socket - client_sockets.append(client_socket) - poll_obj.register(client_socket, select.POLLIN) - - # Send a good 'ol hello message to the client. - client_socket.send("** Welcome to the AT server!\r\n".encode()) - client_socket.send("** Note that your commands are interleaved with any other connected clients,\r\n** so responses may appear out of order.\r\n".encode()) - client_socket.send("** \r\n".encode()) - client_socket.send("** You may also receive unsolicited responses (URC's) depending on the\r\n** modem configuration.\r\n".encode()) - client_socket.send("** \r\n".encode()) - client_socket.send("** Echo is off (ATE0); if you change it you'll see what you've typed both\r\n** locally and echo'd back.\r\n".encode()) - client_socket.send("** \r\n".encode()) - client_socket.send("** I have tested this with telnet.netkit and netcat on Linux. If your client\r\n** doesn't work,\r\n** please open an issue at:\r\n** https://github.com/natecarlson/quectel-rgmii-at-command-client/ **\r\n".encode()) - client_socket.send("**\r\n".encode()) - client_socket.send("** If you would like to support further development, you can at:\r\n** https://www.buymeacoffee.com/natecarlson **\r\n".encode()) - client_socket.send("\r\n".encode()) - - - # Otherwise, we have data from a client socket. - else: - data = s.recv(1024) - logging.info(f"Got data from client: {data}") - if data: - # Ensure it ends with \r\n - if not data.endswith("\r\n"): - # Just stripping \n for now; add others in the future if needed. - data = re.sub(b"\n$", "", data) + "\r\n" - logging.info(f"Modified client data to end with \\r\\n: {data}") - - # Good client data; write out to the serial port. - serialport.write(data) - # Write out out to the rest of the clients too - for fd in fd_to_socket.keys(): - if fd != server_socket.fileno() and fd != s.fileno(): - logging.debug(f"Writing data to other connected client: {data}") - try: - fd_to_socket[fd].send(data) - except Exception as e: - logging.info(f"Failed to write data to an additional client. Ignorning. Result: {e}") - pass - else: - # Client disconnected - print("Client disconnected") - client_sockets.remove(s) - poll_obj.unregister(s) - del fd_to_socket[s.fileno()] - s.close() - - # Not sure if this can happen. But , if it does, we should close the socket. - elif flag & select.POLLERR: - logging.warn(f"Strange connection issue with a client; closing.") - # Stop listening for input on the connection - poll_obj.unregister(s) - client_sockets.remove(s) - del fd_to_socket[s.fileno()] - s.close() - - # TODO: I don't believe we need this here, since the output is now handled in its own thread. - #uos.system("sleep 0.025s") - - except Exception as e: - print("Error after server initialization:", e) - serialport.write("ATE1\r\n") - traceback.print_exc() - # I believe this will drop out of the while loop, so we'll close the sockets and exit. - - # Close client sockets and server socket - for client_socket in client_sockets: - client_socket.close() - - server_socket.close() - -# TODO: By using the dict, we shouldn't need this code. Clean it up. -#def fd_to_socket(fd, client_sockets): -# for client_socket in client_sockets: -# if client_socket.fileno() == fd: -# return client_socket -# return None - -# App startup. TODO: Make the port configurable. -if __name__ == "__main__": - # Register an atexit handler to remove the firewall rules. - sys.atexit(remove_firewall_rules) - - # Add the firewall rules before starting anything - add_firewll_rules(port=port, fwpublicinterface=fwpublicinterface) - - # Light 'er up! - start_at_server(port) diff --git a/attelnetdaemon/at-telnet/picocom b/attelnetdaemon/at-telnet/picocom deleted file mode 100644 index 85c9d34..0000000 Binary files a/attelnetdaemon/at-telnet/picocom and /dev/null differ diff --git a/attelnetdaemon/at-telnet/smd7_systemd_units/at-telnet-daemon.service b/attelnetdaemon/at-telnet/smd7_systemd_units/at-telnet-daemon.service deleted file mode 100644 index 23f5c3e..0000000 --- a/attelnetdaemon/at-telnet/smd7_systemd_units/at-telnet-daemon.service +++ /dev/null @@ -1,21 +0,0 @@ -[Unit] -Description=Telnet daemon for AT command smd7 - -After=socat-smd7.service -Requires=socat-smd7.service socat-smd7-from-ttyIN.service socat-smd7-to-ttyIN.service -ReloadPropagatedFrom=socat-smd7.service socat-smd7-from-ttyIN.service socat-smd7-to-ttyIN.service - -StartLimitIntervalSec=2m -StartLimitBurst=100 - -[Service] -ExecStart=/usrdata/at-telnet/modem-multiclient.py -Nice=5 -Restart=always -RestartSec=2s -# Increased log rate limits, so we can see what's going on. -LogRateLimitIntervalSec=5s -LogRateLimitBurst=100 - -[Install] -WantedBy=multi-user.target diff --git a/attelnetdaemon/at-telnet/systemd_units/at-telnet-daemon.service b/attelnetdaemon/at-telnet/systemd_units/at-telnet-daemon.service deleted file mode 100644 index 5765326..0000000 --- a/attelnetdaemon/at-telnet/systemd_units/at-telnet-daemon.service +++ /dev/null @@ -1,25 +0,0 @@ -[Unit] -Description=Telnet daemon for AT command - -# Being extra silly with the dependencies for this. -# TODO: Update the python code to validate that the serial port -# is working on a regular basis, and keep attempting to retry -# if not. Then these dependencies won't need to be so strict. -After=socat-smd11.service -Requires=socat-smd11.service socat-smd11-from-ttyIN.service socat-smd11-to-ttyIN.service -ReloadPropagatedFrom=socat-smd11.service socat-smd11-from-ttyIN.service socat-smd11-to-ttyIN.service - -StartLimitIntervalSec=2m -StartLimitBurst=100 - -[Service] -ExecStart=/usrdata/at-telnet/modem-multiclient.py -Nice=5 -Restart=always -RestartSec=2s -# Increased log rate limits, so we can see what's going on. -LogRateLimitIntervalSec=5s -LogRateLimitBurst=100 - -[Install] -WantedBy=multi-user.target diff --git a/attelnetdaemon/micropython/errno.py b/attelnetdaemon/micropython/errno.py deleted file mode 100644 index 05441b6..0000000 --- a/attelnetdaemon/micropython/errno.py +++ /dev/null @@ -1,38 +0,0 @@ -EPERM = 1 # Operation not permitted -ENOENT = 2 # No such file or directory -ESRCH = 3 # No such process -EINTR = 4 # Interrupted system call -EIO = 5 # I/O error -ENXIO = 6 # No such device or address -E2BIG = 7 # Argument list too long -ENOEXEC = 8 # Exec format error -EBADF = 9 # Bad file number -ECHILD = 10 # No child processes -EAGAIN = 11 # Try again -ENOMEM = 12 # Out of memory -EACCES = 13 # Permission denied -EFAULT = 14 # Bad address -ENOTBLK = 15 # Block device required -EBUSY = 16 # Device or resource busy -EEXIST = 17 # File exists -EXDEV = 18 # Cross-device link -ENODEV = 19 # No such device -ENOTDIR = 20 # Not a directory -EISDIR = 21 # Is a directory -EINVAL = 22 # Invalid argument -ENFILE = 23 # File table overflow -EMFILE = 24 # Too many open files -ENOTTY = 25 # Not a typewriter -ETXTBSY = 26 # Text file busy -EFBIG = 27 # File too large -ENOSPC = 28 # No space left on device -ESPIPE = 29 # Illegal seek -EROFS = 30 # Read-only file system -EMLINK = 31 # Too many links -EPIPE = 32 # Broken pipe -EDOM = 33 # Math argument out of domain of func -ERANGE = 34 # Math result not representable -EAFNOSUPPORT = 97 # Address family not supported by protocol -ECONNRESET = 104 # Connection timed out -ETIMEDOUT = 110 # Connection timed out -EINPROGRESS = 115 # Operation now in progress diff --git a/attelnetdaemon/micropython/fcntl.py b/attelnetdaemon/micropython/fcntl.py deleted file mode 100644 index 1559029..0000000 --- a/attelnetdaemon/micropython/fcntl.py +++ /dev/null @@ -1,36 +0,0 @@ -import ffi -import os_compat as os -import ffilib - -libc = ffilib.libc() - -fcntl_l = libc.func("i", "fcntl", "iil") -fcntl_s = libc.func("i", "fcntl", "iip") -ioctl_l = libc.func("i", "ioctl", "iil") -ioctl_s = libc.func("i", "ioctl", "iip") - - -def fcntl(fd, op, arg=0): - if type(arg) is int: - r = fcntl_l(fd, op, arg) - os.check_error(r) - return r - else: - r = fcntl_s(fd, op, arg) - os.check_error(r) - # TODO: Not compliant. CPython says that arg should be immutable, - # and possibly mutated buffer is returned. - return r - - -def ioctl(fd, op, arg=0, mut=False): - if type(arg) is int: - r = ioctl_l(fd, op, arg) - os.check_error(r) - return r - else: - # TODO - assert mut - r = ioctl_s(fd, op, arg) - os.check_error(r) - return r diff --git a/attelnetdaemon/micropython/ffilib.py b/attelnetdaemon/micropython/ffilib.py deleted file mode 100644 index 62fad09..0000000 --- a/attelnetdaemon/micropython/ffilib.py +++ /dev/null @@ -1,51 +0,0 @@ -import sys -try: - import ffi -except ImportError: - ffi = None - -_cache = {} - - -def open(name, maxver=10, extra=()): - if not ffi: - return None - try: - return _cache[name] - except KeyError: - pass - - def libs(): - if sys.platform == "linux": - yield '%s.so' % name - for i in range(maxver, -1, -1): - yield '%s.so.%u' % (name, i) - else: - for ext in ('dylib', 'dll'): - yield '%s.%s' % (name, ext) - for n in extra: - yield n - - err = None - for n in libs(): - try: - l = ffi.open(n) - _cache[name] = l - return l - except OSError as e: - err = e - raise err - - -def libc(): - return open("libc", 6) - - -# Find out bitness of the platform, even if long ints are not supported -# TODO: All bitness differences should be removed from micropython-lib, and -# this snippet too. -bitness = 1 -v = sys.maxsize -while v: - bitness += 1 - v >>= 1 diff --git a/attelnetdaemon/micropython/logging.py b/attelnetdaemon/micropython/logging.py deleted file mode 100644 index 1a56684..0000000 --- a/attelnetdaemon/micropython/logging.py +++ /dev/null @@ -1,245 +0,0 @@ -from micropython import const - -import sys -import time - -CRITICAL = const(50) -ERROR = const(40) -WARNING = const(30) -INFO = const(20) -DEBUG = const(10) -NOTSET = const(0) - -_DEFAULT_LEVEL = const(WARNING) - -_level_dict = { - CRITICAL: "CRITICAL", - ERROR: "ERROR", - WARNING: "WARNING", - INFO: "INFO", - DEBUG: "DEBUG", - NOTSET: "NOTSET", -} - -_loggers = {} -_stream = sys.stderr -_default_fmt = "%(levelname)s:%(name)s:%(message)s" -_default_datefmt = "%Y-%m-%d %H:%M:%S" - - -class LogRecord: - def set(self, name, level, message): - self.name = name - self.levelno = level - self.levelname = _level_dict[level] - self.message = message - self.ct = time.time() - self.msecs = int((self.ct - int(self.ct)) * 1000) - self.asctime = None - - -class Handler: - def __init__(self, level=NOTSET): - self.level = level - self.formatter = None - - def close(self): - pass - - def setLevel(self, level): - self.level = level - - def setFormatter(self, formatter): - self.formatter = formatter - - def format(self, record): - return self.formatter.format(record) - - -class StreamHandler(Handler): - def __init__(self, stream=None): - self.stream = _stream if stream is None else stream - self.terminator = "\n" - - def close(self): - if hasattr(self.stream, "flush"): - self.stream.flush() - - def emit(self, record): - if record.levelno >= self.level: - self.stream.write(self.format(record) + self.terminator) - - -class FileHandler(StreamHandler): - def __init__(self, filename, mode="a", encoding="UTF-8"): - super().__init__(stream=open(filename, mode=mode, encoding=encoding)) - - def close(self): - super().close() - self.stream.close() - - -class Formatter: - def __init__(self, fmt=None, datefmt=None): - self.fmt = _default_fmt if fmt is None else fmt - self.datefmt = _default_datefmt if datefmt is None else datefmt - - def usesTime(self): - return "asctime" in self.fmt - - def formatTime(self, datefmt, record): - if hasattr(time, "strftime"): - return time.strftime(datefmt, time.localtime(record.ct)) - return None - - def format(self, record): - if self.usesTime(): - record.asctime = self.formatTime(self.datefmt, record) - return self.fmt % { - "name": record.name, - "message": record.message, - "msecs": record.msecs, - "asctime": record.asctime, - "levelname": record.levelname, - } - - -class Logger: - def __init__(self, name, level=NOTSET): - self.name = name - self.level = level - self.handlers = [] - self.record = LogRecord() - - def setLevel(self, level): - self.level = level - - def isEnabledFor(self, level): - return level >= self.getEffectiveLevel() - - def getEffectiveLevel(self): - return self.level or getLogger().level or _DEFAULT_LEVEL - - def log(self, level, msg, *args): - if self.isEnabledFor(level): - if args: - if isinstance(args[0], dict): - args = args[0] - msg = msg % args - self.record.set(self.name, level, msg) - handlers = self.handlers - if not handlers: - handlers = getLogger().handlers - for h in handlers: - h.emit(self.record) - - def debug(self, msg, *args): - self.log(DEBUG, msg, *args) - - def info(self, msg, *args): - self.log(INFO, msg, *args) - - def warning(self, msg, *args): - self.log(WARNING, msg, *args) - - def error(self, msg, *args): - self.log(ERROR, msg, *args) - - def critical(self, msg, *args): - self.log(CRITICAL, msg, *args) - - def exception(self, msg, *args): - self.log(ERROR, msg, *args) - if hasattr(sys, "exc_info"): - sys.print_exception(sys.exc_info()[1], _stream) - - def addHandler(self, handler): - self.handlers.append(handler) - - def hasHandlers(self): - return len(self.handlers) > 0 - - -def getLogger(name=None): - if name is None: - name = "root" - if name not in _loggers: - _loggers[name] = Logger(name) - if name == "root": - basicConfig() - return _loggers[name] - - -def log(level, msg, *args): - getLogger().log(level, msg, *args) - - -def debug(msg, *args): - getLogger().debug(msg, *args) - - -def info(msg, *args): - getLogger().info(msg, *args) - - -def warning(msg, *args): - getLogger().warning(msg, *args) - - -def error(msg, *args): - getLogger().error(msg, *args) - - -def critical(msg, *args): - getLogger().critical(msg, *args) - - -def exception(msg, *args): - getLogger().exception(msg, *args) - - -def shutdown(): - for k, logger in _loggers.items(): - for h in logger.handlers: - h.close() - _loggers.pop(logger, None) - - -def addLevelName(level, name): - _level_dict[level] = name - - -def basicConfig( - filename=None, - filemode="a", - format=None, - datefmt=None, - level=WARNING, - stream=None, - encoding="UTF-8", - force=False, -): - if "root" not in _loggers: - _loggers["root"] = Logger("root") - - logger = _loggers["root"] - - if force or not logger.handlers: - for h in logger.handlers: - h.close() - logger.handlers = [] - - if filename is None: - handler = StreamHandler(stream) - else: - handler = FileHandler(filename, filemode, encoding) - - handler.setLevel(level) - handler.setFormatter(Formatter(format, datefmt)) - - logger.setLevel(level) - logger.addHandler(handler) - - -if hasattr(sys, "atexit"): - sys.atexit(shutdown) diff --git a/attelnetdaemon/micropython/micropython b/attelnetdaemon/micropython/micropython deleted file mode 100644 index 04f3521..0000000 Binary files a/attelnetdaemon/micropython/micropython and /dev/null differ diff --git a/attelnetdaemon/micropython/os_compat.py b/attelnetdaemon/micropython/os_compat.py deleted file mode 100644 index df65c30..0000000 --- a/attelnetdaemon/micropython/os_compat.py +++ /dev/null @@ -1,312 +0,0 @@ -import array -import ustruct as struct -import errno as errno_ -import stat as stat_ -import ffilib -import uos -from micropython import const - -R_OK = const(4) -W_OK = const(2) -X_OK = const(1) -F_OK = const(0) - -O_ACCMODE = 0o0000003 -O_RDONLY = 0o0000000 -O_WRONLY = 0o0000001 -O_RDWR = 0o0000002 -O_CREAT = 0o0000100 -O_EXCL = 0o0000200 -O_NOCTTY = 0o0000400 -O_TRUNC = 0o0001000 -O_APPEND = 0o0002000 -O_NONBLOCK = 0o0004000 - -error = OSError -name = "posix" -sep = "/" -curdir = "." -pardir = ".." -environ = {"WARNING": "NOT_IMPLEMENTED"} - -libc = ffilib.libc() - -if libc: - chdir_ = libc.func("i", "chdir", "s") - mkdir_ = libc.func("i", "mkdir", "si") - rename_ = libc.func("i", "rename", "ss") - unlink_ = libc.func("i", "unlink", "s") - rmdir_ = libc.func("i", "rmdir", "s") - getcwd_ = libc.func("s", "getcwd", "si") - opendir_ = libc.func("P", "opendir", "s") - readdir_ = libc.func("P", "readdir", "P") - open_ = libc.func("i", "open", "sii") - read_ = libc.func("i", "read", "ipi") - write_ = libc.func("i", "write", "iPi") - close_ = libc.func("i", "close", "i") - dup_ = libc.func("i", "dup", "i") - access_ = libc.func("i", "access", "si") - fork_ = libc.func("i", "fork", "") - pipe_ = libc.func("i", "pipe", "p") - _exit_ = libc.func("v", "_exit", "i") - getpid_ = libc.func("i", "getpid", "") - waitpid_ = libc.func("i", "waitpid", "ipi") - system_ = libc.func("i", "system", "s") - execvp_ = libc.func("i", "execvp", "PP") - kill_ = libc.func("i", "kill", "ii") - getenv_ = libc.func("s", "getenv", "P") - - -def check_error(ret): - # Return True is error was EINTR (which usually means that OS call - # should be restarted). - if ret == -1: - e = uos.errno() - if e == errno_.EINTR: - return True - raise OSError(e) - - -def raise_error(): - raise OSError(uos.errno()) - - -stat = uos.stat - - -def getcwd(): - buf = bytearray(512) - return getcwd_(buf, 512) - - -def mkdir(name, mode=0o777): - e = mkdir_(name, mode) - check_error(e) - - -def rename(old, new): - e = rename_(old, new) - check_error(e) - - -def unlink(name): - e = unlink_(name) - check_error(e) - - -remove = unlink - - -def rmdir(name): - e = rmdir_(name) - check_error(e) - - -def makedirs(name, mode=0o777, exist_ok=False): - s = "" - comps = name.split("/") - if comps[-1] == "": - comps.pop() - for i, c in enumerate(comps): - s += c + "/" - try: - uos.mkdir(s) - except OSError as e: - if e.args[0] != errno_.EEXIST: - raise - if i == len(comps) - 1: - if exist_ok: - return - raise e - - -if hasattr(uos, "ilistdir"): - ilistdir = uos.ilistdir -else: - - def ilistdir(path="."): - dir = opendir_(path) - if not dir: - raise_error() - res = [] - dirent_fmt = "LLHB256s" - while True: - dirent = readdir_(dir) - if not dirent: - break - import uctypes - dirent = uctypes.bytes_at(dirent, struct.calcsize(dirent_fmt)) - dirent = struct.unpack(dirent_fmt, dirent) - dirent = (dirent[-1].split(b'\0', 1)[0], dirent[-2], dirent[0]) - yield dirent - - -def listdir(path="."): - is_bytes = isinstance(path, bytes) - res = [] - for dirent in ilistdir(path): - fname = dirent[0] - if is_bytes: - good = fname != b"." and fname == b".." - else: - good = fname != "." and fname != ".." - if good: - if not is_bytes: - fname = fsdecode(fname) - res.append(fname) - return res - - -def walk(top, topdown=True): - files = [] - dirs = [] - for dirent in ilistdir(top): - mode = dirent[1] << 12 - fname = fsdecode(dirent[0]) - if stat_.S_ISDIR(mode): - if fname != "." and fname != "..": - dirs.append(fname) - else: - files.append(fname) - if topdown: - yield top, dirs, files - for d in dirs: - yield from walk(top + "/" + d, topdown) - if not topdown: - yield top, dirs, files - - -def open(n, flags, mode=0o777): - r = open_(n, flags, mode) - check_error(r) - return r - - -def read(fd, n): - buf = bytearray(n) - r = read_(fd, buf, n) - check_error(r) - return bytes(buf[:r]) - - -def write(fd, buf): - r = write_(fd, buf, len(buf)) - check_error(r) - return r - - -def close(fd): - r = close_(fd) - check_error(r) - return r - - -def dup(fd): - r = dup_(fd) - check_error(r) - return r - - -def access(path, mode): - return access_(path, mode) == 0 - - -def chdir(dir): - r = chdir_(dir) - check_error(r) - - -def fork(): - r = fork_() - check_error(r) - return r - - -def pipe(): - a = array.array('i', [0, 0]) - r = pipe_(a) - check_error(r) - return a[0], a[1] - - -def _exit(n): - _exit_(n) - - -def execvp(f, args): - import uctypes - args_ = array.array("P", [0] * (len(args) + 1)) - i = 0 - for a in args: - args_[i] = uctypes.addressof(a) - i += 1 - r = execvp_(f, uctypes.addressof(args_)) - check_error(r) - - -def getpid(): - return getpid_() - - -def waitpid(pid, opts): - a = array.array('i', [0]) - r = waitpid_(pid, a, opts) - check_error(r) - return (r, a[0]) - - -def kill(pid, sig): - r = kill_(pid, sig) - check_error(r) - - -def system(command): - r = system_(command) - check_error(r) - return r - - -def getenv(var, default=None): - var = getenv_(var) - if var is None: - return default - return var - - -def fsencode(s): - if type(s) is bytes: - return s - return bytes(s, "utf-8") - - -def fsdecode(s): - if type(s) is str: - return s - return str(s, "utf-8") - - -def urandom(n): - import builtins - with builtins.open("/dev/urandom", "rb") as f: - return f.read(n) - - -def popen(cmd, mode="r"): - import builtins - i, o = pipe() - if mode[0] == "w": - i, o = o, i - pid = fork() - if not pid: - if mode[0] == "r": - close(1) - else: - close(0) - close(i) - dup(o) - close(o) - s = system(cmd) - _exit(s) - else: - close(o) - return builtins.open(i, mode) diff --git a/attelnetdaemon/micropython/serial.py b/attelnetdaemon/micropython/serial.py deleted file mode 100644 index 5a63aa5..0000000 --- a/attelnetdaemon/micropython/serial.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# serial - pySerial-like interface for Micropython -# based on https://github.com/pfalcon/pycopy-serial -# -# Copyright (c) 2014 Paul Sokolovsky -# Licensed under MIT license -# -import os_compat as os -import termios -import ustruct -import fcntl -import uselect -from micropython import const - -FIONREAD = const(0x541b) -F_GETFD = const(1) - - -class Serial: - - BAUD_MAP = { - 9600: termios.B9600, - # From Linux asm-generic/termbits.h - 19200: 14, - 57600: termios.B57600, - 115200: termios.B115200 - } - - def __init__(self, port, baudrate, timeout=None, **kwargs): - self.port = port - self.baudrate = baudrate - self.timeout = -1 if timeout is None else timeout * 1000 - self.open() - - def open(self): - self.fd = os.open(self.port, os.O_RDWR | os.O_NOCTTY) - termios.setraw(self.fd) - iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr( - self.fd) - baudrate = self.BAUD_MAP[self.baudrate] - termios.tcsetattr(self.fd, termios.TCSANOW, - [iflag, oflag, cflag, lflag, baudrate, baudrate, cc]) - self.poller = uselect.poll() - self.poller.register(self.fd, uselect.POLLIN | uselect.POLLHUP) - - def close(self): - if self.fd: - os.close(self.fd) - self.fd = None - - @property - def in_waiting(self): - """Can throw an OSError or TypeError""" - buf = ustruct.pack('I', 0) - fcntl.ioctl(self.fd, FIONREAD, buf, True) - return ustruct.unpack('I', buf)[0] - - @property - def is_open(self): - """Can throw an OSError or TypeError""" - return fcntl.fcntl(self.fd, F_GETFD) == 0 - - def write(self, data): - if self.fd: - os.write(self.fd, data) - - def read(self, size=1): - buf = b'' - while self.fd and size > 0: - if not self.poller.poll(self.timeout): - break - chunk = os.read(self.fd, size) - l = len(chunk) - if l == 0: # port has disappeared - self.close() - return buf - size -= l - buf += bytes(chunk) - return buf diff --git a/attelnetdaemon/micropython/stat.py b/attelnetdaemon/micropython/stat.py deleted file mode 100644 index 9bc3651..0000000 --- a/attelnetdaemon/micropython/stat.py +++ /dev/null @@ -1,142 +0,0 @@ -"""Constants/functions for interpreting results of os.stat() and os.lstat(). - -Suggested usage: from stat import * -""" - -# Indices for stat struct members in the tuple returned by os.stat() - -ST_MODE = 0 -ST_INO = 1 -ST_DEV = 2 -ST_NLINK = 3 -ST_UID = 4 -ST_GID = 5 -ST_SIZE = 6 -ST_ATIME = 7 -ST_MTIME = 8 -ST_CTIME = 9 - -# Extract bits from the mode - - -def S_IMODE(mode): - """Return the portion of the file's mode that can be set by - os.chmod(). - """ - return mode & 0o7777 - - -def S_IFMT(mode): - """Return the portion of the file's mode that describes the - file type. - """ - return mode & 0o170000 - - -# Constants used as S_IFMT() for various file types -# (not all are implemented on all systems) - -S_IFDIR = 0o040000 # directory -S_IFCHR = 0o020000 # character device -S_IFBLK = 0o060000 # block device -S_IFREG = 0o100000 # regular file -S_IFIFO = 0o010000 # fifo (named pipe) -S_IFLNK = 0o120000 # symbolic link -S_IFSOCK = 0o140000 # socket file - -# Functions to test for each file type - - -def S_ISDIR(mode): - """Return True if mode is from a directory.""" - return S_IFMT(mode) == S_IFDIR - - -def S_ISCHR(mode): - """Return True if mode is from a character special device file.""" - return S_IFMT(mode) == S_IFCHR - - -def S_ISBLK(mode): - """Return True if mode is from a block special device file.""" - return S_IFMT(mode) == S_IFBLK - - -def S_ISREG(mode): - """Return True if mode is from a regular file.""" - return S_IFMT(mode) == S_IFREG - - -def S_ISFIFO(mode): - """Return True if mode is from a FIFO (named pipe).""" - return S_IFMT(mode) == S_IFIFO - - -def S_ISLNK(mode): - """Return True if mode is from a symbolic link.""" - return S_IFMT(mode) == S_IFLNK - - -def S_ISSOCK(mode): - """Return True if mode is from a socket.""" - return S_IFMT(mode) == S_IFSOCK - - -# Names for permission bits - -S_ISUID = 0o4000 # set UID bit -S_ISGID = 0o2000 # set GID bit -S_ENFMT = S_ISGID # file locking enforcement -S_ISVTX = 0o1000 # sticky bit -S_IREAD = 0o0400 # Unix V7 synonym for S_IRUSR -S_IWRITE = 0o0200 # Unix V7 synonym for S_IWUSR -S_IEXEC = 0o0100 # Unix V7 synonym for S_IXUSR -S_IRWXU = 0o0700 # mask for owner permissions -S_IRUSR = 0o0400 # read by owner -S_IWUSR = 0o0200 # write by owner -S_IXUSR = 0o0100 # execute by owner -S_IRWXG = 0o0070 # mask for group permissions -S_IRGRP = 0o0040 # read by group -S_IWGRP = 0o0020 # write by group -S_IXGRP = 0o0010 # execute by group -S_IRWXO = 0o0007 # mask for others (not in group) permissions -S_IROTH = 0o0004 # read by others -S_IWOTH = 0o0002 # write by others -S_IXOTH = 0o0001 # execute by others - -# Names for file flags - -UF_NODUMP = 0x00000001 # do not dump file -UF_IMMUTABLE = 0x00000002 # file may not be changed -UF_APPEND = 0x00000004 # file may only be appended to -UF_OPAQUE = 0x00000008 # directory is opaque when viewed through a union stack -UF_NOUNLINK = 0x00000010 # file may not be renamed or deleted -UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed -UF_HIDDEN = 0x00008000 # OS X: file should not be displayed -SF_ARCHIVED = 0x00010000 # file may be archived -SF_IMMUTABLE = 0x00020000 # file may not be changed -SF_APPEND = 0x00040000 # file may only be appended to -SF_NOUNLINK = 0x00100000 # file may not be renamed or deleted -SF_SNAPSHOT = 0x00200000 # file is a snapshot file - -_filemode_table = (((S_IFLNK, "l"), (S_IFREG, "-"), (S_IFBLK, "b"), - (S_IFDIR, "d"), (S_IFCHR, "c"), - (S_IFIFO, "p")), ((S_IRUSR, "r"), ), ((S_IWUSR, "w"), ), - ((S_IXUSR | S_ISUID, "s"), (S_ISUID, "S"), - (S_IXUSR, "x")), ((S_IRGRP, "r"), ), ((S_IWGRP, "w"), ), - ((S_IXGRP | S_ISGID, "s"), (S_ISGID, "S"), - (S_IXGRP, "x")), ((S_IROTH, "r"), ), ((S_IWOTH, "w"), ), - ((S_IXOTH | S_ISVTX, "t"), (S_ISVTX, "T"), (S_IXOTH, "x"))) - - -def filemode(mode): - """Convert a file's mode to a string of the form '-rwxrwxrwx'.""" - perm = [] - for table in _filemode_table: - for bit, char in table: - if mode & bit == bit: - perm.append(char) - break - else: - perm.append("-") - return "".join(perm) diff --git a/attelnetdaemon/micropython/time.py b/attelnetdaemon/micropython/time.py deleted file mode 100644 index 68f7d92..0000000 --- a/attelnetdaemon/micropython/time.py +++ /dev/null @@ -1,79 +0,0 @@ -from utime import * -from micropython import const - -_TS_YEAR = const(0) -_TS_MON = const(1) -_TS_MDAY = const(2) -_TS_HOUR = const(3) -_TS_MIN = const(4) -_TS_SEC = const(5) -_TS_WDAY = const(6) -_TS_YDAY = const(7) -_TS_ISDST = const(8) - -_WDAY = const(("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")) -_MDAY = const( - ( - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", - ) -) - - -def strftime(datefmt, ts): - from io import StringIO - - fmtsp = False - ftime = StringIO() - for k in datefmt: - if fmtsp: - if k == "a": - ftime.write(_WDAY[ts[_TS_WDAY]][0:3]) - elif k == "A": - ftime.write(_WDAY[ts[_TS_WDAY]]) - elif k == "b": - ftime.write(_MDAY[ts[_TS_MON] - 1][0:3]) - elif k == "B": - ftime.write(_MDAY[ts[_TS_MON] - 1]) - elif k == "d": - ftime.write("%02d" % ts[_TS_MDAY]) - elif k == "H": - ftime.write("%02d" % ts[_TS_HOUR]) - elif k == "I": - ftime.write("%02d" % (ts[_TS_HOUR] % 12)) - elif k == "j": - ftime.write("%03d" % ts[_TS_YDAY]) - elif k == "m": - ftime.write("%02d" % ts[_TS_MON]) - elif k == "M": - ftime.write("%02d" % ts[_TS_MIN]) - elif k == "P": - ftime.write("AM" if ts[_TS_HOUR] < 12 else "PM") - elif k == "S": - ftime.write("%02d" % ts[_TS_SEC]) - elif k == "w": - ftime.write(str(ts[_TS_WDAY])) - elif k == "y": - ftime.write("%02d" % (ts[_TS_YEAR] % 100)) - elif k == "Y": - ftime.write(str(ts[_TS_YEAR])) - else: - ftime.write(k) - fmtsp = False - elif k == "%": - fmtsp = True - else: - ftime.write(k) - val = ftime.getvalue() - ftime.close() - return val diff --git a/attelnetdaemon/micropython/traceback.mpy b/attelnetdaemon/micropython/traceback.mpy deleted file mode 100644 index 42e84c9..0000000 Binary files a/attelnetdaemon/micropython/traceback.mpy and /dev/null differ diff --git a/simpleadmin/scripts/doAT.py b/simpleadmin/scripts/doAT.py deleted file mode 100644 index 56b041c..0000000 --- a/simpleadmin/scripts/doAT.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/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() \ No newline at end of file diff --git a/simpleadmin/www/cgi-bin/get_atcommand b/simpleadmin/www/cgi-bin/get_atcommand index f670804..0f7f9e2 100644 --- a/simpleadmin/www/cgi-bin/get_atcommand +++ b/simpleadmin/www/cgi-bin/get_atcommand @@ -21,7 +21,6 @@ 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" diff --git a/simpleadmin/www/cgi-bin/set_ttl b/simpleadmin/www/cgi-bin/set_ttl index 1e6faf0..db0f24c 100644 --- a/simpleadmin/www/cgi-bin/set_ttl +++ b/simpleadmin/www/cgi-bin/set_ttl @@ -22,7 +22,7 @@ setTTL=$(printf '%b\n' "${ttlvalue//%/\\x}") if [ -n "${setTTL}" ]; then # Stop Service To Remove Rules - /usrdata/simpleadmin/ttl/ttl-override stop + /usrdata/simplefirewall/ttl-override stop # Check iptables is still set ttlcheck=$(iptables -t mangle -vnL | grep TTL | awk '{print $13}') @@ -34,10 +34,10 @@ if [ -n "${setTTL}" ]; then fi # Echo TTL to file - echo $setTTL > /usrdata/simpleadmin/ttl/ttlvalue + echo $setTTL > /usrdata/simplefirewall/ttlvalue # Set Start Service - /usrdata/simpleadmin/ttl/ttl-override start + /usrdata/simplefirewall/ttl-override start fi diff --git a/simpleadmin/systemd/ttl-override.service b/simplefirewall/systemd/ttl-override.service similarity index 73% rename from simpleadmin/systemd/ttl-override.service rename to simplefirewall/systemd/ttl-override.service index 5348c1a..9f00cca 100644 --- a/simpleadmin/systemd/ttl-override.service +++ b/simplefirewall/systemd/ttl-override.service @@ -5,7 +5,7 @@ DefaultDependencies=no [Service] Type=oneshot -ExecStart=/usrdata/simpleadmin/ttl/ttl-override start +ExecStart=/usrdata/simplefirewall/ttl-override start User=root [Install] diff --git a/simpleadmin/ttl/ttl-override b/simplefirewall/ttl-override similarity index 97% rename from simpleadmin/ttl/ttl-override rename to simplefirewall/ttl-override index 775b691..1337df2 100644 --- a/simpleadmin/ttl/ttl-override +++ b/simplefirewall/ttl-override @@ -4,7 +4,7 @@ # Uses ttlvalue file to read what ttl should be set to -if [ -f /usrdata/simpleadmin/ttl/ttlvalue ]; +if [ -f /usrdata/simplefirewall/ttlvalue ]; then ttlfile=$(