From 11f9b780c84675268c5addf9ed590d544a287140 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 21 Sep 2015 10:59:15 +0200 Subject: [PATCH] Added tools for NXP JN516x --- tools/jn516x/JennicModuleProgrammer | Bin 0 -> 22124 bytes tools/jn516x/Makefile | 25 ++ tools/jn516x/mote-list.py | 94 +++++ tools/jn516x/motelist_lib/__init__.py | 0 .../motelist_lib/linux_motelist_impl.py | 220 ++++++++++ .../motelist_lib/windows_motelist_impl.py | 142 +++++++ tools/jn516x/serialdump.c | 396 ++++++++++++++++++ 7 files changed, 877 insertions(+) create mode 100644 tools/jn516x/JennicModuleProgrammer create mode 100644 tools/jn516x/Makefile create mode 100644 tools/jn516x/mote-list.py create mode 100644 tools/jn516x/motelist_lib/__init__.py create mode 100644 tools/jn516x/motelist_lib/linux_motelist_impl.py create mode 100644 tools/jn516x/motelist_lib/windows_motelist_impl.py create mode 100644 tools/jn516x/serialdump.c diff --git a/tools/jn516x/JennicModuleProgrammer b/tools/jn516x/JennicModuleProgrammer new file mode 100644 index 0000000000000000000000000000000000000000..eef29c284af33e8e04e3a2b0a943839499ee2f7d GIT binary patch literal 22124 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 K={Fx*%lUsGfeYIJ literal 0 HcmV?d00001 diff --git a/tools/jn516x/Makefile b/tools/jn516x/Makefile new file mode 100644 index 000000000..be3caa44b --- /dev/null +++ b/tools/jn516x/Makefile @@ -0,0 +1,25 @@ +ifndef HOST_OS + ifeq ($(OS),Windows_NT) + HOST_OS := Windows + else + HOST_OS := $(shell uname) + endif +endif + +ifeq ($(HOST_OS),Windows) + SERIALDUMP = serialdump-windows +endif + +ifeq ($(HOST_OS),Darwin) + SERIALDUMP = serialdump-macos +endif + +ifndef SERIALDUMP + # Assume Linux + SERIALDUMP = serialdump-linux +endif + +all: $(SERIALDUMP) + +$(SERIALDUMP): serialdump.c + $(CC) -O2 -o $@ $< diff --git a/tools/jn516x/mote-list.py b/tools/jn516x/mote-list.py new file mode 100644 index 000000000..170b04fdb --- /dev/null +++ b/tools/jn516x/mote-list.py @@ -0,0 +1,94 @@ +#!/usr/bin/python + +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the Institute nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This file is part of the Contiki operating system. +# + +import sys, os, platform +import multiprocessing + +# detect the operating system +sysname = platform.system() +if "Linux" in sysname: + IS_WINDOWS = False + FLASH_PROGRAMMER_DEFAULT_PATH = "/usr/jn-toolchain/tools/flashprogrammer/JennicModuleProgrammer" + import motelist_lib.linux_motelist_impl as motelist_impl # @UnusedImport + +elif ("Win" in sysname) or ("NT" in sysname): + IS_WINDOWS = True + FLASH_PROGRAMMER_DEFAULT_PATH = 'C:\\NXP\\bstudio_nxp\\sdk\\JN-SW-4163\\Tools\\flashprogrammer\\FlashCLI.exe' + import motelist_lib.windows_motelist_impl as motelist_impl # @Reimport @UnusedImport + +else: + print ("OS ('{}') is not supported".format(os.name)) + + +def main(): + # use the default location + flash_programmer = FLASH_PROGRAMMER_DEFAULT_PATH + if len(sys.argv) > 2: + flash_programmer=sys.argv[1] + + serial_dumper = "" + if len(sys.argv) > 3: + serial_dumper=sys.argv[3] + + motes = motelist_impl.list_motes(flash_programmer) + if motes: + motes.sort() + print 'Found %d JN516X motes at:' %(len(motes)) + motes_str = '' + for m in motes: + motes_str += "%s " %(str(m)) + print motes_str + + firmware_file='#' + if len(sys.argv) > 2: + firmware_file = sys.argv[2] + elif len(sys.argv) > 1: + firmware_file = sys.argv[1] + + if firmware_file[0] == '\\': + firmware_file = firmware_file[1:] + + if firmware_file not in ['#', '!', '?', '%']: + print '\nBatch programming all connected motes...\n' + motelist_impl.program_motes(flash_programmer, motes, firmware_file) + elif firmware_file == '?' or firmware_file == '!': + should_display_mac_list = (firmware_file == '!') + motelist_impl.print_info(flash_programmer, motes, should_display_mac_list) + elif firmware_file == '%': + print '\nLogging from all connected motes...\n' + motelist_impl.serialdump_ports(flash_programmer, serial_dumper, motes) + else: + print '\nNo firmware file specified.\n' + +if __name__ == '__main__': + multiprocessing.freeze_support() + main() diff --git a/tools/jn516x/motelist_lib/__init__.py b/tools/jn516x/motelist_lib/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tools/jn516x/motelist_lib/linux_motelist_impl.py b/tools/jn516x/motelist_lib/linux_motelist_impl.py new file mode 100644 index 000000000..231c7814f --- /dev/null +++ b/tools/jn516x/motelist_lib/linux_motelist_impl.py @@ -0,0 +1,220 @@ +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the Institute nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This file is part of the Contiki operating system. +# +# Author(s): +# Janis Judvaitis +# Atis Elsts + +import os, glob, re +import multiprocessing, subprocess + +FTDI_VENDOR_ID = "0403" +FTDI_PRODUCT_ID = "6001" + +doPrintVendorID = False + +def read_line(filename): + """helper function to read a single line from a file""" + line = "Unknown" + try: + with open(filename) as f: + line = f.readline().strip() + finally: + return line + +# try to extract descriptions from sysfs. this was done by experimenting, +# no guarantee that it works for all devices or in the future... + +def usb_sysfs_hw_string(sysfs_path): + """given a path to a usb device in sysfs, return a string describing it""" + snr = read_line(sysfs_path + '/serial') + if snr: + snr_txt = '%s' % (snr,) + else: + snr_txt = '' + if doPrintVendorID: + return 'USB VID:PID=%s:%s SNR=%s' % ( + read_line(sysfs_path + '/idVendor'), + read_line(sysfs_path + '/idProduct'), + snr_txt + ) + else: + return snr_txt + +def usb_string(sysfs_path): + # Get dir name in /sys/bus/usb/drivers/usb for current usb dev + dev = os.path.basename(os.path.realpath(sysfs_path)) + dev_dir = os.path.join("/sys/bus/usb/drivers/usb", dev) + + try: + # Go to usb dev directory + product = read_line(os.path.join(dev_dir, "product")) + manufacturer = read_line(os.path.join(dev_dir, "manufacturer")) + result = product + " by " + manufacturer + except: + result = "Unknown device" + + return result + +def describe(device): + """ + Get a human readable description. + For USB-Serial devices try to run lsusb to get a human readable description. + For USB-CDC devices read the description from sysfs. + """ + base = os.path.basename(device) + # USB-Serial devices + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if os.path.exists(sys_dev_path): + sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + return usb_string(sys_usb) + + # Arduino wants special handling + sys_dev_path = '/sys/class/tty/%s/device/driver/' % (base) + for x in os.listdir(sys_dev_path): + # Driver directory's name contains device ID in /sys/bus/usb/drivers/usb + temp = x.split(":") + if len(temp) == 2: + # No Arduino adds, need to save space! + return usb_string(temp[0]).replace("(www.arduino.cc)", "").strip() + + # USB-CDC devices + sys_dev_path = '/sys/class/tty/%s/device/interface' % (base,) + if os.path.exists(sys_dev_path): + return read_line(sys_dev_path) + + return base + +def hwinfo(device): + """Try to get a HW identification using sysfs""" + base = os.path.basename(device) + if os.path.exists('/sys/class/tty/%s/device' % (base,)): + # PCI based devices + sys_id_path = '/sys/class/tty/%s/device/id' % (base,) + if os.path.exists(sys_id_path): + return read_line(sys_id_path) + # USB-Serial devices + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if os.path.exists(sys_dev_path): + sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + return usb_sysfs_hw_string(sys_usb) + # USB-CDC devices + if base.startswith('ttyACM'): + sys_dev_path = '/sys/class/tty/%s/device' % (base,) + if os.path.exists(sys_dev_path): + return usb_sysfs_hw_string(sys_dev_path + '/..') + return 'n/a' # XXX directly remove these from the list? + +####################################### + +def is_nxp_mote(device): + base = os.path.basename(device) + # USB-Serial device? + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if not os.path.exists(sys_dev_path): + return False + + path_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + + dev = os.path.basename(os.path.realpath(path_usb)) + dev_dir = os.path.join("/sys/bus/usb/drivers/usb", dev) + + try: + idProduct = read_line(os.path.join(dev_dir, "idProduct")) + idVendor = read_line(os.path.join(dev_dir, "idVendor")) + if idVendor != FTDI_VENDOR_ID or idProduct != FTDI_PRODUCT_ID: + return False + product = read_line(os.path.join(dev_dir, "product")) + manufacturer = read_line(os.path.join(dev_dir, "manufacturer")) + if manufacturer != "NXP": + return False + except: + return False + return True + + +def list_motes(flash_programmer): + devices = glob.glob('/dev/ttyUSB*')# + glob.glob('/dev/ttyACM*') + return [d for d in devices if is_nxp_mote(d)] + + +def extract_information(port, stdout_value): + mac_str='Unknown' # not supported on Linux + info='' # not properly supported on Linux + is_program_success='' + + info = describe(port) + ", SerialID: " + hwinfo(port) + + res = re.compile('(Success)').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + else: + res = re.compile('(Error .*)\n').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + + return [mac_str, info, is_program_success] + + +def program_motes(flash_programmer, motes, firmware_file): + for m in motes: + cmd = [flash_programmer, '-v', '-s', m, '-I', '38400', '-P', '1000000', '-f', firmware_file] + cmd = " ".join(cmd) + proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + print m, is_program_success + + errors = (stderr_value) + if errors != '': + print 'Errors:', errors + + +def print_info(flash_programmer, motes, do_mac_only): + if do_mac_only: + print "Listing Mac addresses (not supported on Linux):" + else: + print "Listing mote info:" + + for m in motes: + [mac_str, info, is_program_success] = extract_information(m, '') + if do_mac_only: + print m, mac_str + else: + print m, '\n', info, '\n' + +def serialdump(args): + port_name = args[0] + serial_dumper = args[1] + rv = subprocess.call(serial_dumper + ' -b1000000 ' + port_name, shell=True) + +def serialdump_ports(flash_programmer, serial_dumper, ports): + p = multiprocessing.Pool() + p.map(serialdump, zip(ports, [serial_dumper] * len(ports))) + p.close() diff --git a/tools/jn516x/motelist_lib/windows_motelist_impl.py b/tools/jn516x/motelist_lib/windows_motelist_impl.py new file mode 100644 index 000000000..a4528484b --- /dev/null +++ b/tools/jn516x/motelist_lib/windows_motelist_impl.py @@ -0,0 +1,142 @@ +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the Institute nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This file is part of the Contiki operating system. +# +# Author(s): +# Simon Duquennoy +# Atis Elsts + +import os, re, subprocess, multiprocessing + +def list_motes(flash_programmer): + #There is no COM0 in windows. We use this to trigger an error message that lists all valid COM ports + cmd = [flash_programmer, '-c', 'COM0'] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + com_str = (stderr_value) + #print '\tpass through:', repr(stdout_value) + #print '\tstderr :', com_str + + ## Extract COM ports from output: + ## Example com_str: "Available ports: ['COM15', 'COM10']" + res = re.compile('\[((?:\'COM\d+\'.?.?)+)\]').search(com_str) + + ports = [] + if res: + port_str=str(res.group(1)) + ports=port_str.replace('\'', '').replace(',', '').split() + return ports + +def extract_information(port, stdout_value): + mac_str='' + info='' + is_program_success='' + + #print 'output: ', stdout_value + +# res = re.compile('Connecting to device on (COM\d+)').search(stdout_value) +# if res: +# port_str = str(res.group(1)) + + ### extracting the following information + ''' + Devicelabel: JN516x, BL 0x00080006 + FlashLabel: Internal Flash (256K) + Memory: 0x00008000 bytes RAM, 0x00040000 bytes Flash + ChipPartNo: 8 + ChipRevNo: 1 + ROM Version: 0x00080006 + MAC Address: 00:15:8D:00:00:35:DD:FB + ZB License: 0x00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00 + User Data: 00:00:00:00:00:00:00:00 + FlashMID: 0xCC + FlashDID: 0xEE + MacLocation: 0x00000010 + Sector Length: 0x08000 + Bootloader Version: 0x00080006 + ''' + + res = re.compile('(Devicelabel.*\sFlashLabel.*\sMemory.*\sChipPartNo.*\sChipRevNo.*\sROM Version.*\sMAC Address.*\sZB License.*\sUser Data.*\sFlashMID.*\sFlashDID.*\sMacLocation.*\sSector Length.*\sBootloader Version\:\s+0x\w{8})').search(stdout_value) + if res: + info = str(res.group(1)) + + res = re.compile('MAC Address\:\s+((?:\w{2}\:?){8})').search(stdout_value) + if res: + mac_str = str(res.group(1)) + + res = re.compile('(Program\ssuccessfully\swritten\sto\sflash)').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + + return [mac_str, info, is_program_success] + +def program_motes(flash_programmer, motes, firmware_file): + for m in motes: + cmd = [flash_programmer, '-c', m, '-B', '1000000', '-s', '-w', '-f', firmware_file] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + print m, mac_str, is_program_success + + errors = (stderr_value) + if errors != '': + print 'Errors:', errors + +def print_info(flash_programmer, motes, do_mac_only): + if do_mac_only: + print "Listing Mac addresses:" + else: + print "Listing mote info:" + for m in motes: + cmd=[flash_programmer, '-c', m, '-B', '1000000'] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + + errors = (stderr_value) + + if do_mac_only: + print m, mac_str + else: + print m, '\n', info, '\n' + + if errors != '': + print 'Errors:', errors + +def serialdump(args): + port_name = args[0] + serial_dumper = args[1] + cmd = [serial_dumper, '-b1000000', "/dev/" + port_name.lower()] + if os.name == "posix" or os.name == "cygwin": + cmd = " ".join(cmd) + rv = subprocess.call(cmd, shell=True) + +def serialdump_ports(flash_programmer, serial_dumper, ports): + p = multiprocessing.Pool() + p.map(serialdump, zip(ports, [serial_dumper] * len(ports))) + p.close() diff --git a/tools/jn516x/serialdump.c b/tools/jn516x/serialdump.c new file mode 100644 index 000000000..26b0884e2 --- /dev/null +++ b/tools/jn516x/serialdump.c @@ -0,0 +1,396 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BAUDRATE B115200 +#define BAUDRATE_S "115200" +#ifdef linux +#define MODEMDEVICE "/dev/ttyS0" +#else +#define MODEMDEVICE "/dev/com1" +#endif /* linux */ + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +#define CSNA_INIT 0x01 + +#define BUFSIZE 40 +#define HCOLS 20 +#define ICOLS 18 + +#define MODE_START_DATE 0 +#define MODE_DATE 1 +#define MODE_START_TEXT 2 +#define MODE_TEXT 3 +#define MODE_INT 4 +#define MODE_HEX 5 +#define MODE_SLIP_AUTO 6 +#define MODE_SLIP 7 +#define MODE_SLIP_HIDE 8 + +static unsigned char rxbuf[2048]; + +static int +usage(int result) +{ + printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] [SERIALDEVICE]\n"); + printf(" -x for hexadecimal output\n"); + printf(" -i for decimal output\n"); + printf(" -s for automatic SLIP mode\n"); + printf(" -so for SLIP only mode (all data is SLIP packets)\n"); + printf(" -sn to hide SLIP packages\n"); + printf(" -T[format] to add time for each text line\n"); + printf(" (see man page for strftime() for format description)\n"); + return result; +} + +static void +print_hex_line(unsigned char *prefix, unsigned char *outbuf, int index) +{ + int i; + + printf("\r%s", prefix); + for(i = 0; i < index; i++) { + if((i % 4) == 0) { + printf(" "); + } + printf("%02X", outbuf[i] & 0xFF); + } + printf(" "); + for(i = index; i < HCOLS; i++) { + if((i % 4) == 0) { + printf(" "); + } + printf(" "); + } + for(i = 0; i < index; i++) { + if(outbuf[i] < 30 || outbuf[i] > 126) { + printf("."); + } else { + printf("%c", outbuf[i]); + } + } +} + +int +main(int argc, char **argv) +{ + struct termios options; + fd_set mask, smask; + int fd; + speed_t speed = BAUDRATE; + char *speedname = BAUDRATE_S; + char *device = MODEMDEVICE; + char *timeformat = NULL; + unsigned char buf[BUFSIZE], outbuf[HCOLS]; + unsigned char mode = MODE_START_TEXT; + int nfound, flags = 0; + unsigned char lastc = '\0'; + + int index = 1; + while(index < argc) { + if(argv[index][0] == '-') { + switch(argv[index][1]) { + case 'b': + /* set speed */ + if(strcmp(&argv[index][2], "38400") == 0) { + speed = B38400; + speedname = "38400"; + } else if(strcmp(&argv[index][2], "19200") == 0) { + speed = B19200; + speedname = "19200"; + } else if(strcmp(&argv[index][2], "57600") == 0) { + speed = B57600; + speedname = "57600"; + } else if(strcmp(&argv[index][2], "115200") == 0) { + speed = B115200; + speedname = "115200"; + } else if(strcmp(&argv[index][2], "230400") == 0) { + speed = B230400; + speedname = "230400"; + } else if(strcmp(&argv[index][2], "460800") == 0) { + speed = B460800; + speedname = "460800"; + } else if(strcmp(&argv[index][2], "500000") == 0) { + speed = B500000; + speedname = "500000"; + } else if(strcmp(&argv[index][2], "576000") == 0) { + speed = B576000; + speedname = "576000"; + } else if(strcmp(&argv[index][2], "921600") == 0) { + speed = B921600; + speedname = "921600"; + } else if(strcmp(&argv[index][2], "1000000") == 0) { + speed = B1000000; + speedname = "1000000"; + } else { + fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); + return usage(1); + } + break; + case 'x': + mode = MODE_HEX; + break; + case 'i': + mode = MODE_INT; + break; + case 's': + switch(argv[index][2]) { + case 'n': + mode = MODE_SLIP_HIDE; + break; + case 'o': + mode = MODE_SLIP; + break; + default: + mode = MODE_SLIP_AUTO; + break; + } + break; + case 'T': + if(strlen(&argv[index][2]) == 0) { + timeformat = "%Y-%m-%d %H:%M:%S"; + } else { + timeformat = &argv[index][2]; + } + mode = MODE_START_DATE; + break; + case 'h': + return usage(0); + default: + fprintf(stderr, "unknown option '%c'\n", argv[index][1]); + return usage(1); + } + index++; + } else { + device = argv[index++]; + if(index < argc) { + fprintf(stderr, "too many arguments\n"); + return usage(1); + } + } + } + fprintf(stderr, "connecting to %s (%s)", device, speedname); + +#ifdef O_SYNC + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY /*| O_DIRECT*/ | O_SYNC); + if(fd < 0 && errno == EINVAL){ // O_SYNC not supported (e.g. raspberian) + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT); + } +#else + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC ); +#endif + if(fd < 0) { + fprintf(stderr, "\n"); + perror("open"); + exit(-1); + } + fprintf(stderr, " [OK]\n"); + + if(fcntl(fd, F_SETFL, 0) < 0) { + perror("could not set fcntl"); + exit(-1); + } + + if(tcgetattr(fd, &options) < 0) { + perror("could not get options"); + exit(-1); + } + /* fprintf(stderr, "serial options set\n"); */ + cfsetispeed(&options, speed); + cfsetospeed(&options, speed); + /* Enable the receiver and set local mode */ + options.c_cflag |= (CLOCAL | CREAD); + /* Mask the character size bits and turn off (odd) parity */ + options.c_cflag &= ~(CSIZE | PARENB | PARODD); + /* Select 8 data bits */ + options.c_cflag |= CS8; + + /* Raw input */ + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + /* Raw output */ + options.c_oflag &= ~OPOST; + + if(tcsetattr(fd, TCSANOW, &options) < 0) { + perror("could not set options"); + exit(-1); + } + + /* Make read() return immediately */ + /* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ + /* perror("\ncould not set fcntl"); */ + /* exit(-1); */ + /* } */ + + FD_ZERO(&mask); + FD_SET(fd, &mask); + FD_SET(fileno(stdin), &mask); + + index = 0; + for(;;) { + smask = mask; + nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); + if(nfound < 0) { + if(errno == EINTR) { + fprintf(stderr, "interrupted system call\n"); + continue; + } + /* something is very wrong! */ + perror("select"); + exit(1); + } + + if(FD_ISSET(fileno(stdin), &smask)) { + /* data from standard in */ + int n = read(fileno(stdin), buf, sizeof(buf)); + if(n < 0) { + perror("could not read"); + exit(-1); + } else if(n > 0) { + /* because commands might need parameters, lines needs to be + separated which means the terminating LF must be sent */ + /* while(n > 0 && buf[n - 1] < 32) { */ + /* n--; */ + /* } */ + if(n > 0) { + int i; + /* fprintf(stderr, "SEND %d bytes\n", n);*/ + /* write slowly */ + for(i = 0; i < n; i++) { + if(write(fd, &buf[i], 1) <= 0) { + perror("write"); + exit(1); + } else { + fflush(NULL); + usleep(6000); + } + } + } + } else { + /* End of input, exit. */ + exit(0); + } + } + + if(FD_ISSET(fd, &smask)) { + int i, j, n = read(fd, buf, sizeof(buf)); + if(n < 0) { + perror("could not read"); + exit(-1); + } + + for(i = 0; i < n; i++) { + switch(mode) { + case MODE_START_TEXT: + case MODE_TEXT: + printf("%c", buf[i]); + break; + case MODE_START_DATE: { + time_t t; + t = time(&t); + strftime(outbuf, HCOLS, timeformat, localtime(&t)); + printf("%s|", outbuf); + mode = MODE_DATE; + } + /* continue into the MODE_DATE */ + case MODE_DATE: + printf("%c", buf[i]); + if(buf[i] == '\n') { + mode = MODE_START_DATE; + } + break; + case MODE_INT: + printf("%03d ", buf[i]); + if(++index >= ICOLS) { + index = 0; + printf("\n"); + } + break; + case MODE_HEX: + rxbuf[index++] = buf[i]; + if(index >= HCOLS) { + print_hex_line("", rxbuf, index); + index = 0; + printf("\n"); + } + break; + + case MODE_SLIP_AUTO: + case MODE_SLIP_HIDE: + if(!flags && (buf[i] != SLIP_END)) { + /* Not a SLIP packet? */ + printf("%c", buf[i]); + break; + } + /* continue to slip only mode */ + case MODE_SLIP: + switch(buf[i]) { + case SLIP_ESC: + lastc = SLIP_ESC; + break; + + case SLIP_END: + if(index > 0) { + if(flags != 2 && mode != MODE_SLIP_HIDE) { + /* not overflowed: show packet */ + print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); + printf("\n"); + } + lastc = '\0'; + index = 0; + flags = 0; + } else { + flags = !flags; + } + break; + + default: + if(lastc == SLIP_ESC) { + lastc = '\0'; + + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(buf[i]) { + case SLIP_ESC_END: + buf[i] = SLIP_END; + break; + case SLIP_ESC_ESC: + buf[i] = SLIP_ESC; + break; + } + } + + rxbuf[index++] = buf[i]; + if(index >= sizeof(rxbuf)) { + fprintf(stderr, "**** slip overflow\n"); + index = 0; + flags = 2; + } + break; + } + break; + } + } + + /* after processing for some output modes */ + if(index > 0) { + switch(mode) { + case MODE_HEX: + print_hex_line("", rxbuf, index); + break; + } + } + fflush(stdout); + } + } +}