From 426f349e364f52ac05df18c32a5641a5f2c102b6 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 8 Dec 2015 02:49:37 +0300 Subject: [PATCH] Reworked the script uavcan_add_slcan --- .../linux/scripts/uavcan_add_slcan | 136 ++++++++++++++---- 1 file changed, 111 insertions(+), 25 deletions(-) diff --git a/libuavcan_drivers/linux/scripts/uavcan_add_slcan b/libuavcan_drivers/linux/scripts/uavcan_add_slcan index d5d1137aa2..c45a89df2a 100755 --- a/libuavcan_drivers/linux/scripts/uavcan_add_slcan +++ b/libuavcan_drivers/linux/scripts/uavcan_add_slcan @@ -6,13 +6,21 @@ HELP="Register slcan-enabled Serial-to-CAN adapters as network interfaces. Usage: `basename $0` [options] [[options] ...] -First device will be mapped to the interface slcan0, second will be mapped to -slcan1, and so on. Keep in mind that the effect of this script is not -additive, i.e. all existing slcan interfaces will be removed and replaced with -new ones. The package 'can-utils' has to be installed in order to use slcan. + +Interface indexes will be assigned automatically in ascending order, i.e. +first device will be mapped to the interface slcan0, second will be mapped to +slcan1, and so on. Each added option affects only the interfaces that follow +it, which means that options must be properly ordered (see examples below). +This tool requires superuser priveleges. + +The package 'can-utils' must be installed. On Debian/Ubuntu-based systems it +can be installed via APT: apt-get install can-utils Options: - -s (where X is a number in range [1, 8]) Set CAN speed to: + --speed-code (where X is a number in range [0, 8]; default: 8) + -s + Set CAN speed to: + 0 - 10 Kbps 1 - 20 Kbps 2 - 50 Kbps 3 - 100 Kbps @@ -22,12 +30,36 @@ Options: 7 - 800 Kbps 8 - 1 Mbps (UAVCAN recommended, default) -Example: - `basename $0` /dev/ttyUSB3 /dev/ttyUSB0 -s4 /dev/ttyACM0 -The example above initializes: - /dev/ttyUSB3 --> slcan0 @ 1Mbps - /dev/ttyUSB0 --> slcan1 @ 1Mbps - /dev/ttyACM0 --> slcan2 @ 125kbps" + --remove-all + -r + Remove all SLCAN interfaces. + If this option is used, it MUST be provided FIRST, otherwise it + will remove the interfaces added earlier. + + --basename (where X is a string containing [a-z], default: slcan) + -b + Base name to use for the interfaces that follow this option. + Default value is 'slcan'. This option can be provided multiple times, + it will only affect the interfaces that were provided after it. If you + want to affect all added interfaces, provide this option first (see + examples below). + + --baudrate (where X is an integer, default: 3000000) + -S + Configure baud rate to use on the interface. + This option is mostly irrelevant for USB to CAN adapters. + +Example 1: + `basename $0` --remove-all /dev/ttyUSB3 --basename can --baudrate 115200 \\ + /dev/ttyUSB0 --speed-code 4 /dev/ttyACM0 +The example above initializes the interfaces as follows: + /dev/ttyUSB3 --> slcan0 1 Mbps baudrate 3000000 + /dev/ttyUSB0 --> can0 1 Mbps baudrate 115200 + /dev/ttyACM0 --> can1 125 kbps baudrate 115200 + +Example 2: + `basename $0` --remove-all +The example above only removes all SLCAN interfaces without adding new ones." function die() { echo $@ >&2; exit 1; } @@ -35,17 +67,23 @@ if [ "$1" == '--help' ] || [ "$1" == '-h' ]; then echo "$HELP"; exit; fi [ -n "$1" ] || die "Invalid usage. Use --help to get help." -[ "$(id -u)" == "0" ] || die "Must be root" +[ "$(id -u)" == "0" ] || die "Must be root." + +which slcan_attach > /dev/null || die "Please install can-utils first." # --------------------------------------------------------- function deinitialize() { - echo "Terminating slcand..." + echo "Stopping slcand..." >&2 + # Trying SIGINT first + killall -INT slcand &> /dev/null + sleep 0.3 + # Then trying the default signal, which is SIGTERM, if SIGINT didn't help slcand_kill_retries=10 while killall slcand &> /dev/null do (( slcand_kill_retries -= 1 )) - [[ "$slcand_kill_retries" > 0 ]] || die "Failed to kill slcand" + [[ "$slcand_kill_retries" > 0 ]] || die "Failed to stop slcand" sleep 1 done } @@ -53,35 +91,83 @@ function deinitialize() { function handle_tty() { tty=$(readlink -f $1) tty=${tty/'/dev/'} - iface="$IFACE_BASENAME$NEXT_IFACE_INDEX" - stty -F /dev/$tty ispeed 3000000 ospeed 3000000 || return 1 - slcan_attach -f -o -s$SPEED_CODE /dev/$tty || return 2 + iface_index=0 + while ifconfig "$IFACE_BASENAME$iface_index" &> /dev/null + do + iface_index=$((iface_index + 1)) + done + slcan_iface_index=0 + while ifconfig "slcan$slcan_iface_index" &> /dev/null + do + slcan_iface_index=$((slcan_iface_index + 1)) + done + + iface="$IFACE_BASENAME$iface_index" + slcan_iface="slcan$slcan_iface_index" + + echo "Attaching $tty to $iface speed code $SPEED_CODE baudrate $BAUDRATE" >&2 + + # Configuring the baudrate + stty -F /dev/$tty ispeed $BAUDRATE ospeed $BAUDRATE || return 1 + + # Attaching the line discipline. Note that slcan_attach has option -n but it doesn't work. + slcan_attach -f -o -s$SPEED_CODE /dev/$tty > /dev/null || return 2 slcand $tty || return 3 - sleep 1 # FIXME - ifconfig $iface up || return 4 + sleep 1 # FIXME - NEXT_IFACE_INDEX=$((NEXT_IFACE_INDEX + 1)) + # ...therefore we need to rename the interface manually + ip link set $slcan_iface name $iface + + ifconfig $iface up || return 4 } -NEXT_IFACE_INDEX=0 IFACE_BASENAME='slcan' SPEED_CODE=8 +BAUDRATE=3000000 -deinitialize - +next_option='' while [ -n "$1" ]; do case $1 in - -s[1-8]) + -r | --remove-all) + deinitialize + ;; + + -b*) + IFACE_BASENAME=${1:2} + ;; + + -S*) + BAUDRATE=${1:2} + ;; + + -s[0-8]) SPEED_CODE=${1:2} ;; + + --*) + next_option=${1:2} + ;; + -*) die "Invalid option: $1" ;; + *) - handle_tty $1 || die "Failed to configure the interface $1" + if [ "$next_option" = 'basename' ]; then IFACE_BASENAME=$1 + elif [ "$next_option" = 'speed-code' ]; then SPEED_CODE=$1 + elif [ "$next_option" = 'baudrate' ]; then BAUDRATE=$1 + elif [ "$next_option" = '' ] + then + handle_tty $1 || die "Failed to configure the interface $1" + else + die "Invalid option '$next_option'" + fi + next_option='' ;; esac shift done + +[ "$next_option" = '' ] || die "Expected argument for option '$next_option'"