Skip to content

Commit

Permalink
add hint if you run the simulator with already created slcan
Browse files Browse the repository at this point in the history
  • Loading branch information
PonomarevDA committed Dec 3, 2024
1 parent 345d6e6 commit 92527a2
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 2 deletions.
23 changes: 21 additions & 2 deletions scripts/docker_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@

logger = logging.getLogger(__name__)

def is_slcan_already_created(sniffer_path: Optional[str]) -> bool:
return sniffer_path in ["slcan0", "slcan1"]
# if not isinstance(sniffer_path, str):
# return False

# if platform.system() == 'Windows':
# return bool(re.match(r'^COM\d+$', sniffer_path, re.IGNORECASE))

# return os.path.exists(sniffer_path)

def is_valid_sniffer_path(sniffer_path: Optional[str]) -> bool:
if not isinstance(sniffer_path, str):
return False
Expand Down Expand Up @@ -74,8 +84,17 @@ def run_sim_container(mode: SimMode,
image_name: str,
argument: str,
sniffer_path: Optional[str]=None) -> Optional[subprocess.Popen]:
if mode.is_hitl() and not is_valid_sniffer_path(sniffer_path):
raise RuntimeError(f"CAN-Sniffer has not been found (sniffer_path={sniffer_path})")
print(sniffer_path)
if mode.is_hitl():
if is_slcan_already_created(sniffer_path):
raise RuntimeError(
"slcan0 is already exist. "
"You can see it by running 'ifconfig' command. "
"Please, remove slcan0 before using the simulator. "
"Try './scripts/socketcan.sh --remove' or reconnect the SLCAN adapter manually."
)
if not is_valid_sniffer_path(sniffer_path):
raise RuntimeError(f"CAN-Sniffer has not been found (sniffer_path={sniffer_path})")

if mode == SimMode.CYPHAL_HITL:
flags = [
Expand Down
191 changes: 191 additions & 0 deletions scripts/socketcan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
#!/bin/bash
# wget https://raw.githubusercontent.com/PonomarevDA/tools/main/scripts/can/create_slcan.sh
# This software is distributed under the terms of the MIT License.
# Copyright (c) 2023-2024 Dmitry Ponomarev.
# Author: Dmitry Ponomarev <[email protected]>

SCRIPT_NAME=$(basename $BASH_SOURCE)
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

HELP="usage: $SCRIPT_NAME [--help] [--device <dev_path>] [--interface <interface>] [--only-find].
The $SCRIPT_NAME utility is about Linux kernel's implementation of CAN protocols called SocketCAN.
SocketCAN includes support for virtual CAN interfaces, hardware CAN devices and SLCAN (serial line CAN) adapters.
The script allows you to automatically find a CAN-sniffer, create SLCAN or virtual CAN and remove them.
options:
-d, --device DEV_PATH Specify device path manually instead of trying to find it
among known sniffers. Example: /dev/ttyACM0.
-i, --interface INTERFACE Specify custom interface. By default it attach it to slcan0.
-r, --remove Remove interface.
-v, --virtual-can Create virtual CAN interface.
-o, --only-find Do not create the interface, only look for a sniffer.
-h, --help Show this help message and exit.
UC1. Create slcan0 based on a CAN-sniffer
./$SCRIPT_NAME
UC2. Remove an existed slcan0 interface
./$SCRIPT_NAME --remove
UC3. Create virtual CAN interface slcan0
./$SCRIPT_NAME -v
UC4. Just check for online CAN-sniffers
./$SCRIPT_NAME -o
UC5. Customize interface name and device path
./$SCRIPT_NAME -d /dev/ttyACM0 -i vcan0
"

INTERFACE=slcan0
DEV_PATH=""
ONLY_FIND="no"
REMOVE_INTERFACE="no"
VIRTUAL_CAN="no"

function log_error() {
lineno=($(caller))
printf "$RED$SCRIPT_NAME ERROR on line ${lineno}: $1!$NC\n"
}

function log_warn() {
lineno=($(caller))
printf "$YELLOW$SCRIPT_NAME WARN on line ${lineno}: $1.$NC\n"
}

function log_info() {
printf "$SCRIPT_NAME INFO: $1.\n"
}

while [[ $# -gt 0 ]]; do
case $1 in
-d|--device)
DEV_PATH="$2"
shift
;;

-i|--interface)
INTERFACE="$2"
shift
;;

-r|--remove)
REMOVE_INTERFACE="yes"
;;

