Help with 56kbit Modem Scripting

Hi all,

I have been working on an unique script of my own, which should be able to communicate with a classic 56kbit modem. I am quite a newbie to the scripting, but I suppose I am slowly making a progress.

At the beginning I had no idea how I was supposed to communicate with the modem. I am a Mac user (but I am using Debian as well) and I use the Terminal app mostly for everything and it works pretty fine, I'd say. For a physical connection with the modem I am using a USB-to-RS232 (serial port) adapter (AXAGO ADS-50) at /dev/cu.usbserial*.

For turning on the TR (terminal ready) signal I have already used a cat command followed by a ampersand to make it go to the background. At this point I mark a PID number to myself to kill it afterwards. (I am having some problems with a jobs implementation at the moment.)

To the modem I send AT commands using the echo command, eg. echo -n ATH^M > /dev/cu.usbserial*. (The ^M sing at the end is a combination of CTRL-V and CTRL-M characters.)

The script(s) itself works quite fine. It initialises the modem, makes it go offhook, even is able to make a genuine connection between two 56kbit modems. I can send text strings through the modems to each other and I am working on a simple script which can send (cat > device) simple text files.

And here comes the problem. Just today I have found out how to hang-up the modem, but since I process ATH0 to one modem and the other one hangs as well, the second modem also drops the cat > device process, the TR signal of this modem is still on and I cannot use it anymore untill reboot. I tried to kill that process with kill PID, but it cannot be found even in the ps ax list. If I kill the process before the dialling and making of connection, the TR signal successfully disappears.

I am stuck at this point and I have no idea, how could I make it work properly. I have realised that the second modem sends a EOF signal (^D) to the log before the cat process drops.

I would be glad for any help. Thank you and sorry for a long post and a poor level of my English.

  • krustowski (krusty was not available already)

You can do better than cat, and should use printf, which supports escape sequences natively:

#!/bin/bash
trap "echo 'whoa doggies'" SIGHUP

exec 5<> /dev/cu.usbserial* # BASH required for bidirectional open

printf "ATH\r\n" >&5

SIGHUP is what kills processes when a terminal closes, which a shell can catch and respond to as it pleases.

Also check out man stty for a parade of options related to terminal devices, serial ports, and modems, including such things as cr-lf translation and flow control.

1 Like

Have you thought about using exec to redirect all of the output to the modem?
Another option would be to write C or Java code to do the scripting.

export CURR_TIME=`/bin/date +%Y%m%d_%H%M%S`
exec  >/dev/cu.usbserial*
exec 2>/home/user/log/modem_connection_${CURR_TIME}.log
printf "...

I can't help but wonder why in this increasingly connected world someone would
want to do anything with a modem. What can you do using a modem that you can't
do using the internet?

1 Like

There's still a few corner cases here and there, like old POS applications. I had to dig out an external 56K modem to deal with an old food service's reporting program. They'd just upgraded their hardware, and their crummy afterthought of a winmodem didn't work two boots out of three. That place was fascinating - four generations of computers gathering dust on the shelves. Eight-inch floppy disks. The works.

Other applications: Some cell phones pretend to be a modem, with extended AT commands to send text messages.

And in the developing world, modems are alive and well. There's been renewed interest in dialup connections, deferred-transfer things like UUCP, etc.

Thank you both for reply! Unfortunately, I am not quite sure how to use the exec command. It seems like that the tother method (<>) is quite useful, but I have no idea how can I write to the log continuously.

The reason is simple � I am interested in these old devices, because it is not that hard to make them work and it is quite fun to explore the old times' networking.

You use it like I show it, basically. It's among other things the shell's "open a file" setting. Here I use it to open file descriptor 5, in read-write <> mode.

File descriptors 0, 1, and 2 are standard in, standard out, and standard error, respectively. Numbers 3 and up are generally not opened yet in a shell and can be used as you please.

exec 6<inputfile # Open file for read
read LINE <&6 # Read a line from it
exec 6<&- # Close file

exec 7>logfile # open a file for write
echo asdf > &7 # Write to file
exec 7>&- # Close file

Does my code not work, or not fulfill your purpose? What is your question?

In my script I use the cat and echo commands like this:

cat $DEVICE > $LOG &
echo -e "sth" > $DEVICE

And I want to use exec instead, but I have no idea how can I capture the device to the log and printf to the same descriptor. I need the capturing of the modem to check (by grep) if there is any OK response or for example the CONNECT response.

Stumbled across an old thread I posted in involving modems. Instead of grepping a logfile, you can set timeouts via stty.

#!/bin/bash

MODEM="/dev/ttyS3"

function get_response
{
        local ECHO
        # cat will read the response, then die on timeout
        cat <&5 >$TMP &
        echo "$1" >&5
        # wait for cat to die
        wait $!

        exec 6<$TMP
        read ECHO <&6
        if [ "$ECHO" != "$1" ]
        then
                exec 6<&-
                return 1
        fi

        read ECHO <&6
        read RESPONSE <&6
        exec 6<&-
        return 0
}

TMP="./response"

# Clear out old response
: > $TMP

# Set modem with timeout of 5/10 a second
stty -F "$MODEM" 9600 -echo igncr -icanon onlcr ixon min 0 time 5

# Open modem on FD 5
exec 5<>"$MODEM"

get_response "AT+CGMI" || echo "Bad response"
echo "Response was '${RESPONSE}'"       ;       cat $TMP

echo

get_response "AT" || echo "Bad response"
echo "Response was '${RESPONSE}'"       ;       cat $TMP

exec 5<&-