from serial import * #serial port library from threading import Thread #library to make a thread (I guess) from time import sleep #timer library import string #import the string handling library import sys import atexit import signal class TimeoutException(Exception): pass def serial_portFunc(): def timeout_handler(signum, frame): raise TimeoutException() old_handler = signal.signal(signal.SIGALRM, timeout_handler) signal.alarm(50) # triger alarm in 50 seconds try: global ser portAddress = '/dev/ttyUSB1' portName = portAddress[-4:] portExist = os.popen('dmesg | grep ' + portName).read() if portExist == '': print 'The serial port does not exist' sys.exit() ser = Serial( port=portAddress, baudrate=19200, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE #timeout=0, #writeTimeout=0 #xonxoff=0, #rtscts=0 #interCharTimeout=None #I didn't need to set these variables :) ) ser.open() global last_received #make last_received a global variable global exitSuccessful global pickUp global signalStrength global signalStr signalStrength=0 ser.write('AT\r') #just communicate with the cellphone at start sleep(2) callTrue=0 #use this variable to make sure the cell phone has dialed a number pickUp =0 #use to test if I pick up the call buffer = '' #make sure buffer variable is empty while True: #repeat the message accepting part forever #while ser.inWaiting()!=0: #####BEGIN part responsible for receiving on serial port buffer = buffer + ser.read(ser.inWaiting()) #read the serial port and add it to the buffer variable if '\n' in buffer: #if a new line character is found in the buffer then the cellphone has sent something lines = buffer.split('\n') #parse the buffer variable with the new line character last_received = lines.pop(0) #put into last_received variable the first content from lines (FIFO) buffer = '\n'.join(lines) #add a new line to the buffer variable last_received=last_received.split('\n') #parse the last received value with new lines line = last_received[0].replace(chr(13), '') #remove \r from the first parsed value in last_received and return me a nicely parsed value :) #print line; #####END part responsible for receiving on serial port #####START of the state machine responsible for talking to the cellphone if len(line) > 0: #if line not empty then it is a value the cellphone returned #print 'I received:',line, len(line) if line=='RING': #the cellphone is ringing and somebody is calling if pickUp == 0: sleep(1) ser.write('ATA\r') #pick up the phone call sleep(0.5) #wait half a second before sending another AT command sleep(1) ser.write('AT+CSQ\r') #tell me the signal quality sleep(2) sleep(1) ser.write('AT+CLCC\r') #ask for the callers numbers line='' if line[0:5] == '+CSQ:': space = int(string.find(line,' '))+1 #find the (space) sign coma = int(string.find(line,',')) #find the , (coma) sign signalStr = (int(line[space:coma])*2)-113 #print 'Signal strength', signalStrength, 'dBm' line='' if line[0:6]=='+CLCC:': #+CLCC at the start of replied string means the phone responded with caller's numbers pickUp = 1 #here I can be sure that I picked up the phone #print 'I have the calling number' sleep(1) ser.write('AT+CHUP\r') #hang up the call pickUp = 0 #here I can be sure that I hang up the call #ser.write('AT\r') sleep(2) ###BEGIN extract me the phone number inside the quotes +CLCC: 1,1,0,0,0,"474",129 26, e.g. 474 quotation1 = int(string.find(line,'"'))+1 #find the first " (quotation) sign lineTemp = line[quotation1:] #remove from the line everything before and including " sign quotation2 = int(string.find(lineTemp,'"')) #find the first " (quotation) sign in the new line (lineTemp) numberOfCaller = line[quotation1:quotation1+quotation2] #from the old line variable just extract the phone number callBackNumber='ATD' + numberOfCaller + ';\r' #make the command for calling the number ###END extract me the phone number inside the quotes +CLCC: 1,1,0,0,0,"474",129 26, e.g. 474 #print callBackNumber sleep(1) ser.write(callBackNumber) callTrue=1 line='' sleep(3) signalStr = '|1|'+str(signalStr)+'|' exitSuccessful = 1 #sleep(1) #sys.exit() sleep(6) ser.write('AT+CHUP\r') sleep(1) ser.close() return signalStr if len(line) == 4: if line == 'BUSY': if callTrue == 1: signalStr = '|0|Number was busy|' return '|0|Number was busy|' #####END of the state machine responsible for talking to the cellphone except TimeoutException: return "|2|Timeout" finally: signal.signal(signal.SIGALRM, old_handler) signal.alarm(0) return signalStr if __name__ == '__main__': result = serial_portFunc() print result