Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 49 additions & 13 deletions serio
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,20 @@ import sys, os.path, math, time
import hashlib
import StringIO
import uu
import datetime
from getopt import GetoptError, getopt as GetOpt

# verbose
# 1 bytes uploaded/downloaded
# 2 progress
verbose = 0

debug = 0
def time_print(msg):
if debug:
time_str = datetime.datetime.now().strftime("%H:%M:%S.%f")
print "[%s] %s" % (time_str, msg)

# zero always will mean no checksum
CHECKSUM_NONE = 0
CHECKSUM_MD5SUM = 1
Expand Down Expand Up @@ -110,48 +117,63 @@ class RemoteExecute:
data = ""

if count is not None:

for i in range(0, count):
data = self.fp.read(1)
data += self.fp.read(1)
self.progress(len(data), count)

elif lines is not None:

for i in range(0, lines):
data += self.fp.readline()
self.progress(len(data), len(data))

elif delim is not None:

while not data.endswith(delim):
data += self.serial.read(1)
data += self.fp.read(1)
self.progress((len(data)-len(delim)), (len(data)-len(delim)))

data = data[0:-len(delim)]

self.progress(len(data), len(data))
if self.showprogress > 0:
print
return data

# read data from the serial port, for a fixed amount of time
# intended for short reads (e.g. to drain a small amount of
# data from the port, or to get the prompt)
def readuntil_time(self, duration):
saved_timeout = self.fp.timeout
self.fp.timeout = duration
data = self.fp.read(10000)
self.fp.timeout = saved_timeout
return data

def prime_before_first_execute(self):
# required before first call of execute(), after this
# program begins

cmd = "#"
cmd = "# pbfe"
time_print("pbfe: write:" + cmd + "\n")
self.fp.write(cmd + "\n")

# remote system shell echos command, slurp it up
cmd_echo = self.fp.readline()
time_print("pbfe: cmd_echo=[%s]" % cmd_echo)

# The probably will not be a prompt, becuase the remote
# The probably will not be a prompt, because the remote
# shell probably sent it before serio started execution.
# Check for the command with carriage return, newline.
# If the echoed command does not include this then
# repeat the readline().
#
if not cmd_echo.endswith(cmd + "\r\n"):
cmd_echo = self.fp.readline()
time_print("pbfe: cmd_echo=[%s]" % cmd_echo)

def get_prompt(self):
self.fp.write("# gp\n")
data = self.readuntil_time(1)
return data.strip()

def execute(self, cmd):
# This program MUST send a newline to the remote system once
Expand Down Expand Up @@ -186,6 +208,7 @@ class RemoteExecute:

if self.basic:
self.execute("cat '%s' && echo '%s'" % (filename, self.DELIM))

data = self.readuntil(delim=self.DELIM)

# Catting data over a terminal turns all \n's to \r\n's
Expand Down Expand Up @@ -256,6 +279,11 @@ class RemoteExecute:
# a newline, so this does not eliminate all traffic from the
# remote system, it just reduces it.
self._safe_write('stty -echo\n')
# drain the response from the serial buffer
junk = self.readuntil_time(1)

prompt = self.get_prompt()
time_print("putfile: prompt='%s'" % prompt)

# Create/zero the file
self._safe_write('echo -ne > %s\n' % filename)
Expand Down Expand Up @@ -285,6 +313,10 @@ class RemoteExecute:
# Show upload status
self.progress(i, data_size)

# wait for shell prompt before sending next line
recv_data = self.readuntil(delim=prompt)
time_print("putfile: received data=[%s]" % recv_data)

if self.showprogress:
print

Expand All @@ -294,6 +326,7 @@ class RemoteExecute:
return i

def _safe_write(self, data):
time_print("_safe_write:"+data)
self.fp.write(data)
if data.endswith('\n'):
# give the remote system time for disk/flash I/O
Expand All @@ -317,7 +350,6 @@ class RemoteExecute:

# should do this in a thread so we can output while
# the data is coming back
# FIXME - use timeout here
result = self.readuntil(None, None, self.DELIM)

if remote_shell:
Expand All @@ -335,10 +367,10 @@ class RemoteExecute:

class SerialTerminal(RemoteExecute):

def __init__(self, basic, checksum, port, baudrate, io_time):
def __init__(self, basic, checksum, port, baudrate, io_time, timeout):
self.basic = basic
self.checksum = checksum
self.serial = serial.Serial(port=port, baudrate=baudrate)
self.serial = serial.Serial(port=port, baudrate=baudrate, timeout=timeout)
already_open = self.serial.isOpen()
if not already_open:
self.serial.open()
Expand Down Expand Up @@ -411,6 +443,7 @@ def main():
checksum = CHECKSUM_NONE
destination = None
io_time = None
timeout = None
minicom = None
paranoid = None
port = '/dev/ttyUSB0'
Expand All @@ -419,7 +452,7 @@ def main():

