From 512478f871169eb41a25005d37de98d7d61ca6f3 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Wed, 11 Jan 2017 16:36:08 -0800 Subject: [PATCH 1/3] Add vim modeline to preserve 8-byte tabs Otherwise, Tim is likely to inadvertently convert some tabs to spaces, and indent things wrong. --- serio | 1 + 1 file changed, 1 insertion(+) diff --git a/serio b/serio index 40093eb..254d5fe 100755 --- a/serio +++ b/serio @@ -1,4 +1,5 @@ #!/usr/bin/env python +# vim: set ts=8 sw=8 sts=8 noet : # upload/download files to an embedded Linux system via a serial port shell From ce8821353ebe859d21490b393483a6665d5d0c24 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Tue, 6 Dec 2016 01:08:25 -0800 Subject: [PATCH 2/3] Add unit test for serio program --- serio-test.sh | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100755 serio-test.sh diff --git a/serio-test.sh b/serio-test.sh new file mode 100755 index 0000000..281d229 --- /dev/null +++ b/serio-test.sh @@ -0,0 +1,161 @@ +#!/bin/bash +# serio-test.sh - unit test for serio +# + +verbose=0 +if [ "x$1" == "x-v" ] ; then + verbose=1 + shift +fi + +if [ "x$1" == "x--debug" ] ; then + set -x + shift +fi + +if [ "x$1" == "x-h" ] ; then + echo "usage: serio-test.sh [-v] [--debug] [-h] [-nc]" + echo " -v Be verbose" + echo " --debug Print each shell line as it is executed" + echo " -h Show this usage help" + echo " -nc Don't clean up test files" + exit 1 +fi + +SERIAL_DEV=/dev/ttyACM1 +target_dir=/home/a + +FILELIST="file1 file2 file3" +FILELIST="file1 file2" + +# set this to something to wait between operations +SLEEP_TIME=0 +#SLEEP_TIME=30 + +# use this to control whether to use paranoid mode with serio +#PARANOID="-P" + +# use this to control whether to use basic mode (minimal commands) +#BASIC="-B" +SERIO_ARGS="-y $SERIAL_DEV $PARANOID $BASIC -t 0.05" + +function vecho { + if [ $verbose -gt 0 ] ; then + echo $@ + fi +} + +# create test files +echo " Creating files..." + +# make a super-small, super-safe file for file1 +echo "this is the first test file for serio" >file1 + +size=1 +file_arr=($FILELIST) +unset file_arr[0] +for f in ${file_arr[@]} ; do + vecho "Creating file ${f}" + ddout="/dev/null" + if [ $verbose -gt 0 ] ; then + ddout="/dev/stdout" + fi + dd if=/dev/urandom of=${f} bs=1000 count=${size} >$ddout 2>&1 + size=$(( $size * 10 )) + i=$(( $i + 1 )) +done + +######################### +# test put and get +# run some put and get tests, timing them + +#FILELIST="file1 file2 file3 file4" +#FILELIST=file1 + +test_num=1 + +echo "Putting files: $FILELIST" +## put some files +for f in $FILELIST ; do + vecho "Putting file ${f}" + /usr/bin/time -f " time for put of $f: %E" ./serio $SERIO_ARGS -p --source=$f --destination="${target_dir}/$f" ; + sleep $SLEEP_TIME +done + +## get some files +echo "Getting files: $FILE_LIST" +for f in $FILELIST ; do + ret_filename="${f}-return" + vecho " Getting file ${f} (into $ret_filename)" + /usr/bin/time -f " time for get of $f: %E" ./serio $SERIO_ARGS -g --source="${target_dir}/$f" --destination=$ret_filename ; + sleep $SLEEP_TIME + + if [ -e "$ret_filename" ] ; then + echo "ok $test_num - get of file $ret_filename" + else + echo "not ok $test_num - get of file $ret_filename" + fi + test_num=$(( $test_num + 1 )) +done + +if [ $verbose -gt 0 ] ; then + echo "Here are the checksums of testfiles" + cksum file* +fi + +function check_cksum { + local f="$1" + local fr="${f}-return" + + local fs=$(cksum $f | cut -d " " -f 1,2) + local frs=$(cksum $fr | cut -d " " -f 1,2) + + local desc="$test_num - check ${fr} cksum with ${f} cksum" + if [ "${f1s}" = "${f1rs}" ] ; then + echo "ok $desc" + else + echo "not ok $desc" + fi + test_num=$(( $test_num + 1 )) +} + +for f in $FILELIST ; do + check_cksum $f +done + +######################### +# test some commands +#./serio $SERIO_ARGS -c "echo hello there!" + +echo " Executing some commands" +vecho " Execute 'ls -l $target_dir'" +./serio $SERIO_ARGS -c "ls -l $target_dir" + +vecho " Execute 'echo hello there'" +res1=$(./serio $SERIO_ARGS -c "echo hello there") +exp1=$'hello there' + +echo "expected : [$exp1]" +echo "got result: [$res1]" + +desc="$test_num - run 'echo hello there' on target" +if [ "$res1" = "$exp1" ] ; then + echo "ok $desc" +else + echo "not ok $desc" +fi + +######################### +# test cleanup + +function cleanup { + # remove test files + echo "Doing cleanup" + ./serio -y $SERIAL_DEV -c "rm ${target_dir}/file[12345]" + rm file[12345] + rm file[12345]-return +} + +if [ ! "x$1" == "x-nc" ] ; then + cleanup +fi From ad0deed02570368e807b0835d26c31d6cf349273 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Wed, 11 Jan 2017 16:35:47 -0800 Subject: [PATCH 3/3] Add support for command execution on remote target --- serio | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/serio b/serio index 254d5fe..5b447ad 100755 --- a/serio +++ b/serio @@ -220,8 +220,6 @@ class RemoteExecute: return mode, outfile.getvalue() - - def putfile(self, data, filename): i = 0 j = 0 @@ -286,6 +284,21 @@ class RemoteExecute: def close(self): self.fp.close() + def cmd(self, cmd_str, timeout=None): + delim="[[&&%s&&]]" % "serio_cmd_done" + self.fp.write(cmd_str + ' ; echo "%s"\n' % delim) + line = self.fp.readline() + + # should do this in a thread so we can output while + # the data is coming back + # FIXTHIS - use timeout here + result = self.readuntil(None, None, delim) + + # Sending output over a terminal turns all \n's to \r\n's + result = result.replace("\r\n", "\n") + return result + + class SerialTerminal(RemoteExecute): def __init__(self, basic, checksum, port, baudrate, io_time): @@ -297,12 +310,6 @@ class SerialTerminal(RemoteExecute): self.serial.open() RemoteExecute.__init__(self, fp=self.serial, io_time=io_time) - - - - - - def usage(): print '\nUsage: %s [OPTIONS]\n' % os.path.basename(sys.argv[0]) print ' -b, --baudrate= Serial port baud rate [115200]' @@ -311,6 +318,7 @@ def usage(): print ' -g, --get Get a file from the remote system' print ' -h, --help Show help' print ' -p, --put Put a file to the remote system' + print ' -c, --cmd="command with args" Execute a command on the remote system' print ' -M, --md5sum verify file transfer with md5sum' print ' -m, --minicom= Name of the minicom config file to use' print ' -P, --paranoid Assume target is fragile, be conservative' @@ -362,10 +370,11 @@ def main(): try: opts, args = GetOpt(sys.argv[1:], - 'b:Bd:ghMm:pPs:t:vy:', + 'b:Bc:d:ghMm:pPs:t:vy:', [ 'baudrate=', 'basic', + 'cmd=', 'destination=', 'get', 'help' @@ -388,6 +397,9 @@ def main(): baudrate = arg elif opt in ('-B', '--basic'): basic = 1 + elif opt in ('-c', '--cmd'): + action = 'cmd' + cmd_str = arg elif opt in ('-d', '--destination'): destination = arg elif opt in ('-g', '--get'): @@ -419,12 +431,13 @@ def main(): print 'Usage error: must specify either -g or -p options' usage() - if not source: - print 'Usage error: must specify the -s option' - usage() + if action in ['get','put']: + if not source: + print 'Usage error: must specify the -s option' + usage() - if destination is None or destination == ".": - destination = os.path.basename(source) + if destination is None or destination == ".": + destination = os.path.basename(source) if minicom is not None: port = minicom.port() @@ -456,6 +469,16 @@ def main(): except Exception, e: print "\nERROR:", e sys.exit(3) + + elif action == 'cmd': + try: + data = sterm.cmd(cmd_str) + if len(data): + print data + except Exception, e: + print "ERROR:", e + else: + print "ERROR: unknown action '%s'" % action sterm.close() @@ -463,4 +486,3 @@ def main(): if __name__ == '__main__': main() -