#!/usr/bin/env bash
trap 'killm f; killall owltsim >/dev/null 2>&1; killall lt-owltsim >/dev/null 2>&1' EXIT
#
# Scott Burleigh
# October 4, 2014
#
# CFDP over BP/LTP between two nodes on the same computer, communicating
# across an owltsim link that imposes 3 seconds of one-way light time
# with no loss.  CFDP is started at both nodes and a background cfdptest
# task, which receives and documents service indications, runs at each
# node.  Node 1 then "puts" a file to node 2 and issues a proxy "get" to
# fetch a file from node 2.  Both operations run in unacknowledged mode
# with closure requested by the file sender in each direction.

# documentation boilerplate
CONFIGFILES=" \
./global.ionrc \
./1.ipn.ltp/node.ionrc \
./1.ipn.ltp/node.ionconfig \
./1.ipn.ltp/node.ionsecrc \
./1.ipn.ltp/node.ltprc \
./1.ipn.ltp/node.owltsim \
./1.ipn.ltp/node.bprc \
./1.ipn.ltp/node.ipnrc \
./1.ipn.ltp/node.cfdprc \
./2.ipn.ltp/node.ionrc \
./2.ipn.ltp/node.ionconfig \
./2.ipn.ltp/node.ionsecrc \
./2.ipn.ltp/node.ltprc \
./2.ipn.ltp/node.bprc \
./2.ipn.ltp/node.ipnrc \
./2.ipn.ltp/node.cfdprc \
"

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: demonstrate the CCSDS File Delivery Protocol (CFDP)
    running over BP/LTP and confirm end-to-end file delivery.  Two
    nodes reside on the same computer and communicate across an owltsim
    link with 3 seconds of one-way light time and no loss.  Node 1 puts
    a file to node 2 and issues a proxy get to retrieve a file from
    node 2; both transfers run in unacknowledged mode with closure
    requested.  This is a configuration demonstration and a delivery
    smoke test -- two files are exchanged and their arrival is confirmed
    (present and complete) -- not a throughput measurement (loopback
    throughput is not representative of any real deployment)."
echo
echo "CONFIG: 2 node custom:"
echo
for N in $CONFIGFILES
do
    echo "$N:"
    cat "$N"
    echo "# EOF"
    echo
done
echo "OUTPUT: Terminal messages will relay results."
echo
echo "########################################"

./cleanup
sleep 1

echo "Starting ION..."
export ION_NODE_LIST_DIR=$PWD
rm -f ./ion_nodes

# Start nodes.
cd 1.ipn.ltp
./ionstart
sleep 1
cd ../2.ipn.ltp
./ionstart

sleep 10

echo "Starting cfdptest on each node..."
cd ../1.ipn.ltp
cfdptest < cfdp_cmds >& node1.stdout &
cd ../2.ipn.ltp
cfdptest < cfdp_cmds >& node2.stdout &
cd ..

ROOT=$PWD
WAIT_SECS=45
RETVAL=0

# Delivery confirmation.  Node 1 puts its sourceFile to node 2 (arriving
# as 2.ipn.ltp/receivedFile) and gets node 2's sourceFile (arriving as
# 1.ipn.ltp/receivedFile).  A received file is complete only once it
# exists AND matches the size of the corresponding source file, so poll
# (bounded) for both conditions rather than sleeping a fixed interval and
# checking once.  With 3s OWLT each way the transfers finish well within
# WAIT_SECS; a shortfall fails fast here rather than hanging until the
# harness timeout.
NODE1_RECV="$ROOT/1.ipn.ltp/receivedFile"
NODE2_RECV="$ROOT/2.ipn.ltp/receivedFile"
# Node 1 gets node 2's sourceFile; node 2 receives node 1's sourceFile.
EXP_NODE1=$(wc -c < "$ROOT/2.ipn.ltp/sourceFile" | tr -d '[:space:]')
EXP_NODE2=$(wc -c < "$ROOT/1.ipn.ltp/sourceFile" | tr -d '[:space:]')

echo ""
echo "Waiting up to ${WAIT_SECS}s for both file transfers to complete..."
elapsed=0
got1=0
got2=0
while [ "$elapsed" -lt "$WAIT_SECS" ]
do
    got1=0
    got2=0
    if [ -f "$NODE1_RECV" ]; then
        sz1=$(wc -c < "$NODE1_RECV" | tr -d '[:space:]')
        [ "$sz1" = "$EXP_NODE1" ] && got1=1
    fi
    if [ -f "$NODE2_RECV" ]; then
        sz2=$(wc -c < "$NODE2_RECV" | tr -d '[:space:]')
        [ "$sz2" = "$EXP_NODE2" ] && got2=1
    fi
    if [ "$got1" -eq 1 ] && [ "$got2" -eq 1 ]; then
        break
    fi
    sleep 2
    elapsed=$((elapsed + 2))
done

echo ""
if [ "$got1" -eq 1 ]; then
    echo "Okay: node 1 received file from node 2 (${EXP_NODE1} bytes)."
else
    echo "Error: node 1 did not receive the expected file from node 2."
    RETVAL=1
fi

if [ "$got2" -eq 1 ]; then
    echo "Okay: node 2 received file from node 1 (${EXP_NODE2} bytes)."
else
    echo "Error: node 2 did not receive the expected file from node 1."
    RETVAL=1
fi

echo ""
echo "Stopping ION..."
killm f
killall owltsim >/dev/null 2>&1
killall lt-owltsim >/dev/null 2>&1
echo ""
echo "CFDP demonstration completed."
exit $RETVAL
