To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit f3aa4e20 authored by Roman Trüb's avatar Roman Trüb

added sanitizing of forwarded serial for direction "write"

parent 60119ff3
......@@ -41,7 +41,7 @@ targetos_list = ('tinyos', 'contiki', 'moterunner', 'other') # List with all
proc_list = [] # List with all running processes
dbbuf_proc = [] # Dbbuf process
msgQueueDbBuf = None # Queue used to send data to the DB buffer
##############################################################################
#
......@@ -68,8 +68,8 @@ class SerialError(Error):
#
##############################################################################
def sigterm_handler(signum, frame):
"""If the program is terminated by sending it the signal SIGTERM
(e.g. by executing 'kill') or SIGINT (pressing ctrl-c),
"""If the program is terminated by sending it the signal SIGTERM
(e.g. by executing 'kill') or SIGINT (pressing ctrl-c),
this signal handler is invoked for cleanup."""
syslog(LOG_INFO, "Main process received SIGTERM signal")
# Close serial forwarder object:
......@@ -94,7 +94,7 @@ class ServerSockets():
self.sock_listen_timeout = 0.2
self.connection = None
self.address = None
def start(self):
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
......@@ -105,7 +105,7 @@ class ServerSockets():
except:
self.sock = None
syslog(LOG_INFO, "Encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
def stop(self):
if self.sock != None:
try:
......@@ -118,7 +118,7 @@ class ServerSockets():
self.connection = None
self.address = None
self.sock = None
def waitForClient(self):
if self.sock != None:
# syslog(LOG_INFO, "Waiting for clients on socket %s:%d"%(self.sock_host, self.sock_port))
......@@ -133,20 +133,20 @@ class ServerSockets():
return self.connection
else:
raise socket.error
def disconnectClient(self):
if self.connection != None:
syslog(LOG_INFO, "Disconnect client %s:%d from socket %s:%d"%(self.address[0], self.address[1], self.sock_host, self.sock_port))
self.connection.close()
self.connection = None
self.address = None
def send(self, data):
if self.connection != None:
return self.connection.send(data)
else:
raise socket.error
def recv(self, bufsize=None):
if ((self.sock != None) and (self.connection != None)):
if bufsize == None:
......@@ -154,12 +154,12 @@ class ServerSockets():
return self.connection.recv(bufsize)
else:
raise socket.error
def isRunning(self):
if self.sock != None:
return True
return False
def clientConnected(self):
if self.connection != None:
return True
......@@ -182,7 +182,7 @@ class SerialForwarderStandard():
self.num_elements_rcv = 0 # Number of packets received by the process. For statistical information.
self.num_elements_snd = 0 # Number of packets sent by the process. For statistical information.
self.sf = None
def open(self):
try:
self.sf = serial.Serial(port=self.serialdev, baudrate=self.baudrate, timeout=self.read_timeout)
......@@ -190,7 +190,7 @@ class SerialForwarderStandard():
syslog(LOG_ERR, "SerialForwarderStandard could not initialize serial connection because: %s" % (str(sys.exc_info()[1])))
return None
syslog(LOG_INFO, "SerialForwarderStandard opened serial device %s with baudrate %d and timeout %d"%(self.serialdev, self.baudrate, self.read_timeout))
def close(self):
try:
if self.sf != None:
......@@ -200,12 +200,12 @@ class SerialForwarderStandard():
finally:
self.sf = None
syslog(LOG_INFO, "SerialForwarderStandard stopped...%d packets received, %d packets sent."%(self.num_elements_rcv, self.num_elements_snd))
def isRunning(self):
if self.sf != None:
return True
return False
def read(self):
ret = None
try:
......@@ -223,15 +223,15 @@ class SerialForwarderStandard():
syslog(LOG_INFO, "SerialForwarderStandard interrupted due to caught stop signal.")
return None
except OSError, err:
syslog(LOG_ERR, "SerialForwarderStandard error while reading from serial forwarder: %s" %str(err))
syslog(LOG_ERR, "SerialForwarderStandard error while reading from serial forwarder: %s" %str(err))
self.close()
except SerialException, err:
syslog(LOG_ERR, "SerialForwarderStandard error while reading from serial forwarder: %s" %str(err))
syslog(LOG_ERR, "SerialForwarderStandard error while reading from serial forwarder: %s" %str(err))
self.close()
except:
syslog(LOG_ERR, "SerialForwarderStandard encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
return ret
def write(self, data):
try:
rs = self.sf.write(data)
......@@ -243,7 +243,7 @@ class SerialForwarderStandard():
syslog(LOG_INFO, "SerialForwarderStandard interrupted due to caught stop signal.")
return None
except OSError, err:
syslog(LOG_ERR, "SerialForwarderStandard error while writing to serial forwarder: %s" %str(err))
syslog(LOG_ERR, "SerialForwarderStandard error while writing to serial forwarder: %s" %str(err))
self.close()
except:
syslog(LOG_ERR, "SerialForwarderStandard encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
......@@ -272,7 +272,7 @@ class SerialForwarderTinyOS():
self.sf_proc = None
self.blocksize = config.getint("serial", "tinyos_blocksize")
self.sf_proto_len = -1
def open(self):
try:
self.sf_proc = subprocess.Popen(["sf", "control-port", str(self.control_port), "daemon"], close_fds = True)
......@@ -296,12 +296,12 @@ class SerialForwarderTinyOS():
syslog(LOG_INFO, "SerialForwarderTinyOS completed handshake with SF server")
else:
raise Exception
syslog(LOG_INFO, "SerialForwarderTinyOS started SF server for device %s with baudrate %d and timeout %d at port %d"%(self.serialdev, self.baudrate, self.read_timeout, self.listen_port))
syslog(LOG_INFO, "SerialForwarderTinyOS started SF server for device %s with baudrate %d and timeout %d at port %d"%(self.serialdev, self.baudrate, self.read_timeout, self.listen_port))
except Exception, err:
syslog(LOG_ERR, "SerialForwarderTinyOS could not initialize SF server because: %s" % (str(sys.exc_info()[1])))
return None
syslog(LOG_INFO, "SerialForwarderTinyOS opened SF server.")
def close(self):
try:
if self.sf != None:
......@@ -322,12 +322,12 @@ class SerialForwarderTinyOS():
finally:
self.sf = None
syslog(LOG_INFO, "SerialForwarderTinyOS stopped...%d packets received, %d packets sent."%(self.num_elements_rcv, self.num_elements_snd))
def isRunning(self):
if self.sf != None:
return True
return False
def check_sf_proc(self):
_ret = self.sf_proc.poll()
if _ret != None:
......@@ -337,7 +337,7 @@ class SerialForwarderTinyOS():
self.open()
except:
syslog(LOG_ERR, "SerialForwarderTinyOS could not restart TinyOS serial forwarder because of error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
def read(self):
ret = None
try:
......@@ -369,7 +369,7 @@ class SerialForwarderTinyOS():
except:
syslog(LOG_ERR, "SerialForwarderTinyOS encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
return ret
def write(self, data):
try:
rs = self.sf.send(data)
......@@ -377,7 +377,7 @@ class SerialForwarderTinyOS():
syslog(LOG_ERR, "SerialForwarderTinyOS error while writing: no of bytes written (%d) != no of bytes in data (%d)." %str(rs, len(data)))
self.num_elements_snd = self.num_elements_snd + 1
except socket.error, err:
syslog(LOG_ERR, "SerialForwarderTinyOS error while writing to serial forwarder: %s" %str(err))
syslog(LOG_ERR, "SerialForwarderTinyOS error while writing to serial forwarder: %s" %str(err))
self.close()
except:
syslog(LOG_ERR, "SerialForwarderTinyOS encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
......@@ -400,7 +400,7 @@ class SerialForwarderContiki():
self.num_elements_rcv = 0 # Number of packets received by the process. For statistical information.
self.num_elements_snd = 0 # Number of packets sent by the process. For statistical information.
self.sf_proc = None
def open(self):
try:
self.sf_proc = subprocess.Popen([self.serialdump_path, '-b%d'%self.baudrate, '-s', '%s'%self.serialdev], stdout=subprocess.PIPE, stdin=subprocess.PIPE, close_fds=False)
......@@ -409,7 +409,7 @@ class SerialForwarderContiki():
syslog(LOG_ERR, "SerialForwarderContiki could not start contiki serialdump because: %s" % (str(sys.exc_info()[1])))
return None
syslog(LOG_INFO, "SerialForwarderContiki opened.")
def close(self):
try:
if self.sf_proc != None:
......@@ -421,12 +421,12 @@ class SerialForwarderContiki():
finally:
self.sf_proc = None
syslog(LOG_INFO, "SerialForwarderContiki stopped...%d packets received, %d packets sent."%(self.num_elements_rcv, self.num_elements_snd))
def isRunning(self):
if ((self.sf_proc != None) and (self.sf_proc.poll() == None)):
return True
return False
def read(self):
ret = None
# Get data from serialdump:
......@@ -435,7 +435,7 @@ class SerialForwarderContiki():
if (data != ''):
# Useful data was retrieved, insert it into queue:
timestamp = time.time()
self.num_elements_rcv = self.num_elements_rcv +1
self.num_elements_rcv = self.num_elements_rcv +1
ret = [data.encode("hex"), timestamp]
except select.error, err:
if (err[0] == 4):
......@@ -443,7 +443,7 @@ class SerialForwarderContiki():
except:
syslog(LOG_ERR, "SerialForwarderContiki encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
return ret
def write(self, data):
try:
rs = self.sf_proc.stdin.write(data)
......@@ -451,7 +451,7 @@ class SerialForwarderContiki():
syslog(LOG_ERR, "SerialForwarderContiki error while writing: no of bytes written (%d) != no of bytes in data (%d)." %str(rs, len(data)))
self.num_elements_snd = self.num_elements_snd + 1
except socket.error, err:
syslog(LOG_ERR, "SerialForwarderContiki error while writing to serial forwarder: %s" %str(err))
syslog(LOG_ERR, "SerialForwarderContiki error while writing to serial forwarder: %s" %str(err))
self.close()
except:
syslog(LOG_ERR, "SerialForwarderContiki encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
......@@ -479,7 +479,7 @@ class SerialForwarderMoterunner():
self.lipproxy_path = '/usr/bin/lip-proxy'
self.sf = None
self.lipproxy = None
def open(self):
try:
self.lipproxy = multiprocessing.Process(target=ProcSfMoterunnerLipproxy, args=(self.serialdev, self.lipproxy_path, self.lipproxy_socketpath, self.lipproxy_port), name='sfmoterunner_lip')
......@@ -510,7 +510,7 @@ class SerialForwarderMoterunner():
syslog(LOG_ERR, "SerialForwarderMoterunner could not open socket to lip-proxy because of error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
return None
syslog(LOG_INFO, "SerialForwarderMoterunner opened.")
def close(self):
# Close connection to socket:
try:
......@@ -518,7 +518,7 @@ class SerialForwarderMoterunner():
self.sf.shutdown(socket.SHUT_RDWR)
self.sf.close()
os.unlink(self.lipproxy_socketpath)
syslog(LOG_INFO, "SerialForwarderMoterunner closed socket successfully.")
syslog(LOG_INFO, "SerialForwarderMoterunner closed socket successfully.")
except OSError, err:
if err.errno == 2:
pass
......@@ -539,13 +539,13 @@ class SerialForwarderMoterunner():
syslog(LOG_ERR, "SerialForwarderMoterunner could not stop lip-proxy because of error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
finally:
self.lipproxy = None
syslog(LOG_INFO, "SerialForwarderMoterunner stopped...%d packets received, %d packets sent."%(self.num_elements_rcv, self.num_elements_snd))
syslog(LOG_INFO, "SerialForwarderMoterunner stopped...%d packets received, %d packets sent."%(self.num_elements_rcv, self.num_elements_snd))
def isRunning(self):
if ((self.lipproxy != None) and (self.lipproxy.poll() == None) and (self.sf != None)):
return True
return False
def read(self):
ret = None
try:
......@@ -562,7 +562,7 @@ class SerialForwarderMoterunner():
except:
syslog(LOG_ERR, "SerialForwarderMoterunner encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
return ret
def write(self, data):
try:
rlist, wlist, elist = select.select( [], [self.sf], [], self.read_timeout )
......@@ -574,7 +574,7 @@ class SerialForwarderMoterunner():
if (err[0] == 4):
syslog(LOG_INFO, "SerialForwarderMoterunner interrupted due to caught stop signal.")
except:
syslog(LOG_ERR, "SerialForwarderMoterunner encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
syslog(LOG_ERR, "SerialForwarderMoterunner encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
return None
### END SerialForwarderMoterunner
......@@ -588,11 +588,11 @@ class SerialForwarderMoterunner():
def ProcSfMoterunnerLipproxy(serialdev, lipproxy_path, lipproxy_socketpath, lipproxy_port):
_serialdev = os.path.realpath(serialdev)
_p = None
def _sigterm_handler(signum, frame):
syslog(LOG_INFO, "ProcSfMoterunnerLipproxy process received SIGTERM signal")
_p.terminate()
_p.terminate()
try:
syslog(LOG_INFO, "ProcSfMoterunnerLipproxy process starting lip-proxy for device %s with socketfile %s and port %d..."%(_serialdev, lipproxy_socketpath, lipproxy_port))
signal.signal(signal.SIGTERM, _sigterm_handler)
......@@ -624,8 +624,8 @@ def ThreadSerialReader(sf, mode, msgQueueDbBuf, msgQueueSockBuf, stopLock):
sf_err_back_init= 0.5 # Initial time to wait after error on opening serial port
sf_err_back_step= 0.5 # Time to increase backoff time to wait after error on opening serial port
sf_err_back_max = 5.0 # Maximum backoff time to wait after error on opening serial port
sf_err_backoff = sf_err_back_init # Time to wait after error on opening serial port
sf_err_backoff = sf_err_back_init # Time to wait after error on opening serial port
syslog(LOG_ERR, "ThreadSerialReader started.")
while stopLock.acquire(False):
stopLock.release()
......@@ -647,7 +647,7 @@ def ThreadSerialReader(sf, mode, msgQueueDbBuf, msgQueueSockBuf, stopLock):
try:
elem = sf.read()
if elem != None:
# Data has been received.
# Data has been received.
if elem[0] is None:
elem[0]=''
data = data + elem[0]
......@@ -669,18 +669,18 @@ def ThreadSerialReader(sf, mode, msgQueueDbBuf, msgQueueSockBuf, stopLock):
#syslog(LOG_INFO, "---> timestamp: %s, lastTimestamp: %s"%(str(timestamp), str(lastTimestamp)))
if len(data)>0:
try:
# In packet mode, the data can be handled directly. For ASCII/raw mode, data is collected for some time before being
# In packet mode, the data can be handled directly. For ASCII/raw mode, data is collected for some time before being
# put onto the DB buffer queue (to reduce the lines being generated in the CSV report file).
if mode == 'pck':
# Send data directly:
if len(data) > 0:
# Signal with 0, that data is from reader (use 1 for writer):
# Signal with 0, that data is from reader (use 1 for writer):
msgQueueDbBuf.put([0,data,timestamp], False)
data = ''
timestamp = lastTimestamp = 0
elif mode == 'ascii':
# Wait for more data to come. Process data if it either contains newline characters, becomes to big or
# Wait for more data to come. Process data if it either contains newline characters, becomes to big or
# if no new data is coming in for some time.
if ((data.find('\r') != -1) or (data.find('\n') != -1)) or (len(data)>maxCollectSize) or ((timestamp-lastTimestamp)>maxCollectTime):
if len(data) > 0:
......@@ -697,16 +697,16 @@ def ThreadSerialReader(sf, mode, msgQueueDbBuf, msgQueueSockBuf, stopLock):
# syslog(LOG_INFO, "---> lines: >%s<"%(str(lines)))
# syslog(LOG_INFO, "---> data-tail: >%s<"%(str(data)))
for line in lines:
# Signal with 0, that data is from reader (use 1 for writer):
# Signal with 0, that data is from reader (use 1 for writer):
msgQueueDbBuf.put([0,line,timestamp], False)
if data == '':
timestamp = lastTimestamp = 0
elif mode == 'raw':
# Wait for more data to come. Process data if it becomes to big or if no new data is coming in for some time.
if (len(data)>maxCollectSize) or ((timestamp-lastTimestamp)>maxCollectTime):
if len(data) > 0:
# Signal with 0, that data is from reader (use 1 for writer):
# Signal with 0, that data is from reader (use 1 for writer):
msgQueueDbBuf.put([0,data,timestamp], False)
data = ''
timestamp = lastTimestamp = 0
......@@ -724,7 +724,7 @@ def ThreadSerialReader(sf, mode, msgQueueDbBuf, msgQueueSockBuf, stopLock):
if sf.isRunning():
sf.close()
syslog(LOG_ERR, "ThreadSerialReader stopped.")
### END ThreadSerialReader()
......@@ -740,16 +740,16 @@ def ThreadSocketProxy(msgQueueSockBuf, ServerSock, sf, msgQueueDbBuf, mode, stop
message_queues = {}
connection = None
fd_to_socket = {}
try:
syslog(LOG_INFO, "ThreadSocketProxy started")
# Initialize poller:
poller = select.poll()
poller.register(msgQueueSockBuf._reader, READ_ONLY)
fd_to_socket[msgQueueSockBuf._reader.fileno()] = msgQueueSockBuf
# Let thread run until stopLock is acquired:
while stopLock.acquire(False):
stopLock.release()
......@@ -764,7 +764,7 @@ def ThreadSocketProxy(msgQueueSockBuf, ServerSock, sf, msgQueueDbBuf, mode, stop
# Wait for data:
# drop data if client is not connected
events = poller.poll(poll_timeout)
for fd, flag in events:
# Retrieve the actual socket from its file descriptor
s = fd_to_socket[fd]
......@@ -796,9 +796,14 @@ def ThreadSocketProxy(msgQueueSockBuf, ServerSock, sf, msgQueueDbBuf, mode, stop
# syslog(LOG_INFO, "<--- Wrote data to SF: >%s<"%(str(data)))
# Signal with 1, that data is from writer (use 0 for reader):
try:
msgQueueDbBuf.put([1, data, timestamp], False)
dataSanList = data.replace(b'\r', b'').split('\n')
for i, dataSan in enumerate(dataSanList):
ts = timestamp + i * 0.000001 # with sligthly different timestamps we make sure that ordering is preserved
msgQueueDbBuf.put([1, dataSan, ts], False)
except Queue.full:
syslog(LOG_ERR, "Queue msgQueueDbBuf full in ThreadSocketProxy, dropping data.")
except Exception:
syslog(LOG_ERR, "Serial data could not be sanitized, dropping data.")
elif s is msgQueueSockBuf:
# Retrieve element from queue:
item = msgQueueSockBuf.get()
......@@ -839,7 +844,7 @@ def ThreadSocketProxy(msgQueueSockBuf, ServerSock, sf, msgQueueDbBuf, mode, stop
ServerSock.stop()
except:
pass
except:
syslog(LOG_ERR, "ThreadSocketProxy encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
......@@ -859,7 +864,7 @@ def ProcDbBuf(msgQueueDbBuf, stopLock, testid):
_dbfile_creation_time = 0
_dbflushinterval = config.getint("serial", "dbflushinterval")
_obsdbfolder = "%s/%d" % (os.path.realpath(config.get("observer", 'obsdbfolder')),testid)
def _get_db_file_name():
return "%s/serial_%s.db" % (_obsdbfolder, time.strftime("%Y%m%d%H%M%S", time.gmtime()))
......@@ -867,7 +872,7 @@ def ProcDbBuf(msgQueueDbBuf, stopLock, testid):
syslog(LOG_INFO, "ProcDbBuf started")
# set lower priority
os.nice(1)
# Let process run until stoplock is acquired:
while stopLock.acquire(False):
stopLock.release()
......@@ -907,7 +912,7 @@ def ProcDbBuf(msgQueueDbBuf, stopLock, testid):
continue
except:
syslog(LOG_ERR, "ProcDbBuf encountered error in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
# Stop the process
syslog(LOG_INFO, "ProcDbBuf stopping... %d elements received "%_num_elements)
except:
......@@ -932,13 +937,13 @@ def ProcDbBuf(msgQueueDbBuf, stopLock, testid):
#
##############################################################################
def stop_on_sig(ret_val=SUCCESS):
"""Stop all serial forwarder threads and the output socket
"""Stop all serial forwarder threads and the output socket
and exit the application.
Arguments:
ret_val: Return value to exit the program with.
"""
global proc_list
# Close all threads:
syslog(LOG_INFO, "Closing %d processes/threads..."% len(proc_list))
for (proc,stopLock) in proc_list:
......@@ -954,7 +959,7 @@ def stop_on_sig(ret_val=SUCCESS):
syslog(LOG_ERR, "Could not stop process/thread.")
if proc.is_alive():
syslog(LOG_ERR, "Could not stop process/thread.")
# Stop dbbuf process:
syslog(LOG_INFO, "Closing ProcDbBuf process...")
try:
......@@ -970,14 +975,14 @@ def stop_on_sig(ret_val=SUCCESS):
syslog(LOG_ERR, "Could not stop ProcDbBuf process.")
if dbbuf_proc[0].is_alive():
syslog(LOG_ERR, "Could not stop ProcDbBuf process.")
# Remove the PID file if it exists:
if os.path.exists(pidfile):
try:
os.remove(pidfile)
except:
syslog(LOG_WARN, "Could not remove pid file.")
syslog(LOG_INFO, "FlockLab serial service stopped.")
# Close the syslog and terminate the program
closelog()
......@@ -991,7 +996,7 @@ def stop_on_sig(ret_val=SUCCESS):
#
##############################################################################
def stop_on_api():
"""Stop all already running serial reader processes
"""Stop all already running serial reader processes
"""
# Get PID of running serial reader (if any) from pidfile and send it the terminate signal.
try:
......@@ -1011,7 +1016,7 @@ def stop_on_api():
return SUCCESS
except (IOError, OSError):
#DEBUG syslog(LOG_ERR, "----->Main process: Error while trying to kill main process in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
# The pid file was most probably not present. This can have two causes:
# The pid file was most probably not present. This can have two causes:
# 1) The serial reader service is not running.
# 2) The serial reader service did not shut down correctly the last time.
# As consequence, try to kill all remaining serial reader servce threads (handles 1)) and if that
......@@ -1046,7 +1051,7 @@ def stop_on_api():
# Usage
#
##############################################################################
def usage():
def usage():
print "Usage: %s --targetos=<string> --testid=<int> [--port=<string>] [--baudrate=<int>] [--mode=<string>] [--socketport=<int>] [--stop] [--daemon] [--debug] [--help] [--version]" %sys.argv[0]
print "Options:"
print " --targetos=<string>\t\tOperating system running on the target node."
......@@ -1055,7 +1060,7 @@ def usage():
print " --port=<string>\t\tOptional. Port over which serial communication is done. Default is serial for moterunner, usb for all other."
print "\t\t\t\tPossible values are: %s" %(str(port_list))
print " --baudrate=<int>\t\tOptional. Baudrate of serial device. Default is 115200."
print "\t\t\t\tPossible values for targetos=contiki are: %s" %(str(baudrate_contiki2_list))
print "\t\t\t\tPossible values for targetos=contiki are: %s" %(str(baudrate_contiki2_list))
print "\t\t\t\tPossible values for other targets are: %s" %(str(baudrate_list))
print " --mode=<string>\t\tOptional. Defines output mode. Default is pck. Possible values are: %s" %(str(mode_list))
print "\t\t\t\tFor targetos=tinyos, specifies whether serial data transmitted will be as ASCII strings or packed in TOS messages."
......@@ -1077,7 +1082,7 @@ def usage():
#
##############################################################################
def main(argv):
global proc_list
global isdaemon
global dbbuf_proc
......@@ -1085,7 +1090,7 @@ def main(argv):
global config
global debug
global msgQueueDbBuf
port = 'usb' # Standard port. Can be overwritten by the user.
serialdev = None
baudrate = 115200 # Standard baudrate. Can be overwritten by the user.
......@@ -1095,18 +1100,18 @@ def main(argv):
testid = None
socketport = None
stop = False
# Open the syslog:
openlog('flocklab_serial', LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER)
# Get config:
config = flocklab.get_config()
if not config:
logger.warn("Could not read configuration file. Exiting...")
sys.exit(errno.EAGAIN)
# Get command line parameters.
try:
try:
opts, args = getopt.getopt(argv, "ehvqdt:p:m:b:i:l:", ["stop", "help", "version", "daemon", "debug", "targetos=", "port=", "mode=", "baudrate=", "testid=", "socketport="])
except getopt.GetoptError, err:
syslog(LOG_ERR, str(err))
......@@ -1162,27 +1167,27 @@ def main(argv):
syslog(LOG_ERR, "Wrong API usage")
usage()
sys.exit(errno.EINVAL)
# Check if the mandatory parameter --testid is set:
# Check if the mandatory parameter --testid is set:
if testid==None:
print "Wrong API usage"
syslog(LOG_ERR, "Wrong API usage")
usage()
sys.exit(errno.EINVAL)
pidfile = "%s/%s" %(config.get("observer", "pidfolder"), "flocklab_serial_%d.pid" % testid)
if stop:
rs = stop_on_api()
sys.exit(rs)
# Check if the mandatory parameter --targetos is set:
# Check if the mandatory parameter --targetos is set:
if targetos==None:
print "Wrong API usage"
syslog(LOG_ERR, "Wrong API usage")
usage()
sys.exit(errno.EINVAL)
# Check that if targetos=contiki, the baudrate is correct:
if targetos=='contiki':
if baudrate not in baudrate_contiki2_list:
......@@ -1190,7 +1195,7 @@ def main(argv):
print err
syslog(LOG_ERR, err)
sys.exit(errno.EINVAL)
# Check port for targetos=moterunner and set it to serial if needed:
if targetos=='moterunner':
if port != 'serial':
......@@ -1198,7 +1203,7 @@ def main(argv):
print err
syslog(LOG_WARNING, err)
port='serial'
""" Check if daemon option is on. If on, reopen the syslog without the ability to write to the console.
If the daemon option is on, later on the process will also be daemonized.
"""
......@@ -1210,30 +1215,30 @@ def main(argv):
else:
open(pidfile,'w').write("%d"%(os.getpid()))
# Find out which target interface is currently activated.
slotnr = flocklab.tg_interface_get()
slotnr = flocklab.tg_interface_get()
if not slotnr:
err = "No interface active. Please activate one first."
syslog(LOG_ERR, err)
sys.exit(errno.EINVAL)
syslog(LOG_INFO, "Active target interface detected as %d"%slotnr)
# Make sure the right power source is on:
if port == 'usb':
if port == 'usb':
serialdev = '/dev/flocklab/usb/target%d' %slotnr
flocklab.tg_usbpwr_set(slotnr, 1)
time.sleep(2.0)
elif port == 'serial':
serialdev = '/dev/ttyS1'
# Initialize message queues ---
msgQueueDbBuf = multiprocessing.Queue()
msgQueueSockBuf = multiprocessing.Queue()
# Initialize socket ---
if not socketport is None:
ServerSock = ServerSockets(socketport)
# Initialize serial forwarder ---
if (targetos == 'tinyos'):
if (mode == 'pck'):
......@@ -1249,7 +1254,7 @@ def main(argv):
sf = SerialForwarderMoterunner(slotnr,serialdev,baudrate)
elif (targetos == 'other'):
sf = SerialForwarderStandard(slotnr,serialdev,baudrate)
# Start process for DB buffer ---
stopLock = multiprocessing.Lock()
p = multiprocessing.Process(target=ProcDbBuf, args=(msgQueueDbBuf,stopLock, testid), name="ProcDbBuf")
......@@ -1268,7 +1273,7 @@ def main(argv):
syslog(LOG_ERR, "Error when starting DB buffer process in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
stop_on_sig(SUCCESS)
sys.exit(errno.ECONNABORTED)
# Start thread for serial reader ---
stopLock = multiprocessing.Lock()
p = threading.Thread(target=ThreadSerialReader, args=(sf,mode,msgQueueDbBuf,msgQueueSockBuf,stopLock))
......@@ -1287,7 +1292,7 @@ def main(argv):
syslog(LOG_ERR, "Error when starting serial reader thread in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
stop_on_sig(SUCCESS)
sys.exit(errno.ECONNABORTED)
# Start thread for socket proxy ---
if not socketport is None:
stopLock = multiprocessing.Lock()
......@@ -1308,22 +1313,22 @@ def main(argv):
syslog(LOG_ERR, "Error when starting socket proxy thread in line %d: %s: %s" % (traceback.tb_lineno(sys.exc_info()[2]), str(sys.exc_info()[0]), str(sys.exc_info()[1])))
stop_on_sig(SUCCESS)
sys.exit(errno.ECONNABORTED)
# Catch kill signal and ctrl-c
signal.signal(signal.SIGTERM, sigterm_handler)
signal.signal(signal.SIGINT, sigterm_handler)
syslog(LOG_INFO, "Signal handler registered")