#!/bin/bash set -e # Exit on error ############################################################################### # Script to compile and install calimero server + tool on an Orange Pi PC # armbian based systems or Raspberry Pi rasbian systems # - installs a JDK # - installs Maven # # Michael Albert info@michlstechblog.info # 09.04.2018 # # # Currently state is experimental # Script should also run on x86/x64 devices # # License: Feel free to modify. Feedback (positive or negative) is welcome # # Changes: # 20180525-120000: Workaround for calimero-core => Master requires Java 9 # 20180518-120000: symlink /opt/calimero-server/calimero-core-2.4-rc2.jar -> /opt/calimero-server/calimero-core-2.4-SNAPSHOT.jar # 20180603-230000: calimero-device switched to 2.4/release branch # copy jar with wildcards # delete all calimero-core-2.4-*test*.jar from server path # 20180625-053000: Checkout release/2.4 from calimero-rxtx and calimero-tools # 20180629-053500: changed copy calimero-tools-2.4-*.jar instead of SNAPSHOT # 20180702-054500: Removed detach server process from console patch and instead added new --no-stdin command line option to systemd service file. Set default KNX Address to a valid coupler address # 20180706-054000: knxtools script adjusted to calimero-tools-2.4-rc2.jar # 20190925-121000: Oracle Java -> OpenJDK # 20200110-054500: Orange PI PC: Script adjusted for Armbian with Mainline Kernel 5.4.x # # please see https://github.com/Race666/calimero-server for the latest changes # # version:20200110-054000 # # ############################################################################### ################################## Constants ################################## export CALIMERO_BUILD=~/calimero-build # export JAVA_LIB_PATH=/usr/java/packages/lib/arm export CALIMERO_SERVER_PATH=/opt/calimero-server export CALIMERO_TOOLS_PATH=/opt/calimero-tools export CALIMERO_CONFIG_PATH=/etc/calimero # Bin Path export BIN_PATH=/usr/local/bin # export SERIAL_INTERFACE=ttyS3 export SERIAL_INTERFACE_ORANGE_PI=ttyS3 export SERIAL_INTERFACE_RASPBERRY_PI=ttyAMA0 # Default, would be overwritten from hardware detection export SERIAL_INTERFACE=ttyS0 # KNX_ROUTING => true or false export KNX_ROUTING=true # If routing is enabled set a valid Coupler KNX Address x.x.0 export KNX_ADDRESS="1.1.0" # If routing disabled, set a KNX Device Address # export KNX_ADDRESS="1.1.128" export KNX_CLIENT_ADDRESS_START="1.1.129" export KNX_CLIENT_ADDRESS_COUNT=8 # Network interface calimero bind to # export LISTEN_NETWORK_INTERFACE=eth0 # If defined this network interface is used for outgoing connections. Comment it if the tunnel target is on the same subnet export OUTGOING_NETWORK_INTERFACE_TUNNEL=eth0 export LISTEN_NETWORK_INTERFACE=eth0 # User to run Server export CALIMERO_SERVER_USER=knx # Group export CALIMERO_SERVER_GROUP=knx # Application data directory export CALIMERO_SERVER_APP_DATA=/home/$CALIMERO_SERVER_USER/.calimero-server # KNX Server Name export KNX_SERVER_NAME="Calimero KNXnet/IP Server" # Branch to use export GIT_BRANCH="master" export GIT_BRANCH_TOOLS="master" # Temp dir for extracting archives after building export CALIMERO_TMP="/tmp/calimero" ############################################################################### # Usage if [ "$1" = "-?" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ];then echo Usage $0 "[tpuart|usb|tunnel ip-tunnel-endpoint|clean][--keyring ]" echo " clean deletes directories" $CALIMERO_BUILD, $CALIMERO_TOOLS_PATH and $CALIMERO_SERVER_PATH echo " --keyring configure KNX IP Secure using keyring in current directory" exit 0 fi ############################################################################### # Check for root permissions if [ "$(id -u)" != "0" ]; then echo " Attention!!!" echo " Start script must run as root" 1>&2 echo " Start a root shell with" echo " sudo su -" exit 1 fi ################################# Parameters ################################## # Connection to KNX Bus if [ "$1" = "usb" ] || [ "$1" = "--usb" ];then echo Configure support for USB export KNX_CONNECTION=USB elif [ "$1" = "tunnel" ] || [ "$1" = "--tunnel" ];then echo Configure support for TUNNELING if [ ! -z "$2" ];then export KNX_CONNECTION=TUNNEL export PARAM_VALUE=$2 echo Tunnel Endpoint: $PARAM_VALUE else echo ERROR: A tunnel endpoint address must be specified!!! echo Example: $0 tunnel 192.166.200.200 exit 4 fi elif [ "$1" = "clean" ]; then # Check on zero for $CALIMERO_BUILD to avoid "cleaning" the wrong directory if [ ! -z $CALIMERO_BUILD ] && [ -d $CALIMERO_BUILD ]; then if [[ $CALIMERO_BUILD == *"calimero"* ]]; then rm -r $CALIMERO_BUILD else echo $CALIMERO_BUILD does not seem to be a calimero-specific directory, please clean manually fi fi # Check on zero for $CALIMERO_SERVER_PATH to avoid "cleaning" the wrong directory if [ ! -z $CALIMERO_SERVER_PATH ] && [ -d $CALIMERO_SERVER_PATH ]; then if [[ $CALIMERO_SERVER_PATH == *"calimero"* ]]; then rm -r $CALIMERO_SERVER_PATH else echo $CALIMERO_SERVER_PATH does not seem to be a calimero-specific directory, please clean manually fi fi # Check on zero for $CALIMERO_TOOLS_PATH to avoid "cleaning" the wrong directory if [ ! -z $CALIMERO_TOOLS_PATH ] && [ -d $CALIMERO_TOOLS_PATH ]; then if [[ $CALIMERO_TOOLS_PATH == *"calimero"* ]]; then rm -r $CALIMERO_TOOLS_PATH else echo $CALIMERO_TOOLS_PATH does not seem to be a calimero-specific directory, please clean manually fi fi exit 0 elif [ "$1" = "tpuart" ] || [ "$1" = "--tpuart" ];then echo Configure support for TPUART export KNX_CONNECTION=TPUART else echo Configure support for TPUART export KNX_CONNECTION=TPUART fi # Keyring option for KNX IP Secure if [ "$1" = "--keyring" ] || [ "$2" = "--keyring" ];then files=( ./*.knxkeys ) export KEYRING_FILENAME=${files[0]} export KEYRING=$(realpath $KEYRING_FILENAME) echo Configure server for KNX IP Secure using $KEYRING export KEYRING_PWD=${*: -1} fi ########################## Determine Hardware ################################# # Old:sun8i=OrangePi PC # export HARDWARE_STRING_OPI=$(dmesg|grep Machine:|cut -d":" -f 2|xargs echo -n) export HARDWARE_STRING_OPI=$(dmesg|grep -i 'Machine Model:'|cut -d":" -f 4|xargs echo -n) if [ ! -z "$HARDWARE_STRING_OPI" ]; then # if [ $HARDWARE_STRING_OPI = "sun8i" ]; then if [ "$HARDWARE_STRING_OPI" = "Xunlong Orange Pi PC" ]; then echo "Orange Pi PC detected" export HARDWARE=Orange export SERIAL_INTERFACE=$SERIAL_INTERFACE_ORANGE_PI fi fi # Raspberry if [ -z $HARDWARE ]; then export MODEL_STRING=$(tr -d '\0' /dev/null if [ $? -eq 0 ]; then echo Raspberry Pi found! export HARDWARE=Raspi export SERIAL_INTERFACE=$SERIAL_INTERFACE_RASPBERRY_PI elif [[ $MODEL_STRING == *"Raspberry Pi"* ]]; then echo $MODEL_STRING found! export HARDWARE=Raspi export SERIAL_INTERFACE=$SERIAL_INTERFACE_RASPBERRY_PI fi set -e fi # Detect RPI 3 # Disable error handling set +e dmesg |grep -i "Raspberry Pi 3" > /dev/null if [ $? -eq 0 ]; then echo Raspberry 3 found! export IS_RASPBERRY_3=1 fi # Enable error handling set -e # x86 PC set +e arch|grep -i x86 > /dev/null if [ $? -eq 0 ]; then echo Standard x86 PC found! export HARDWARE=X86 fi set -e # Check if Hardware is recognized if [ -z $HARDWARE ]; then echo No supported Hardware detected exit 1 fi ######################## CPU Architecture ##################################### set +e arch|grep -i arm > /dev/null if [ $? -eq 0 ]; then echo CPU architecture ARM export ARCH=ARM fi arch|grep -i x86_64 > /dev/null if [ $? -eq 0 ]; then echo CPU architecture x64 export ARCH=X64 fi set -e if [ -z $ARCH ]; then echo Unknown CPU architecture $(arch) exit 2 fi ############################ Build Directory ################################## if [ ! -d $CALIMERO_BUILD ]; then mkdir -p $CALIMERO_BUILD fi # Server and config path mkdir -p $CALIMERO_SERVER_PATH mkdir -p $CALIMERO_TOOLS_PATH mkdir -p $CALIMERO_CONFIG_PATH ########################## Required packages ################################# if [ -z "$(find /var/cache/apt/pkgcache.bin -mmin -120)" ]; then apt-get -y update apt-get -y upgrade fi apt-get -y install setserial apt-get -y install git maven apt-get -y install build-essential cmake apt-get -y install automake autoconf libtool apt-get -y install dirmngr apt-get -y install net-tools software-properties-common xmlstarlet debconf-utils crudini apt-get -y install unzip ########################### Java ############################################## set +e # Install JDK >= 17 # Steps according to https://adoptium.net/en-GB/blog/2021/12/eclipse-temurin-linux-installers-available/ apt-get install -y wget apt-transport-https gnupg wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | apt-key add - echo "deb https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list apt-get update apt-get install -y temurin-17-jdk set -e export JAVA_HOME_PATH=$(readlink -e /usr/bin/javac |sed -e's/\/bin\/javac//') # Check for Java bin if [ ! -f $JAVA_HOME_PATH/bin/java ]; then echo Java not found in path $JAVA_HOME_PATH! exit 6 fi # Get JavaLibPath for libserialcom.so cat > $CALIMERO_BUILD/GetLibraryPath.java <= 1) System.out.println(JavaPath.split(":")[0]); else System.exit(1); } } EOF export JAVA_LIB_PATH=$(java $CALIMERO_BUILD/GetLibraryPath.java) if [ ! -d $JAVA_LIB_PATH ]; then mkdir -p $JAVA_LIB_PATH fi # Install Maven MVN_VERSION=3.9.4 wget -P /tmp/ https://archive.apache.org/dist/maven/maven-3/$MVN_VERSION/binaries/apache-maven-$MVN_VERSION-bin.tar.gz cd /opt && sudo tar -xzvf /tmp/apache-maven-$MVN_VERSION-bin.tar.gz cat > /etc/profile.d/maven.sh < /root/.bashrc < User $CALIMERO_SERVER_USER dialout group set +e getent passwd $CALIMERO_SERVER_USER if [ $? -ne 0 ]; then useradd $CALIMERO_SERVER_USER -s /bin/false -U -M -G dialout -d /home/$CALIMERO_SERVER_USER fi set -e # On Raspberry add user pi to group $CALIMERO_SERVER_GROUP set +e getent passwd pi if [ $? -eq 0 ]; then usermod -a -G $CALIMERO_SERVER_GROUP pi fi usermod -a -G $CALIMERO_SERVER_GROUP $(logname) set -e # Create home if [ ! -d /home/$CALIMERO_SERVER_USER ]; then mkdir /home/$CALIMERO_SERVER_USER fi chown -R $CALIMERO_SERVER_USER:$CALIMERO_SERVER_GROUP /home/$CALIMERO_SERVER_USER # Create app data dir if [ ! -d $CALIMERO_SERVER_APP_DATA ]; then mkdir -p $CALIMERO_SERVER_APP_DATA fi chown -R $CALIMERO_SERVER_USER:$CALIMERO_SERVER_GROUP $CALIMERO_SERVER_APP_DATA ################################ USB ########################################## # !!!! Not sure if requiered to access USB devices...!!!! # Set permissions on USB devices # http://knx-user-forum.de/342820-post9.html to access USB Devices as $GROUP cat > /etc/udev/rules.d/90-knxusb-devices.rules < $BIN_PATH/knxtools < $CALIMERO_SERVER_APP_DATA/keyfile <\)//g' $CALIMERO_CONFIG_PATH/server-config.xml --in-place=.bak # Enable TPUART, uncomment TPUART sed -e's//\1/g' $CALIMERO_CONFIG_PATH/server-config.xml --in-place=.bak elif [ "$KNX_CONNECTION" = "USB" ];then # Empty node -> First device is used echo Configure calimero for USB connection xmlstarlet ed --inplace -u 'knxServer/serviceContainer/knxSubnet[@type="usb"]' -v "" $CALIMERO_CONFIG_PATH/server-config.xml elif [ "$KNX_CONNECTION" = "TUNNEL" ];then # Comment USB echo Configure calimero for Tunnel connection to endpoint $PARAM_VALUE sed -e's/\(\)//g' $CALIMERO_CONFIG_PATH/server-config.xml --in-place=.bak # Enable ip, xmlstarlet ed --inplace -s 'knxServer/serviceContainer' -t elem -n knxSubnet -v $PARAM_VALUE $CALIMERO_CONFIG_PATH/server-config.xml xmlstarlet ed --inplace -s 'knxServer/serviceContainer/knxSubnet' -t attr -n "type" -v "ip" $CALIMERO_CONFIG_PATH/server-config.xml # If outgoing interface defined if [ ! -z $OUTGOING_NETWORK_INTERFACE_TUNNEL ]; then xmlstarlet ed --inplace -s 'knxServer/serviceContainer/knxSubnet[@type="ip"]' -t attr -n netif -v $OUTGOING_NETWORK_INTERFACE_TUNNEL $CALIMERO_CONFIG_PATH/server-config.xml fi else echo No KNX Connection specified exit 5 fi # Set properties.xml path xmlstarlet ed --inplace -u "knxServer/propertyDefinitions/@ref" -v "$CALIMERO_CONFIG_PATH/properties.xml" $CALIMERO_CONFIG_PATH/server-config.xml # Replace serial device /dev/ttySx => $SERIAL_INTERFACE sed -e"s/\/dev\/ttyS[[:digit:]]/\/dev\/$SERIAL_INTERFACE/g" $CALIMERO_CONFIG_PATH/server-config.xml --in-place=.bak # Replace serial device /dev/ttyACMx => $SERIAL_INTERFACE sed -e"s/\/dev\/ttyACM[[:digit:]]/\/dev\/$SERIAL_INTERFACE/g" $CALIMERO_CONFIG_PATH/server-config.xml --in-place=.bak # Comment routing tag sed -e's/[^<^!^\-^\-]\s\{1,\}\(\)//g' $CALIMERO_CONFIG_PATH/server-config.xml --in-place=.bak # Add empty groupAddressFilter ######### Addresses assigned to KNXnet/IP Clients # Remove existing xmlstarlet ed --inplace -d 'knxServer/serviceContainer/additionalAddresses/knxAddress[@type="individual"]' $CALIMERO_CONFIG_PATH/server-config.xml # Add $KNX_CLIENT_ADDRESS_COUNT Addresses, starting from $KNX_CLIENT_ADDRESS_START export KNX_ADDRESS_PREFIX=$(echo $KNX_CLIENT_ADDRESS_START|cut -d'.' -f 1-2) export START_OCTET=$(echo $KNX_CLIENT_ADDRESS_START|cut -d'.' -f 3) # Add new KNX Client Address elements for ((i=0;i<$KNX_CLIENT_ADDRESS_COUNT;i++)) do CURRENT_OCTET=$(expr $START_OCTET + $i) xmlstarlet ed --inplace -s 'knxServer/serviceContainer/additionalAddresses' -t elem -n knxAddress -v $KNX_ADDRESS_PREFIX.$CURRENT_OCTET $CALIMERO_CONFIG_PATH/server-config.xml done # Add Attribute type=individual xmlstarlet ed --inplace -s 'knxServer/serviceContainer/additionalAddresses/knxAddress' -t attr -n type -v individual $CALIMERO_CONFIG_PATH/server-config.xml # If a keyring is present, add to server-config.xml if [ $KEYRING ]; then xmlstarlet ed --inplace --insert 'knxServer/serviceContainer' -t attr -n keyring -v $CALIMERO_SERVER_APP_DATA/$KEYRING_FILENAME $CALIMERO_CONFIG_PATH/server-config.xml xmlstarlet ed --inplace --insert 'knxServer/serviceContainer' -t attr -n keyfile -v $CALIMERO_SERVER_APP_DATA/keyfile $CALIMERO_CONFIG_PATH/server-config.xml fi # Set owner on server and config path. Need to be discussed. Read/execute permissions should sufficient echo Set owner chown -R $CALIMERO_SERVER_USER:$CALIMERO_SERVER_GROUP $CALIMERO_TOOLS_PATH chown -R $CALIMERO_SERVER_USER:$CALIMERO_SERVER_GROUP $CALIMERO_SERVER_PATH chown -R $CALIMERO_SERVER_USER:$CALIMERO_SERVER_GROUP $CALIMERO_CONFIG_PATH ###################### Serial interface ####################################### # Configure serial devices depending on the underlying hardware # Orange Pi if [ $HARDWARE = "Orange" ]; then # Enable UART3 for connecting a TPUART module echo Alter Orange Hardware settings #bin2fex /boot/script.bin /tmp/script.fex #crudini --set /tmp/script.fex uart3 uart_used 1 #fex2bin /tmp/script.fex /boot/script.bin grep -i overlays /boot/armbianEnv.txt if [ "$?" -ge "1" ]; then echo Add UART3 Overlay echo overlays=uart3 >> /boot/armbianEnv.txt else echo Overlays already defined please add overlays=uart3 manually to /boot/armbianEnv.txt read -p "Press enter to continue" fi elif [ $HARDWARE = "Raspi" ]; then # Raspberry echo Alter Raspberry Hardware settings if [ "$IS_RASPBERRY_3" == "1" ]; then sed -e's/ console=ttyAMA0,115200/ enable_uart=1 dtoverlay=pi3-disable-bt/g' /boot/cmdline.txt --in-place=.bak sed -e's/ console=serial0,115200/ enable_uart=1 dtoverlay=pi3-disable-bt/g' /boot/cmdline.txt --in-place=.bak2 sed -e's/ console=ttyS0,115200/ enable_uart=1 dtoverlay=pi3-disable-bt/g' /boot/cmdline.txt --in-place=.bak4 sed -e's/ console=ttyACM0,115200/ enable_uart=1 dtoverlay=pi3-disable-bt/g' /boot/cmdline.txt --in-place=.bak6 systemctl disable hciuart else sed -e's/ console=ttyAMA0,115200//g' /boot/cmdline.txt --in-place=.bak sed -e's/ console=serial0,115200//g' /boot/cmdline.txt --in-place=.bak2 sed -e's/ console=ttyS0,115200//g' /boot/cmdline.txt --in-place=.bak4 sed -e's/ console=ttyACM0,115200//g' /boot/cmdline.txt --in-place=.bak6 fi sed -e's/ kgdboc=ttyAMA0,115200//g' /boot/cmdline.txt --in-place=.bak1 sed -e's/ kgdboc=serial0,115200//g' /boot/cmdline.txt --in-place=.bak3 sed -e's/ kgdboc=ttyS0,115200//g' /boot/cmdline.txt --in-place=.bak5 sed -e's/ kgdboc=ttyACM0,115200//g' /boot/cmdline.txt --in-place=.bak7 # Disable serial console systemctl disable serial-getty@ttyAMA0.service > /dev/null 2>&1 systemctl disable serial-getty@ttyS0.service > /dev/null 2>&1 systemctl disable serial-getty@.service> /dev/null 2>&1 fi # Systemd knx unit echo Create systemd service export DEF_SERVER_OPTS="\ --add-reads io.calimero.core=io.calimero.server \ --add-reads io.calimero.usb.provider.javax=ALL-UNNAMED \ --limit-modules io.calimero.server,io.calimero.serial.provider.jni,io.calimero.usb.provider.javax \ -p $CALIMERO_CONFIG_PATH:$CALIMERO_SERVER_PATH -cp \"$CALIMERO_CONFIG_PATH:$CALIMERO_SERVER_PATH/*\"" cat > /etc/systemd/system/knx.service <