#!/bin/bash

#This script does the following:
#Updates the installed packages in the node
#Installs iproute2 package for kernel version 4.19
#Installs Linux PTP version 2.0
#Checks if 8021q module is loaded; if not, adds the same

#Usage:  ./setup.sh

#Program name and version
program=$(basename $0)
version=2.0

#Let us install the required packages for building, configuring, running, and evaluating the performance of OPC UA application that includes PubSub and Time-Sensitive Networking
sudo apt-get install cmake g++ gcc make bison flex ethtool git linuxptp daemonize r-base -y  || \
    { echo "Required packages not installed: apt-get install failed"; exit 1; }

#We have often noticed that accelerated graphics introduce system latency and affect the real-time performance of the system. So, we recommend disabling accelerated graphics and enabling frame buffer-based processing.
#To disable accelerated graphics and enable frame buffer based graphic processing, use the below command
sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& nomodeset/' /etc/default/grub || \
    { echo "Disabling accelerated graphics: sed command failed"; exit 1; }

#For the above changes to take effect, update the grub using the below command
sudo update-grub || \
    { echo "Disabling accelerated graphics: update grub failed"; exit 1; }

#Traverse to /usr/local/src/ folder
cd /usr/local/src/ || \
    { echo "cd failed"; exit 1; }

#iproute2 is a collection of userspace utilities for controlling and monitoring various aspects of networking in the Linux kernel,
#including routing, network interfaces, tunnels, traffic control, and network-related device drivers.
#This utility is normally available in Linux.
#Intel has released series of commits to modify the tc qdisc command to support Qbv like scheduler in iproute2 of Linux.
#Clone and install iproute2 package version 4.19 using the below commands
git clone https://git.kernel.org/pub/scm/network/iproute2/iproute2.git || \
    { echo "iproute2 installation failed: git clone failed"; exit 1; }

#Traverse to the iproute2 folder
cd iproute2/ || \
    { echo "cd failed"; exit 1; }

#You should be able to take the master branch and get the latest iproute2.
#But we tested the whole setup in a particular SHA as mentioned below.
#To avoid any unknown errors, checkout to the particular SHA using the following command
git checkout e7d0b97f0544c02fef1185563def23114d7cfdd8 || \
    { echo "iproute2 installation failed: Checking out to e7d0b97 SHA failed"; exit 1; }

#Make and install the binaries of iproute2
make all
make install || \
    { echo "iproute2 installation failed: make failed"; exit 1; }

#Traverse to /usr/local/src/ folder
cd ../ || \
    { echo "cd failed"; exit 1; }

#TSN - Time Sensitive Networking, a standard that addresses the transmission of very low transmission latency using the synchronized clocks in the entire network
#To use TSN in Linux, first synchronize the clocks in the network using Linux PTP
#Clone and install Linux PTP using the below commands
git clone https://github.com/richardcochran/linuxptp.git || \
    { echo "linuxptp installation failed: git clone failed"; exit 1; }

#Traverse to linuxptp folder
cd linuxptp/ || \
    { echo "cd failed"; exit 1; }

#You should be able to take the master branch and get the latest Linux PTP.
#But we tested the whole setup in a particular SHA (linuxptp 2.0 version) as mentioned below.
#To avoid any unknown errors, checkout to the particular SHA using the following command
git checkout -f 2f0bfb2837573c4dcbbe440e642aabda0e5d5131 || \
    { echo "linuxptp installation failed: Checking out to 059269d SHA failed"; exit 1; }

#Offset determines the clock synchronization between and within the systems.
#Below commands can be omitted, as we normally use this for troubleshooting.
#Without this modification you will not see the offset values of PTP and PHC2SYS.
#To enable offset debug prints, use the below commands
sed -i '/clock_stats_update(&c->stats, tmv_dbl(c->master_offset), freq);/a pr_info("master offset %10" PRId64 " s%d freq %+7.0f " "path delay %9" PRId64,tmv_to_nanoseconds(c->master_offset), state, freq, tmv_to_nanoseconds(c->path_delay));' clock.c
sed -i '/clock_stats_update(&c->stats, tmv_dbl(c->master_offset), adj);/a pr_info("master offset %10" PRId64 " s%d freq %+7.0f " "path delay %9" PRId64,tmv_to_nanoseconds(c->master_offset), state, adj, tmv_to_nanoseconds(c->path_delay));' clock.c
sed -i '/if (!stats_get_result(s->delay, &delay_stats)) {/a/*' clock.c
sed -i '/delay_stats.mean, delay_stats.stddev);/a*/' clock.c || \
    { echo "linuxptp installation failed: sed command failed"; exit 1; }

#Install the linuxptp using the below commands
make
make install || \
    { echo "linuxptp installation failed: make failed"; exit 1; }

#Linux PTP supports multiple standard configurations. But we are particularly interested in IEEE802.1 AS standard, which is also known as gPTP configuration.
#Copy the gPTP configuration to /etc/linuxptp/ directory using the below command
cp configs/gPTP.cfg /etc/linuxptp/ || \
    { echo "linuxptp installation failed: ptp configuration copy failed"; exit 1; }

#Traverse to /usr/local/src/ folder
cd ../ || \
    { echo "cd failed"; exit 1; }

#We use VLAN tagged PubSub packets for transmission and reception
#To use VLAN, 8021q should be loaded in the kernel
#Check if the /etc/modules have an entry for 8021q. If not, load the 8021q module
grep -q 8021q /etc/modules || \
    echo 8021q >> /etc/modules
