steptail.com

If I try to fail, but succeed, which one did I do?

User Tools

Site Tools


guides:virtual_modem:script

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
guides:virtual_modem:script [2019-11-18 23:58]
omolini [ppp.sh]
guides:virtual_modem:script [2022-12-28 03:32] (current)
omolini
Line 1: Line 1:
 ====== VModem ====== ====== VModem ======
-The script that fakes a Hayes compatible modem.+The script that simulates ​a Hayes compatible modem. 
 + 
 +A copy of vmodem can be also found at Github, at https://​github.com/​molivil/​vmodem
  
 ===== vmodem.sh ===== ===== vmodem.sh =====
Line 17: Line 19:
 # VMODEM - Virtual Modem bootstrap # VMODEM - Virtual Modem bootstrap
 # -------------------------------- # --------------------------------
-# Oliver Molini ​2019+# Oliver Molini ​2020-2022 
 +
 +# Additional credits: 
 +# - Billy Stoughton II for bug fixes and contributions 
 +# - Hamish for helping test Windows 2000 compatibility
 # #
 # Licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License # Licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
 # https://​creativecommons.org/​licenses/​by-nc-sa/​4.0/​ # https://​creativecommons.org/​licenses/​by-nc-sa/​4.0/​
-# + 
-# Tested working out of box with the following ​host configurations:​+# Tested working out of box with the following ​client ​configurations:​
 # #
 # o Standard VT100 terminal # o Standard VT100 terminal
Line 28: Line 34:
 # o PuTTY # o PuTTY
 # #
-# PPP connectivity ​will initialize ​correctly ​under the following configurations:​+# PPP dial-up ​connectivity ​tested to initialize under the following configurations:​ 
 +
 +# o Windows 3.1 
 +#   - Trumpet Winsock 3.0 revision D
 # #
-# o Microsoft ​Windows ​3.1 +# o Windows ​95 OSR 2.5 + DUN 1.4 
-#   ​- ​Trumpet Winsock+#   ​- ​Generic Modem 
 +#     - Standard 28800 bps Modem
 # #
-# o Microsoft ​Windows 98 +# o Windows 98 
-#   - Generic+#   - Generic ​Modem
 #     - Standard 9 600 bps modem #     - Standard 9 600 bps modem
 #     - Standard 33 600 bps modem #     - Standard 33 600 bps modem
Line 40: Line 50:
 #     - Standard 56 000 bps X2 modem #     - Standard 56 000 bps X2 modem
 #     - Standard 56 000 bps K56Flex modem #     - Standard 56 000 bps K56Flex modem
 +#
 +# o Windows 2000
 +#   - Generic Modem
 +#     - Standard 19200 bps Modem
 +#
 +# Help us test and add more supported systems! ​
 +# Contact us on Discord, links at the bottom of the Virtual Modem page.
 # #
  
 # Script version # Script version
-vmodver=1.4+vmodver=1.7.1
  
-# CONFIGURATION ​VARIABLES+# CONFIGURATION
 # ----------------------- # -----------------------
- 
 # Variable: serport # Variable: serport
 # serport specifies which local serial device to use. # serport specifies which local serial device to use.
-# For example, ​using "ttyAMA0" will tell the script +# For example, "ttyUSB0" will tell the script ​to use 
-# to use /dev/ttyAMA0 ​for communication.+# to use /dev/ttyUSB0 ​for communication. 
 +# Common values: ttyUSB0 or ttyAMA0
 # #
-# Default: +serport=ttyUSB0
-serport=ttyAMA0 +
-+
-serport=ttyAMA0+
  
 # Variable: baud # Variable: baud
Line 68: Line 82:
 # baud=57600 # baud=57600
 # #
-#baud 9600+#baud=9600
 #baud=38400 #baud=38400
 baud=57600 baud=57600
 +
 +# Variable: etherp
 +# Sets the name of the ethernet device for PPP connections.
 +
 +# eth0 for wired 
 +# wlan0 for wireless
 +#
 +etherp=eth0
  
 # Variable: echoser # Variable: echoser
Line 79: Line 101:
  
 # Variable: resultverbose # Variable: resultverbose
-# Controls default ​behaviour ​when printing result +# Controls default ​behavior ​when printing ​Hayes result 
-# codes. When 0, will print result codes in numerical +# codes. ​ 
-form. When 1, will print result codes in english.+When 0, prints ​result codes in numerical form. (eg. 0) 
 +When 1, prints ​result codes in english. ​(eg. CONNECT)
 # Default is 1. # Default is 1.
 resultverbose=1 resultverbose=1
 +
 +# Variable: TERM
 +# Tells the script and environment which type of terminal to emulate.
 +# It is only useful to change this, if you're using a serial ​
 +# terminal to connect to this script. If you're connecting form a ANSI 
 +# cabable machine such as DOS, you may want to use TERM="​ansi"​
 +#
 +TERM="​vt100"​
  
 # EXPORT SHELL VARS # EXPORT SHELL VARS