try:
opts, args = GetOpt(sys.argv[1:],
'b:Bc:d:ghMNm:pPs:t:vy:',
'b:Bc:d:ghMNm:pPs:t:T:vy:',
['baudrate=',
'basic',
'cmd=',
Expand All @@ -433,6 +466,7 @@ def main():
'no-remote-shell',
'source=',
'time=',
'timeout=',
'verbose',
'port=',
]
Expand Down Expand Up @@ -471,6 +505,8 @@ def main():
source = arg
elif opt in ('-t', '--time'):
io_time = float(arg)
elif opt in ('-T', '--timeout'):
timeout = float(arg)
elif opt in ('-v', '--verbose'):
verbose += 1
elif opt in ('-y', '--port'):
Expand Down Expand Up @@ -499,7 +535,7 @@ def main():
port = minicom.port()
baudrate = minicom.baudrate()

sterm = SerialTerminal(basic, checksum, port, baudrate, io_time)
sterm = SerialTerminal(basic, checksum, port, baudrate, io_time, timeout)

if action == 'put':
try:
Expand Down
65 changes: 48 additions & 17 deletions serio-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ echo "
usage: ${script_name} [-v] [--debug] [-h] [-nc]

-B, --basic *Use basic (minimal) remote system commands
--debug Print each shell line as it is executed
-F, --numfile <count> Number of random data test files
--debug Print each shell line as it is executed
-F, --numfiles <count> Number of random data test files
-h, -help, --help Show help
-nc Don't clean up test files
-s, --sleep <seconds> Time to sleep between --get and --put tests [0.0]
-t, --time <seconds> *Delay in _safe_write()
-T, --timeout <seconds> *Timeout for serial port I/O operations
-y, --port <serial port> *Serial port to use [/dev/ttyUSB0]
--remote-dir <dir> Directory on remote system to put files into [.]
-R, --remote-dir <dir> Directory on remote system to put files into [.]
-v Be verbose

* Sets a serio command line option
Expand All @@ -44,10 +45,11 @@ unset SERIAL_DEV
unset PARANOID
unset SLEEP
unset TIME
unset TIMEOUT

do_cleanup=1
help=0
numfile=1
numfiles=2
remote_dir="."
verbose=0
while [ $# -gt 0 ] ; do
Expand All @@ -64,9 +66,9 @@ while [ $# -gt 0 ] ; do
set -x
;;

-F | --numfile )
-F | --numfiles )
shift
numfile=$1
numfiles=$1
shift
;;

Expand Down Expand Up @@ -98,7 +100,14 @@ while [ $# -gt 0 ] ; do
verbose=1
;;

-T | --remote-dir )
-T | --timeout )
shift
TIMEOUT="-T $1"
shift
verbose=1
;;

-R | --remote-dir )
shift
remote_dir="$1"
shift
Expand Down Expand Up @@ -148,13 +157,13 @@ fi
tmp_dir=$( mktemp --tmpdir -d serio-test.XXXXXXXXXX )


FILE_LIST="file_1"
for k in $( seq 2 $(( ${numfile} + 1 )) ) ; do
FILE_LIST=""
for k in $(seq ${numfiles}) ; do
FILE_LIST="${FILE_LIST} file_${k}"
done


SERIO_ARGS="$SERIAL_DEV $PARANOID $BASIC $TIME"
SERIO_ARGS="$SERIAL_DEV $PARANOID $BASIC $TIME $TIMEOUT"

# shell builtin 'time' does not recognize -f
TIME="/usr/bin/time"
Expand All @@ -177,7 +186,7 @@ vecho "SERIO = ${SERIO}"
echo "Creating files..."

# make a super-small, super-safe file for file1
echo "this is the first test file for serio" >file1
echo "this is the first test file for serio" >${tmp_dir}/file_short

if [ $verbose -gt 0 ] ; then
ddout="/dev/stdout"
Expand All @@ -194,6 +203,9 @@ for f in ${FILE_LIST} ; do
i=$(( $i + 1 ))
done

FILE_LIST="file_short ${FILE_LIST}"


#########################
# test put and get
# run some put and get tests, timing them
Expand Down Expand Up @@ -276,26 +288,45 @@ vecho " Execute 'ls -l $remote_dir'"
$SERIO $SERIO_ARGS -c "ls -l $remote_dir"

vecho " Execute 'echo hello there'"
res1=$($SERIO $SERIO_ARGS -c "echo hello there")
exp1=$'hello there'
res=$($SERIO $SERIO_ARGS -c "echo hello there")
rcode=$?
exp=$'hello there'

echo "expected : [$exp1]"
echo "got result: [$res1]"
echo "expected : [$exp], rcode=[0]"
echo "got result: [$res], rcode=[$rcode]"

desc="$test_num - run 'echo hello there' on remote"
if [ "$res1" = "$exp1" ] ; then
if [ "$res" = "$exp" -a "$rcode" = "0" ] ; then
echo "ok $desc"
else
echo "not ok $desc"
fi
test_num=$(( $test_num + 1 ))

vecho " Execute 'echo foo ; false'"
res=$($SERIO $SERIO_ARGS -c "echo foo ; false")
rcode=$?
exp=$'foo'
expcode=1

echo "expected : [$exp], rcode=[$expcode]"
echo "got result: [$res], rcode=[$rcode]"

desc="$test_num - run 'echo foo ; false' on remote"
if [ "$res" = "$exp" -a "$rcode" = "$expcode" ] ; then
echo "ok $desc"
else
echo "not ok $desc"
fi
test_num=$(( $test_num + 1 ))

#########################
# test cleanup

function cleanup {
# remove test files

$SERIO $SERIAL_DEV -c "rm ${remote_dir}/file_[1-9]*"
$SERIO $SERIAL_DEV -c "rm ${remote_dir}/file_[1-9]* ${remote_dir}/file_short"

rm -r ${tmp_dir}
}
Expand Down