This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
guides:virtual_modem:script [2021-01-24 23:52] omolini |
guides:virtual_modem:script [2022-12-28 03:25] 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 | + | A copy of vmodem can be also found at Github, at https://github.com/molivil/vmodem |
- | https://github.com/molivil/vmodem | + | |
===== vmodem.sh ===== | ===== vmodem.sh ===== | ||
Line 20: | Line 19: | ||
# VMODEM - Virtual Modem bootstrap | # VMODEM - Virtual Modem bootstrap | ||
# -------------------------------- | # -------------------------------- | ||
- | # Oliver Molini 2021 | + | # Oliver Molini 2020-2022 |
# | # | ||
- | # Billy Stoughton II for bug fixes and contributions | + | # 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 | ||
Line 33: | 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 Microsoft Windows 3.1 | + | # o Windows 3.1 |
- | # - Trumpet Winsock | + | # - Trumpet Winsock 3.0 revision D |
# | # | ||
- | # o Microsoft Windows 95 OSR 2.5 + DUN 1.4 | + | # o Windows 95 OSR 2.5 + DUN 1.4 |
- | # - Generic | + | # - Generic Modem |
# - Standard 28800 bps 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 49: | 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.5.3 | + | vmodver=1.7.0 |
# CONFIGURATION | # CONFIGURATION | ||
Line 80: | Line 88: | ||
# Variable: etherp | # Variable: etherp | ||
# Sets the name of the ethernet device for PPP connections. | # Sets the name of the ethernet device for PPP connections. | ||
- | # Usually eth0 for wired and wlan0 for wireless. | + | # |
+ | # eth0 for wired | ||
+ | # wlan0 for wireless | ||
# | # | ||
etherp=eth0 | etherp=eth0 | ||
Line 122: | 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 sendtty | ||
+ | export -f readtty | ||
export -f ttyinit | export -f ttyinit | ||
Line 139: | 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 "\n" |
- | sendtty "TYPE HELP FOR COMMANDS" | + | sendtty "TYPE \"HELP\" FOR COMMAND REFERENCE.\n" |
- | sendtty "READY." | + | 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 167: | Line 335: | ||
#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 |
# | # | ||
Line 173: | Line 341: | ||
# | # | ||
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 == 1 ]]; 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"; sleep 1; fi | + | |
- | if [ -f "$number.sh" ]; then | + | |
- | if [[ $resultverbose == 1 ]]; then sendtty "CONNECT $baud"; else sendtty "1"; fi | + | |
- | # Execute dialed script! | + | |
- | + | ||
- | # For compatibility, explicitly tell the terminal to default to CR/LF | + | |
- | # when pressing enter, to avoid cases where the terminal just sends CR. | + | |
- | echo -en "\x1b[20h" > /dev/$serport | + | |
- | + | ||
- | # Run script with getty | + | |
- | /sbin/getty -8 -L $serport $baud $TERM -n -l "./$number.sh" | + | |
- | + | ||
- | # Reset serial settings | + | |
- | ttyinit | + | |
- | result=3 | + | |
- | else | + | |
- | # Phone number is valid, but no internal script by that name exists | + | |
- | result=3 | + | |
- | fi | + | |
else | else | ||
- | # No number specified, return OK status code | + | # Phone number is valid, but no internal script by that name exists |
- | result=0 | + | result=3 |
fi | fi | ||
+ | number="" | ||
fi | fi | ||
Line 268: | Line 445: | ||
# | # | ||
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 a 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 | ||
Line 306: | Line 562: | ||
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 344: | Line 600: | ||
# RUN PPPD DAEMON | # RUN PPPD DAEMON | ||
# | # | ||
- | # Oliver Molini 2020 | + | # Oliver Molini 2021 |
# | # | ||
# Billy Stoughton II for bug fixes and contributions | # Billy Stoughton II for bug fixes and contributions | ||
Line 369: | Line 625: | ||
# | # | ||
# Default: lcpidle=5 | # Default: lcpidle=5 | ||
- | lcpidle=5 | + | lcpidle=10 |
# | # | ||
Line 378: | Line 634: | ||
# 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 410: | Line 668: | ||
# | # | ||
- | 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 -e -p "User? " 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 | ||