Line 89: Line 120:
 export serport export serport
 export baud export baud
 +export etherp
 +export TERM
  
 # FUNCTIONS # FUNCTIONS
Line 99: Line 132:
   stty -F /​dev/​$serport sane   stty -F /​dev/​$serport sane
   stty -F /​dev/​$serport raw   stty -F /​dev/​$serport raw
-  stty -F /​dev/​$serport -echo -icrnl clocal+  stty -F /​dev/​$serport -echo -icrnl ​onlcr opost clocal ​-crtscts
 } }
  
 # SEND MESSAGE ON SCREEN AND OVER SERIAL # SEND MESSAGE ON SCREEN AND OVER SERIAL
 sendtty () { sendtty () {
-  ​echo -en "$1\n"; +  ​# Prints message in console and over serial. Message is given as first parameter. 
-  echo -en "$1\x0d\x0a" ​>/​dev/​$serport+  message="​$1"​ 
 +  echo -en "$message" ​| tee /​dev/​$serport
 } }
 +
 +readtty () {
 +  # Reads input from TTY and stores it in variable given as first parameter
 +  line=
 +  while [[ -z "​$line"​ ]]; do
 +    charhex=`head -c 1 /​dev/​$serport | xxd -p -`
 +    char="​`echo -e "​\x$charhex"​`"​
 +    echo -n "​$char"​
 +    echo -n "​$char"​ > /​dev/​$serport
 +    # Newline received
 +    if [ "​$charhex"​ = "​0d"​ -o "​$charhex"​ = "​0a"​ ]; then
 +      line=$buffer
 +      buffer=
 +      char=
 +      sendtty "​\n"​
 +    fi
 +    buffer=$buffer$char
 +  done
 +  local __resultvar=$1
 +  local result="​$line"​
 +  eval $__resultvar="'​$result'"​
 +}
 +
 +export -f sendtty
 +export -f readtty
 +export -f ttyinit
  
 # Open serial port for use. Allocate file descriptor # Open serial port for use. Allocate file descriptor
Line 113: Line 173:
 exec 99<>/​dev/​$serport exec 99<>/​dev/​$serport
  
