ttySx

Marco Mariani marco at sferacarta.com
Fri Sep 6 11:24:18 EDT 2002


On Fri, Sep 06, 2002 at 05:08:25PM +0200, Bo M. Maryniuck wrote:

> I've tried do somethig like:
> 
> modem = open('/dev/ttyS0', 'r+')
> modem.write('ATZ\r')
> modem.read() # Hang here forewer
> 
> This is bad. Then I've tried use several modules for serial port, wheere I can 
> write, but if I read, always get ''.
> 
> Perhaps I should figure out with DTR status and so on.... Any ideas?


Here it is.
Of course, the code is old and sucks. If you have problems with lock
files, I don't want to know :-)

If you or anybody patch it, I would like to know..





#
# modem.py
#

import os, time, signal

from termios import *


def timeout(signum, frame):
    raise IOError, "Timeout!"

speeds = {
    2400:B2400,
    4800:B4800,
    9600:B9600,
    19200:B19200,
    38400:B38400,
    57600:B57600,
    115200:B115200,
    230400:B230400,
    460800:B460800
    }



class Modem:
    devname=None
    lockname=None
    locked=0
    fd=-1
    old_term=None
    new_term=[
    #       iflag       oflag       cflag
            IGNPAR,     0,          CRTSCTS | CS8 | CLOCAL | CREAD,
    #       lflag       ispeed      ospeed
            0,          0,          0,
    #       cc
            ['\000']*32
    ]
    answer=[]


    def __init__(self,name):
        self.devname = name
        self.lockname = '/var/lock/LCK..%s' % name

    def purge(self):
        if self.fd>=0:
            self.alarm_on()
            try:
                os.close(self.fd)
            except:
                pass
            self.alarm_off()

        if self.locked:
            os.unlink(self.lockname)


    #
    # 0:  OK
    # -1: Errore
    #
    def __lock(self,last_try=0):
        try:
            fd = os.open(self.lockname, os.O_RDWR | os.O_EXCL | os.O_CREAT, 0644)
            os.write(fd,'%10s\n' % os.getpid())
            os.close(fd)
            self.locked = 1
            return
        except:
            if not last_try:
                time.sleep(0.2)
                pid = int(open(self.lockname,'r').readline())
                try:
                    os.kill(pid,0)
                    return -1
                except OSError:
                    os.unlink(self.lockname)
                    return self.__lock(last_try=1)
            else:
                return -1

    def alarm_on(self):
        signal.signal(signal.SIGALRM, timeout)
        signal.alarm(1)

    def alarm_off(self):
        signal.alarm(0)


    #
    # 0:  OK
    # -1: Errore
    #
    def open(self):
        if self.__lock():
            return -1

        self.alarm_on()

        try:
            self.fd = os.open ('/dev/'+self.devname, os.O_RDWR | os.O_NOCTTY);
        except:
            self.fd=-1

        self.alarm_off()

        return self.fd<0

    def term_init(self):
        try:
            self.old_term = tcgetattr(self.fd)
            self.new_term[6][VMIN]=1
            self.new_term[6][VTIME]=0
            tcflush(self.fd,TCIFLUSH)
            tcsetattr(self.fd,TCSANOW,self.new_term)
            self.set_speed(B2400)
            return 0
        except:
            return -1

    def term_reset(self):
        self.alarm_on()

        try:
            tcsetattr(self.fd,TCSANOW,self.old_term)
            retval = 0
        except:
            retval = -1

        self.alarm_off()
        return retval

    def set_speed(self,rate):
        if rate in speeds.keys():
            rate = speeds[rate]
        self.new_term[4] = rate
        self.new_term[5] = rate
        tcsetattr(self.fd,TCSANOW,self.new_term)

    def sendline(self,line):
        if not os.write(self.fd,line+'\015'):
            return 1

        time.sleep(0.2)

        self.answer=[]
        s=''
        while 1:
            self.alarm_on()
            try:
                c = os.read(self.fd,1)
            except:
                retval = -1
                break

            if c=='\015' or c=='\012':
                if s:
                    self.answer.append(s)
                if s=='OK':
                    retval = 0
                    break
                if s=='ERROR':
                    retval = 1
                    break
                s=''
            else:
                s += c

        self.alarm_off()

        return retval





More information about the Python-list mailing list