py code to dial a modem

Roy Mathew roymath at yahoo.com
Fri Feb 8 14:40:10 EST 2002


#!/usr/bin/python

"""
------------------------------------------------------------------------
Here is a simple python program to dial a modem. The tty flag setting
is heavily borrowed from a perl/C program called dialstring somewhere
on the web. I don't have the original source anymore, so this meager
acknowledgement is all I can provide. Use freely, and if you would
like to let me know that you found this code useful/buggy, I would
like to hear from you; drop me a line at "roymath @ yahoo.com". (note
spam spoiled address). So far, only tested on linux (debian).

Roy Mathew (Feb/8/2002)

USAGE COMMENTS:
Invoke the program with any number of args; the args are 
concatenated, and only the digits in the args-strings are used.

I usually grep for a a string from my contact info file, and feed it to
the program. For example:
echo "bob smith: 305-555-2222" | xargs dial.py
will cause the sequence 305-555-2222 to be dialed.
------------------------------------------------------------------------
"""

import termios, sys, os, time, string, re

# a simple function to set the modem flags for dialout.
# I found that setting the termios flags was the only slightly tricky bit,
# so this is the most useful code here.
def setFlags(fd):

  [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] = termios.tcgetattr(fd)

  # input flags
  iflag = iflag & ~(termios.ISTRIP|termios.ICRNL)
  
  # output flags
  oflag = oflag & ~(termios.OPOST)
  
  # control flags
  cflag = cflag & ~(termios.CSIZE|termios.PARENB)
  cflag = cflag | termios.CS8 | termios.CLOCAL
  
  # local flags
  lflag = lflag & ~(termios.ICANON|termios.ISIG|termios.IEXTEN|termios.ECHO)
  
  cc[termios.VMIN]  = 1;
  cc[termios.VTIME] = 0;

  termios.tcsetattr(fd, termios.TCSADRAIN,
    [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])

# invoke the dialing sequence; trap exceptions/interrupts such as Ctrl-C,
# and reset the modem.
def dial(device, dialStr):
  fd = os.open(device, os.O_RDWR)
  old = termios.tcgetattr(fd)
  
  try:
      setFlags(fd)  
      os.write(fd, dialStr)
  
      # this could be a loop; could log to a file.
      print os.read(fd, 1024)
      sys.stdout.flush()
          
      time.sleep(10)
  finally:
      termios.tcsetattr(fd, termios.TCSADRAIN, old)

def constructDialSequence(args):
  # remove all non-numeric digits
  num = re.sub("[^\d\*,]", "", args)
  
  # add a 1 to all non local #s within the US.
  # Don't further modify intl. numbers either.
  # (remember match only looks
  # at the beginning of the string. I live in Florida, hence 305 is local)
  if not re.match("1", num) \
     and not re.match("305", num) \
     and not re.match("786", num) \
     and not re.match("011", num):
    num = "1%s" % num
  
  # if doing international, prepend a *70
  if re.match("011", num):
    num = "*70,%s" % num
  
  #initString = "ATZ\r\d ATQ0 V1 E1 S0=0 &C1 &D2 S11=55 +FCLASS=0\r\d"
  initString = ""
  
  dialString = "%sATS11=55DT%s\r" % (initString,num)
  return dialString


if __name__=='__main__':

  # concatenate all command line args to form a number.
  args = string.join(sys.argv[1:], "")
  dialString = constructDialSequence(args)
  
  print "dialing %s" % dialString
  dial("/dev/modem", dialString)



More information about the Python-list mailing list