-sendtty ""​ +sendtty "\n
-sendtty "VMODEM - Virtual Modem bootstrap for PPP link v$vmodver"​ +sendtty "​Virtual Modem bootstrap for PPP link v$vmodver\n
-sendtty "​Connection speed set to $baud baud"​ +sendtty "​Connection speed set to $baud baud.\n
-sendtty ""​ +sendtty "My current IP address is $(hostname -I).\n"​ 
-sendtty "TYPE HELP FOR COMMANDS+sendtty "\n
-sendtty "​READY."​+sendtty "​TYPE ​\"HELP\" ​FOR COMMAND REFERENCE.\n
 +sendtty "​READY.\n" 
 + 
 +# execute hayes commands 
 +dohayes () { 
 +  # default to error result code, if command not recognized 
 +  result=4 
 + 
 +  # Debugging 
 +  #sendtty "​COMMAND:​ $hcmd $hparm\n"​ 
 + 
 +  # ATA 
 +  # - A Answer 
 +  if [[ $hcmd == '​A'​ ]]; then result=0; fi 
 + 
 +  # ATD Dial a number 
 +  if [[ $hcmd == '​D'​ ]]; then 
 +    if [[ ! -z "​$hparm"​ ]]; then 
 +      number=$(echo $hparm |tr -dc '​0-9'​) 
 +      result=0 
 +    fi 
 +  fi 
 + 
 +  # ATE Command echo to host 
 +  # - E0 Commands are not echoed 
 +  # - E1 Commands are echoed 
 +  if [[ $hcmd == '​E'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then echoser=0; result=0; fi 
 +    if [[ $hparm == '​0'​ ]]; then echoser=0; result=0; fi 
 +    if [[ $hparm == '​1'​ ]]; then echoser=1; result=0; fi 
 +  fi 
 + 
 +  # ATH Hang up or pick-up. 
 +  # - H0 Go on-hook (Hang up) 
 +  # - H1 Go off-hook 
 +  if [[ $hcmd == '​H'​ ]]; then result=0; fi 
 + 
 +  # ATM Speaker control 
 +  # - M0 Speaker always off 
 +  # - M1 Speaker on until carrier detected 
 +  # - M2 Speaker always on 
 +  # - M3 Speaker on only while answering 
 +  if [[ $hcmd == '​M'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then result=0; fi 
 +    if [[ $hparm == '​1'​ ]]; then result=0; fi 
 +    if [[ $hparm == '​2'​ ]]; then result=0; fi 
 +    if [[ $hparm == '​3'​ ]]; then result=0; fi 
 +  fi 
 + 
 +  # ATQn Result codes 
 +  # Q0 Modem returns result codes 
 +  # Q1 Quiet mode. Modem gives no result codes. 
 +  if [[ $hcmd == '​Q'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then resultverbose=0;​ result=0; fi 
 +    if [[ $hparm == '​0'​ ]]; then resultverbose=0;​ result=0; fi 
 +    if [[ $hparm == '​1'​ ]]; then resultverbose=2;​ result=0; fi 
 +  fi 
 + 
 +  # S Registers (just auto-accept) 
 +  if [[ $hcmd == '​S'​ ]]; then 
 +    result=0; 
 +  fi 
 + 
 +  # ATV Result codes in numerical or verbose form 
 +  # - V0 Returns the code in numerical form 
 +  # - V1 Full-word result codes 
 +  if [[ $hcmd == '​V'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then resultverbose=0;​ result=0; fi 
 +    if [[ $hparm == '​0'​ ]]; then resultverbose=0;​ result=0; fi 
 +    if [[ $hparm == '​1'​ ]]; then resultverbose=1;​ result=0; fi 
 +  fi 
 + 
 +  # ATXn Extended result codes 
 +  # - X0 Disable extended result codes (Hayes Smartmodem 300 compatible result codes) 
 +  # - X1 Add connection speed to basic result codes (e.g. CONNECT 1200) 
 +  # - X2 Add dial tone detection (preventing blind dial, and sometimes preventing ATO) 
 +  # - X3 Add busy signal detection 
 +  # - X4 Add both busy signal and dial tone detection 
 +  if [[ $hcmd == '​X'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then resultverbose=1;​ result=0; fi 
 +    if [[ $hparm == '​0'​ ]]; then resultverbose=1;​ result=0; fi 
 +    if [[ $hparm == '​1'​ ]]; then resultverbose=0;​ result=0; fi 
 +    if [[ $hparm == '​2'​ ]]; then resultverbose=0;​ result=0; fi 
 +    if [[ $hparm == '​3'​ ]]; then resultverbose=0;​ result=0; fi 
 +    if [[ $hparm == '​4'​ ]]; then resultverbose=0;​ result=0; fi 
 +  fi 
 + 
 +  # ATZ Reset modem 
 +  # - Zn  Restore stored profile n 
 +  if [[ $hcmd == '​Z'​ ]]; then echoser=1; resultverbose=1;​ carrierdetect=0;​ result=0; fi 
 + 
 +  # AT&Cn Carrier-detect 
 +  # - &C0 Force DCD signal active 
 +  # - &C1 DCD signal indicates true state of remote carrier signal 
 +  if [[ $hcmd == '&​C'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then result=0; carrierdetect=0;​ fi 
 +    if [[ $hparm == '​0'​ ]]; then result=0; carrierdetect=0;​ fi 
 +    if [[ $hparm == '​1'​ ]]; then result=0; carrierdetect=1;​ fi 
 +  fi 
 + 
 +  # AT&Dn Data Terminal Ready settings 
 +  # - &D0 Modem ignores DTR 
 +  # - &D1 Go to command mode on ON-to-OFF DTR transition. 
 +  # - &D2 Hang up on DTR-drop and go to command mode 
 +  # - &D3 Reset (ATZ) on DTR-drop. Modem hangs up. 
 +  if [[ $hcmd == '&​D'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then result=0; fi 
 +    if [[ $hparm == '​0'​ ]]; then result=0; fi 
 +    if [[ $hparm == '​1'​ ]]; then result=0; fi 
 +    if [[ $hparm == '​2'​ ]]; then result=0; fi 
 +    if [[ $hparm == '​3'​ ]]; then result=0; fi 
 +  fi 
 + 
 +  # AT&F Restore factory settings 
 +  # - &Fn Use profile n 
 +  if [[ $hcmd == '&​F'​ ]]; then echoser=1; resultverbose=1;​ carrierdetect=0;​ result=0; fi 
 + 
 +  # AT&K DTE - MODEM Flow control 
 +  # - &K0 Local flow control off 
 +  # - &K1 Not used 
 +  # - &K2 Not used 
 +  # - &K3 RTS/CTS 
 +  # - &K4 XON/XOFF 
 +  # - &K5 Transparent XON/XOFF 
 +  # - &K6 RTS/CTS and XON/XOFF 
 +  if [[ $hcmd == '&​K'​ ]]; then result=0; fi 
 + 
 +  # AT&Sn DSR Override 
 +  # - &S0 DSR will remain on at all times. 
 +  # - &S1 DSR will become active after answer tone has been detected and inactive after the carrier has been lost 
 +  if [[ $hcmd == '&​S'​ ]]; then 
 +    if [[ $hparm == ''​ ]]; then result=0; fi 
 +    if [[ $hparm == '​0'​ ]]; then result=0; fi 
 +    if [[ $hparm == '​1'​ ]]; then result=0; fi 
 +  fi 
 +}
  
 # MAIN LOOP # MAIN LOOP
Line 141: Line 336:
     #NEWLINE SENT - ECHO NEWLINE TO CONSOLE     #NEWLINE SENT - ECHO NEWLINE TO CONSOLE
     if [ "​$echoser"​ = "​0"​ ]; then echo; fi     if [ "​$echoser"​ = "​0"​ ]; then echo; fi
-    if [ "​$echoser"​ = "​1"​ ]; then sendtty; fi+    if [ "​$echoser"​ = "​1"​ ]; then sendtty ​"​\n"​; fi
  
     #     #
-    # --- MODEM EMULATION ---+    # --- HAYES EMULATION ---
     #     #
     if [[ $cmd == AT* ]]; then     if [[ $cmd == AT* ]]; then
-      # ok, the client ​issued an AT command+      # Attention! Client ​issued an AT command
       #       #
       # default to error result code, if command not recognized       # default to error result code, if command not recognized
-      result=4+      result=4; resultc=0
  
       if [[ $cmd == AT ]]; then result=0; fi       if [[ $cmd == AT ]]; then result=0; fi
  
-      # Get hayes string+      # Get full hayes string ​and parse it
       seq=`echo $cmd |cut -b3-`       seq=`echo $cmd |cut -b3-`
-      ​# ATA +      ​ptr=1 
-      if [[ $seq == A ]]; then result=0; fi+      ​until [ $ptr -gt 64 ]; do 
 +        hchar=$(echo "​$seq"​ |cut -b$ptr) 
 +        #sendtty "$ptr $hchar\n"​ 
 +        ​if [[ $hchar =~ [A-Z\&] ]]; then 
 +          if [[ $hchar == '&'​ ]]; then 
 +            hcmd="​$hchar"​ 
 +            ptr=$((ptr+1)) 
 +            hchar=$(echo "$seq" |cut -b$ptr) 
 +            if [[ $hchar ​=~ [A-Z] ]]; then 
 +              hcmd="​$hcmd$hchar"​ 
 +              until [ $hdone ]; do 
 +                ptr=$((ptr+1)) 
 +                hchar=$(echo "​$seq"​ |cut -b$ptr) 
 +                if [[ $hchar =~ [0-9] ]]; then 
 +                  hparm="​$hparm$hchar"​ 
 +                else 
 +                  ptr=$((ptr-1)) 
 +                  hdone=1 
 +                fi 
 +              done 
 +            fi 
 +          elif [[ $hchar =~ [A-CE-Z] ​]]; then 
 +            hcmd="​$hcmd$hchar"​ 
 +            until [ $hdone ]; do 
 +              ptr=$((ptr+1)) 
 +              hchar=$(echo "​$seq"​ |cut -b$ptr) 
 +              if [[ $hchar =~ [0-9] ]]then 
 +                hparm="​$hparm$hchar"​ 
 +              else 
 +                ptr=$((ptr-1)) 
 +                hdone=1 
 +              ​fi 
 +            done 
 +          elif [[ $hchar == '​D'​ ]]; then 
 +            hcmd="​$hcmd$hchar"​ 
 +            until [ $hdone ]; do 
 +              ptr=$((ptr+1)) 
 +              hchar=$(echo "​$seq"​ |cut -b$ptr) 
 +              if [[ $hchar =~ [0-9PRT,!] ]]; then 
 +                hparm="​$hparm$hchar"​ 
 +              else 
 +                ptr=$((ptr-1)) 
 +                hdone=1 
 +              fi 
 +            done 
 +          fi 
 +        fi 
 +        ptr=$((ptr+1)) 
 +        if [[ ! -z "​$hcmd"​ ]]; then 
 +          dohayes 
 +          # preserve error if one was encountered 
 +          if [[ $result == '​4'​ ]]; then resultc='​4';​ fi 
 +        else 
 +          break 
 +        fi 
 +        hcmd=""​ 
 +        hparm=""​ 
 +        hdone=""​ 
 +      done
  
-      ​# ATH Go on-hook, hang up. +      if [[ $resultc ​== '​4' ​]]; then result='​4'​; fi
-      ​if [[ $seq == H* ]]; then result=0; fi  # H0 Go on-hook (Hang up) +
-      if [[ $seq == H1* ]]; then result=0; fi # H1 Go off-hook+
  
-      # ATZ Reset modem +      # ATD Dial number 
-      if [[ $seq == Z* ]]; then echoser=1; resultverbose=1; ​result=0; fi      Zn  Restore stored profile n+      if [[ ! -z "$number" ​]]; then 
 +        if [[ $resultverbose == 1 ]]then sendtty "​RINGING\n";​ fi 
 +        sleep 2 
 +        if [ -f "​$number.sh"​ ]; then 
 +          if [[ $resultverbose ​== 1 ]]then sendtty "​CONNECT $baud\n";​ else sendtty "​1\n"​; fi 
 +          ​Assert DCD when carrier detection is turned on (for Trumpet Winsock) 
 +          if [[ $carrierdetect == 1 ]]; then exec 99>&​-;​ fi
  
-      ​AT&F Restore factory settings +          ​Tell the terminal to use CR/LF for newlines instead of just CR. 
-      if [[ $seq == *\&F* ]]; then echoser=1; resultverbose=1;​ result=0; fi   # &Fn Use profile n+          echo -en "\x1b[20h" > /dev/$serport
  
-      ​ATE Command echo to host +          ​Run script 
-      if [[ $seq == *E* ]]; then echoser=0; result=0; fi        ​E0 Commands are not echoed +          #/sbin/getty -8 -L $serport $baud $TERM -n -l "​./​$number.sh"​ 
-      if [[ $seq == *E1* ]]; then echoser=1; result=0; fi       # E1 Commands are echoed+          ./$number.sh
  
-      # ATV Result codes in numerical or verbose form +          ​if [[ $carrierdetect ​== ]]; then exec 99<>/​dev/​$serport; fi
-      ​if [[ $seq == *V* ]]; then resultverbose=0;​ result=0; fi  # V0 Returns the code in numerical form +
-      if [[ $seq == *V1* ]]; then resultverbose=1;​ result=0; fi # V1 Full-word result codes+
  
-      # ATM Speaker control +          ​# Reset serial settings 
-      if [[ $seq == *M* ]]; then result=0; fi                   # M0 Speaker always off +          ttyinit 
-      if [[ $seq == *M1* ]]; then result=0; fi                  # M1 Speaker on until carrier detected +          result=3
-      if [[ $seq == *M2* ]]; then result=0; fi                  # M2 Speaker always on +
-      if [[ $seq == *M3* ]]; then result=0; fi                  # M3 Speaker on only while answering +
- +
-      # AT&Cn Carrier-detect +
-      if [[ $seq == *\&C0* ]]; then result=0; fi +
-      if [[ $seq == *\&C1* ]]; then result=0; fi +
- +
-      # AT&Dn Data Terminal Ready settings +
-      if [[ $seq == *\&D0* ]]; then result=0; fi                # Modem ignores DTR +
-      if [[ $seq == *\&D1* ]]; then result=0; fi                # Go to command mode on ON-to-OFF DTR transition. +
-      if [[ $seq == *\&D2* ]]; then result=0; fi                # Hang up on DTR-drop and go to command mode +
-      if [[ $seq == *\&D3* ]]; then result=0; fi                # Reset (ATZ) on DTR-drop. Modem hangs up. +
- +
-      # AT&Sn DSR Override +
-      if [[ $seq == *\&S0* ]]; then result=0; fi # &S0 DSR will remain on at all times. +
-      if [[ $seq == *\&S1* ]]; then result=0; fi # &S1 DSR will become active after answer tone has been detected and inactive after the carrier has been lost +
- +
-      # ATQn Result codes +
-      if [[ $seq == *Q0* ]]; then resultverbose=0;​ result=0; fi # Q0 Modem returns result codes +
-      if [[ $seq == *Q1* ]]; then resultverbose=2;​ result=0; fi # Q1 Quiet mode. Modem gives no result codes. +
- +
-      # ATXn Extended result codes +
-      if [[ $seq == *X0* ]]; then resultverbose=1;​ result=0; fi     # X0 Disable extended result codes (Hayes Smartmodem 300 compatible result codes) +
-      if [[ $seq == *X1* ]]; then resultverbose=0;​ result=0; fi     # X1 Add connection speed to basic result codes (e.g. CONNECT 1200) +
-      if [[ $seq == *X2* ]]; then resultverbose=0;​ result=0; fi     # X2 Add dial tone detection (preventing blind dial, and sometimes preventing ATO) +
-      if [[ $seq == *X3* ]]; then resultverbose=0;​ result=0; fi     # X3 Add busy signal detection +
-      if [[ $seq == *X4* ]]; then resultverbose=0;​ result=0; fi     # X4 Add both busy signal and dial tone detection +
- +
-      # ATD Dial number +
-      if [[ $cmd == ATD* ]]; then +
-        # Get number, if applicable +
-        number=`echo $seq |tr -dc '​0-9'​` +
-        if [ ! -z "​$number"​ ]; then +
-          if [[ $resultverbose == 1 ]]; then sendtty "​RINGING";​ fi +
-          if [ -f "​$number.sh"​ ]; then +
-            if [[ $resultverbose == 1 ]]; then sendtty "​CONNECT $baud";​ else sendtty "​1";​ fi +
-            # Close serial port +
-            exec 99>&​- +
-            # Execute dialed script +
-            /sbin/getty -8 -L $serport $baud vt100 -n -l "​./​$number.sh"​ +
-            ​# Reset serial settings +
-            ttyinit +
-            # Reopen serial port +
-            exec 99<>/​dev/​$serport +
-            result=3 +
-          ​else +
-            # Phone number is valid, but no internal script by that name exists +
-            ​result=3 +
-          fi+
         else         else
-          # No number ​specifiedreturn OK status code +          # Phone number ​is validbut no internal script by that name exists 
-          result=0+          result=3
         fi         fi
 +        number=""​
       fi       fi
  
Line 239: Line 446:
       #       #
       if [[ $resultverbose == 0 ]]; then       if [[ $resultverbose == 0 ]]; then
-        sendtty $result;+        sendtty ​"$result\n";
       elif [[ $resultverbose == 1 ]]; then       elif [[ $resultverbose == 1 ]]; then
-        if [[ $result == 0 ]]; then sendtty "​OK";​ fi +        if [[ $result == 0 ]]; then sendtty "OK\n"; fi 
-        if [[ $result == 1 ]]; then sendtty "​CONNECT";​ fi +        if [[ $result == 1 ]]; then sendtty "​CONNECT\n"; fi 
-        if [[ $result == 2 ]]; then sendtty "​RING";​ fi +        if [[ $result == 2 ]]; then sendtty "RING\n"; fi 
-        if [[ $result == 3 ]]; then sendtty "NO CARRIER";​ fi +        if [[ $result == 3 ]]; then sendtty "NO CARRIER\n"; fi 
-        if [[ $result == 4 ]]; then sendtty "​ERROR";​ fi +        if [[ $result == 4 ]]; then sendtty "ERROR\n"; fi 
-        if [[ $result == 5 ]]; then sendtty "​CONNECT 1200"; fi +        if [[ $result == 5 ]]; then sendtty "​CONNECT 1200\n"; fi 
-        if [[ $result == 6 ]]; then sendtty "NO DIALTONE";​ fi +        if [[ $result == 6 ]]; then sendtty "NO DIALTONE\n"; fi 
-        if [[ $result == 7 ]]; then sendtty "​BUSY";​ fi +        if [[ $result == 7 ]]; then sendtty "BUSY\n"; fi 
-        if [[ $result == 8 ]]; then sendtty "NO ANSWER";​ fi+        if [[ $result == 8 ]]; then sendtty "NO ANSWER\n"; fi
       fi       fi
     fi     fi
  
-    if [[ $cmd = HELP ]]; then +    if [[ $cmd = "HELP" ]] || [[ $cmd = "?" ​]]; then 
-      sendtty "​Command Reference for Virtual Modem Bootstrap v$vmodver"​ +      sendtty "​Command Reference for Virtual Modem Bootstrap v$vmodver\n
-      sendtty +      sendtty ​"​\n"​ 
-      sendtty "AT......Tests modem link, prints OK if successful+      sendtty "General commands:​\n"​ 
-      sendtty "ATE0....Switch terminal echo off+      sendtty "HELP.......Display this help\n
-      sendtty "ATE1....Switch terminal echo on+      sendtty "LOGIN......Drop to shell\n
-      sendtty "ATD?....Fork program ?.sh and output on terminal+      sendtty "SETUP......Change settings\n
-      sendtty "ATDT1...Open PPPD connection"​ +      sendtty "EXIT.......End this script\n
-      sendtty "ATZ.....Reset modem settings+      sendtty "\n" 
-      sendtty "HELP....Display command reference+      sendtty "​Common Hayes commands:​\n"​ 
-      sendtty "LOGIN...Fork a new linux login on serial+      sendtty "AT.........Tests serial ​connection, prints OK if successful\n
-      sendtty "EXIT....End this script+      sendtty "ATE0/ATE1..Switch terminal echo 0-off or 1-on\n
-      sendtty +      sendtty "ATD#.......Fork #.sh and output on terminal\n
-      sendtty "To establish connection over PPP, dial 1 using tone dialing ​(ATDT1)"​ +      sendtty "ATD1.......Fork ​1.sh, which by default starts ​PPP connection\n
-      sendtty +      sendtty "ATZ........Reset modem settings\n
-      sendtty "​READY."​+      sendtty ​"​\n"​ 
 +      sendtty "To establish connection over PPP, dial 1 (ATDT1)\n
 +      sendtty ​"​\n"​ 
 +      sendtty "​READY.\n"
     fi     fi
 +
 +    if [[ $cmd = "​SETUP"​ ]]; then
 +      while true; do
 +        # Display menu
 +        sendtty "​\n"​
 +        sendtty "​System Setup\n"​
 +        sendtty "​============\n"​
 +        sendtty "1. Change Wireless Network settings\n"​
 +        sendtty "2. Exit\n"​
 +        sendtty "Enter your selection: "
 +        # Read user input
 +        readtty selection
 +
 +        # Wireless network settings
 +        if [[ "​$selection"​ == "​1"​ ]]; then
 +          while true; do
 +            sendtty "​\n"​
 +            sendtty "Wi-Fi Settings\n"​
 +            sendtty "​==============\n"​
 +            sendtty "1. Connect to new Wi-Fi network\n"​
 +            sendtty "2. Modify password for current Wi-Fi network\n"​
 +            sendtty "3. Disconnect from current Wi-Fi network\n"​
 +            sendtty "4. Display current Wi-Fi connection status\n"​
 +            sendtty "5. Exit\n"​
 +            sendtty "Enter your selection: "
 +            # Read user input
 +            readtty selection
 +            # Connect to new Wi-Fi network
 +            if [[ "​$selection"​ == "​1"​ ]]; then
 +              sendtty "Enter SSID: "
 +              readtty ssid
 +              sendtty "Enter password: "
 +              readtty password
 +              sudo wpa_cli -i wlan0 remove_network 0
 +              sudo wpa_cli -i wlan0 add_network
 +              sudo wpa_cli -i wlan0 set_network 0 ssid "​\"​$ssid\""​
 +              sudo wpa_cli -i wlan0 set_network 0 psk "​\"​$password\""​
 +              sudo wpa_cli -i wlan0 select_network 0
 +              sudo wpa_cli -i wlan0 enable_network 0
 +            # Modify password for current Wi-Fi network
 +            elif [[ "​$selection"​ == "​2"​ ]]; then
 +              sendtty "Enter new password: "
 +              readtty password
 +              sudo wpa_cli -i wlan0 set_network 0 psk "​\"​$password\""​
 +            # Disconnect from current Wi-Fi network
 +            elif [[ "​$selection"​ == "​3"​ ]]; then
 +              sendtty "​Disconnecting from current Wi-Fi network\n"​
 +              sudo wpa_cli -i wlan0 disable_network 0
 +            # Display current Wi-Fi connection status
 +            elif [[ "​$selection"​ == "​4"​ ]]; then
 +              status=$(sudo wpa_cli -i wlan0 status)
 +              sendtty "​\n"​
 +              sendtty "Wi-fi connection status\n"​
 +              sendtty "​=======================\n"​
 +              sendtty "​$status"​
 +              sendtty "​\n"​
 +            # Exit
 +            elif [[ "​$selection"​ == "​5"​ ]]; then
 +              break
 +            # Invalid selection
 +            else
 +              sendtty "​Invalid selection. Please try again.\n"​
 +            fi
 +          done
 +        # Exit
 +        elif [[ "​$selection"​ == "​2"​ ]]; then
 +          sendtty "​Exited setup\n"​
 +          sendtty "​READY.\n"​
 +          break
 +        # Invalid selection
 +        else
 +          sendtty "​Invalid selection. Please try again.\n"​
 +        fi
 +      done
 +    fi
 +
  
     # LOGIN  -  FORK LOGIN SESSION     # LOGIN  -  FORK LOGIN SESSION
     if [[ $cmd == LOGIN ]]; then     if [[ $cmd == LOGIN ]]; then
       exec 99>&​-       exec 99>&​-
-      /sbin/getty -8 -L ttyAMA0 ​$baud vt100+      /sbin/getty -8 -L $serport ​$baud $TERM
       ttyinit       ttyinit
       exec 99<>/​dev/​$serport       exec 99<>/​dev/​$serport
-      sendtty; sendtty "​READY."​+      sendtty ​"​\n"​; sendtty "​READY.\n"
     fi     fi
  
     # EXIT  -  EXIT SCRIPT     # EXIT  -  EXIT SCRIPT
-    if [ "​$cmd"​ = "​EXIT"​ ]; then sendtty "​OK";​ continue="​1";​ fi+    if [ "​$cmd"​ = "​EXIT"​ ]; then sendtty "OK\n"; continue="​1";​ fi
   fi   fi
   buffer=$buffer$char   buffer=$buffer$char
Line 303: Line 589:
  
 When Trumpet Winsock is in PPP mode, by default it will expect the following output after dialing the ISP's number and establishing a connection: ​ When Trumpet Winsock is in PPP mode, by default it will expect the following output after dialing the ISP's number and establishing a connection: ​
-  * A username prompt, matched by the text "​sername:"​ +  * A username prompt, matched by Trumpet with the text "​sername:"​ 
-  * A password prompt, matched by the text "​ssword:"​ +  * A password prompt, matched by Trumpet with the text "​ssword:"​ 
-  * A command prompt, matched by the text ">"​+  * A command prompt, matched by Trumpet with the character ​">"​
  
 This script has been tested with the default installation of Trumpet Winsock 3.0 revision D with PPP mode switched on. This script has also been tested with the default dial-up utility of Windows 95 and Windows 98 with PPP enabled. ​ This script has been tested with the default installation of Trumpet Winsock 3.0 revision D with PPP mode switched on. This script has also been tested with the default dial-up utility of Windows 95 and Windows 98 with PPP enabled. ​
  
-I've added a parameter to send an LCP echo to the client to test if the connection is still up. If the connection has abruptly been closed, pppd will know this by not receiving an echo reply, and will exit and relinquish control back to the vmodem.sh script. The only reason the timeout is in there, is because it seems like Trumpet Winsock 3.0 doesn'​t know how to tell pppd to terminate a PPP session from within a PPP session, and it will just attempt to hang up the call. As a result, pppd daemon will be left running indefinitely. This is obviously not preferred, so LCP echo is added to let pppd know when the link has been cut. If you can think of better ways to accomplish this check, feel free to send tips on how to improve the script.+I've added a parameter to send an LCP echo to the client to test if the connection is still up. If the connection has abruptly been closed, pppd will know this by not receiving an echo reply, and will exit and relinquish control back to the vmodem.sh script. The only reason the timeout is in there, is because it seems like Trumpet Winsock 3.0 doesn'​t know how to tell pppd to terminate a PPP session from within a PPP session, and it will just hang up the call. As a result, pppd daemon will be left running indefinitely ​and won't ever give control back to vmodem. This is obviously not preferred, so LCP echo is added to let pppd know when the link has been cut. If you can think of better ways to accomplish this check, feel free to send tips on how to improve the script.
  
 <code bash ppp.sh> <code bash ppp.sh>
 #!/bin/bash #!/bin/bash
 # RUN PPPD DAEMON # RUN PPPD DAEMON
 +#
 +# Oliver Molini 2021
 +
 +# Billy Stoughton II for bug fixes and contributions
 +#
 +# Licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
 +# https://​creativecommons.org/​licenses/​by-nc-sa/​4.0/​
 # #
 # Note on PPPD settings: # Note on PPPD settings:
Line 319: Line 612:
 # - Make sure DNS servers are defined (add ms-dns 1.2.3.4 twice) # - Make sure DNS servers are defined (add ms-dns 1.2.3.4 twice)
 # #
 +
 +# Variable: etherp
 +# Override the ethernet device to use to connect to your network.
 +# This is set in vmodem.sh, but can be overridden here.
 +#
 +# Default: ​   #​etherp=eth0 (commented out)
 +#​etherp=eth0
 +
 # Variable: lcpidle # Variable: lcpidle
 # Specifies the idle timeout period in seconds for lcp-echo-interval. # Specifies the idle timeout period in seconds for lcp-echo-interval.
Line 325: Line 626:
 # #
 # Default: ​   lcpidle=5 # Default: ​   lcpidle=5
-+lcpidle=10
-lcpidle=5+
  
 # #
Line 335: Line 635:
 # unless specifically told to expect one. # unless specifically told to expect one.
 # #
-printf ​"​\n`uname -sn`****\n"​ + 
-printf ​"\nUsername: "; sleep 1 +sleep 2 
-printf ​"\nPassword: "; sleep 1 +sendtty ​"\n\n`uname -sn`****\n\n" 
-printf ​"\nStarting ​pppd..."​ +sendtty  ​"Username: "; sleep 1; sendtty ​"\n" 
-printf ​"\nPPP>"+sendtty ​ "​Password: "; sleep 1; sendtty ​"\n" 
 +sendtty ​ "​Starting ​pppd...\n
 +sendtty  ​"PPP>"
 # End of fake login prompt. # End of fake login prompt.
  
Line 346: Line 648:
  
 # Share eth0 over ppp0 # Share eth0 over ppp0
-iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +iptables -t nat -A POSTROUTING -o $etherp ​-j MASQUERADE 
-iptables -t filter -A FORWARD -i ppp0 -o eth0 -m state --state RELATED,​ESTABLISHED -j ACCEPT +iptables -t filter -A FORWARD -i ppp0 -o $etherp ​-m state --state RELATED,​ESTABLISHED -j ACCEPT 
-iptables -t filter -A FORWARD -i eth0 -o ppp0 -j ACCEPT+iptables -t filter -A FORWARD -i $etherp ​-o ppp0 -j ACCEPT
  
 # Run PPP daemon and establish a link. # Run PPP daemon and establish a link.
Line 367: Line 669:
 # #
  
-echo "Hello World Demo Box!"​ +sendtty ​"Hello World Demo Box!\n
-echo "​---------------------"​ +sendtty ​"​---------------------\n
-echo +sendtty "​\n"​ 
-echo "You have just successfully dialed this virtual box!"​ +sendtty ​"You have just successfully dialed this virtual box!\n
-echo +sendtty "​\n"​ 
-echo "​Please enter your name: " +sendtty ​"​Please enter your name: \n
-read username +readtty ​username 
-echo +sendtty "​\n"​ 
-echo "​Hello,​ $username!"​ +sendtty ​"​Hello,​ $username!\n
-echo +sendtty "​\n"​ 
-echo "Thank you for visiting! Bye!"+sendtty ​"Thank you for visiting! Bye!\n"
 sleep 2 sleep 2
 +
 +</​code>​
 +
 +===== 3.sh =====
 +This example script allows VT100 compatible terminal access to the web by way of running lynx as soon as the number "​3"​ is dialed with "​ATD3"​. It demonstrates how to add a Linux based web browser for simple terminals.
 +
 +<code bash 3.sh>
 +#!/bin/bash
 +#
 +sendtty "​Terminal type set to $TERM. Running Lynx ..."
 +lynx
 </​code>​ </​code>​
  
guides/virtual_modem/script.1574121505.txt.gz · Last modified: 2019-11-18 23:58 by omolini