#!/bin/bash ############################################################################### mode_can_dump=false can_device=vcan0 mode_file=true input_file=- while [ -n "$1" ]; do case "$1" in -h|--help) echo -e "Usage: $0 [-h|--help] [-i|--input |-]" echo -e " [-c|--can [-d|--can-device ]]" exit 0 ;; -i|--input) mode_file=true input_file="$2" shift ;; -c|--can) mode_can_dump=true ;; -d|--can-device) mode_can_dump=true can_device="$2" shift ;; *) echo -e "$0: error: invalid command line argument near '$1'." >> /dev/stderr exit 1 ;; esac shift done ############################################################################### function wideenc_decode() { local out=0 local hex=0x0$1 local a0=$((hex)) local hex=0x0$2 local a1=$((hex)) local hex=0x0$3 local a2=$((hex)) local hex=0x0$4 local a3=$((hex)) local hex=0x0$5 local a4=$((hex)) if [ $((a0&0xC0)) == 0 ]; then out=$a0 elif [ $((a0&0xE0)) == $((0x40)) ]; then out=$(( ((a0&0x1F)<< 7) | (a1&0x7F) )) elif [ $((a0&0xF0)) == $((0x60)) ]; then out=$(( ((a0&0x0F)<<14) | ((a1&0x7F)<< 7) | (a2&0x7F) )) elif [ $((a0&0xF8)) == $((0x70)) ]; then out=$(( ((a0&0x07)<<21) | ((a1&0x7F)<<14) | ((a2&0x7F)<< 7) | (a3&0x7F) )) elif [ $((a0&0xFC)) == $((0x78)) ]; then out=$(( ((a0&0x03)<<28) | ((a1&0x7F)<<21) | ((a2&0x7F)<<14) | ((a3&0x7F)<< 7) | (a4&0x7F) )) else out=0 fi echo $out } function wideenc_length() { local hex=0x0$1 local a0=$((hex)) if [ $((a0&0xC0)) == 0 ]; then echo 1 elif [ $((a0&0xE0)) == $((0x40)) ]; then echo 2 elif [ $((a0&0xF0)) == $((0x60)) ]; then echo 3 elif [ $((a0&0xF8)) == $((0x70)) ]; then echo 4 elif [ $((a0&0xFC)) == $((0x78)) ]; then echo 5 else echo 1 fi } ############################################################################### GETF_DK_PORT_DEFAULT=0x33 GETF_PORT_FLAG_SIZE_OFFSET_FILENAME=0x01 GETF_PORT_FLAG_INODE_POSITION=0x02 GETF_PORT_FLAG_REED_SOLOMON=0x04 if $mode_can_dump; then candump ${can_device} | \ while read interface eid plength frame; do eid=0x$eid FARR=($frame) length=${#FARR[*]} mac_src=$(((eid>>24)&0x1F)) mac_dst=$(((eid>>19)&0x1F)) is_first=$(((eid>>18)&1)) fragment_left=$(((eid>>10)&0xFF)) packet_serial=$((eid&0x3FF)) if [ $is_first == 0 ]; then HARR=(${FARR[0]} ${FARR[1]} ${FARR[2]} ${FARR[3]}) hex_id=${FARR[0]}${FARR[1]}${FARR[2]}${FARR[3]} id=0x${hex_id} priority=$(((id>>30)&3)) src=$(((id>>25)&0x1F)) dst=$(((id>>20)&0x1F)) dport=$(((id>>14)&0x3F)) sport=$(((id>>8)&0x3F)) length=0x${FARR[4]}${FARR[5]} doffset=6 DARR=() else doffset=0 fi nbyte=${#FARR[*]} for (( i=doffset; i>30)&3)) src=$(((id>>25)&0x1F)) dst=$(((id>>20)&0x1F)) dport=$(((id>>14)&0x3F)) sport=$(((id>>8)&0x3F)) flen=${#FARR[*]} unset FARR[0] unset FARR[1] unset FARR[2] unset FARR[3] [ 4 -le $flen ] && unset FARR[flen-4] [ 3 -le $flen ] && unset FARR[flen-3] [ 2 -le $flen ] && unset FARR[flen-2] [ 1 -le $flen ] && unset FARR[flen-1] DARR=(${FARR[*]}) length=${#FARR[*]} echo "$src:$sport $dst:$dport $length ${hex_id} ${DARR[*]}" done fi | \ while read src dst length header data; do A=(${src//:/ }) src=${A[0]} sport=${A[1]} A=(${dst//:/ }) dst=${A[0]} dport=${A[1]} darr=($data) dk_cmd=${darr[0]} dk_port=0x${darr[1]} downlink_flags=$((dk_port ^ GETF_DK_PORT_DEFAULT)) if [ "$dport" == 12 ] && [ "${darr[0]}" == 00 ] && [ $downlink_flags -le 7 ]; then unset darr[0] unset darr[1] darr=(${darr[*]}) if [ $(( downlink_flags & GETF_PORT_FLAG_SIZE_OFFSET_FILENAME )) -ne 0 ]; then has_size_offset_filename=true size=`wideenc_decode ${darr[*]}` skip=`wideenc_length ${darr[*]}` for ((i=0;i