-v|--virtual-can)
VIRTUAL_CAN="yes"
;;

-o|--only-find)
ONLY_FIND="yes"
;;

-h|--help)
echo "$HELP"
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 0 || return 0
;;

*)
log_error "Unknown option: $1"
echo "$HELP"
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 1 || return 1
;;
esac
shift
done

function find_sniffer() {
KNOWN_SNIFFERS=(
"ID_MODEL_ID=374b|ID_VENDOR_ID=0483" # RaccoonLab programmer-sniffer
"ID_MODEL_ID=60c7|ID_VENDOR_ID=1d50" # Zubax Babel-Babel
)

EXPECTED_DEV_PATH="/dev/ttyACM*"
EXPECTED_SYMLINK_PATH="/dev/serial/by-id/"
for dev_path in $EXPECTED_DEV_PATH; do
[ -e "$dev_path" ] || continue
for sniffer in ${KNOWN_SNIFFERS[@]}; do
is_sniffer=$(udevadm info $dev_path | grep -E "($sniffer)" -wc || true)
if [ "$is_sniffer" == 2 ]; then
DEV_PATH=$(find -L $EXPECTED_SYMLINK_PATH -samefile $dev_path)
break
fi
done
done
}

function create_slcan() {
sudo slcand -o -c -f -s8 -t hw -S 1000000 $DEV_PATH $INTERFACE
sleep 1 # without sleep next commands may fail with 'Cannot find device "slcan0"'
sudo ip link set up $INTERFACE
sudo tc qdisc add dev $INTERFACE root handle 1: pfifo_head_drop limit 1000
}

function create_virtual_can() {
sudo modprobe vcan
sudo ip link add dev $INTERFACE type vcan
sudo ip link set up $INTERFACE
}

function remove_interface() {
if [[ $(ifconfig | grep $INTERFACE) ]]; then
log_info "Trying to remove $INTERFACE interface.."
fi
sudo ip link delete $INTERFACE
if [[ $(ifconfig | grep $INTERFACE) ]]; then
log_warn "Removing $INTERFACE interface failed. Try to reconnect the CAN-sniffer manually"
fi
}

echo "SLCAN creator settings:
- DEV_PATH=$INTERFACE"

# Step 1. Remove interface if requested
if [[ $REMOVE_INTERFACE == "yes" ]]; then
echo "- REMOVE_INERFACE: yes ($INTERFACE)"
remove_interface
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 0 || return 0
fi

# Step 2.
if [[ $VIRTUAL_CAN == "yes" ]]; then
echo "- VIRTUAL_CAN: yes ($INTERFACE)"
create_virtual_can
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 0 || return 0
fi


# Step 2. Define the device path
if [ -z $DEV_PATH ]; then
find_sniffer

if [ -z "$DEV_PATH" ]; then
log_error "Can't find a sniffer"
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 2 || return 1
fi

if [[ $ONLY_FIND == "yes" ]]; then
echo "$DEV_PATH"
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 0 || return 0
fi
fi


# Step 3. Create SLCAN based on device path
echo "- INTERFACE=$INTERFACE"

if [[ $(ifconfig | grep $INTERFACE) ]]; then
log_warn "specified interface already exist, skip"
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 0 || return 1
fi

create_slcan

if [[ -z $(ifconfig | grep $INTERFACE) ]]; then
log_error "Interface '$INTERFACE' has not been successfully created"
[[ "${BASH_SOURCE[0]}" -ef "$0" ]] && exit 3 || return 1
fi

0 comments on commit 92527a2

Please sign in to comment.