#!/bin/sh
#********************************************************************************
# FILE NAME  : nfs_update
# DESCRIPTION: firmware updating script
# Copyright (C) 2012 Elphel, Inc
# -----------------------------------------------------------------------------**
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  The four essential freedoms with GNU GPL software:
#  * the freedom to run the program for any purpose
#  * the freedom to study how the program works and change it to make it do what you wish
#  * the freedom to redistribute copies so you can help your neighbor
#  * the freedom to distribute copies of your modified versions to others
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------------**

# TODO:
# CVS log
# add local update (script to overwrite any files)
# save/restore /etc/reflash.conf
echo "running $* in `pwd`"
#running update no_reboot in /var/tmp/nfs_mount_point/latest80
ENTRYPWD=`pwd`
echo "mount"
mount
DIRNAME=`basename $ENTRYPWD`
echo "DIRNAME == "$DIRNAME
echo "mount | grep -c DIRNAME == "`mount | grep -c "$DIRNAME"`
LOGSLINK="/logs"
#Old firmware - write log to the same directory
if [ `mount | grep -c "$DIRNAME"` != 0 ] ; then
  LOGSLINK=""
  echo "Updating from older firmware, can not reach logs directory."
  echo "Will use current directory to save reflash log."
fi

# grep max-count does not work in busybox
NFS_MOUNT_POINT=`mount | grep  "nfs " | awk {'print $3'}`
NFS_MOUNT_POINT=`echo $NFS_MOUNT_POINT | awk {'print $1'}`
echo "\$NFS_MOUNT_POINT=$NFS_MOUNT_POINT"

LOG=${NFS_MOUNT_POINT}${LOGSLINK}/flash.log
LOCK=${NFS_MOUNT_POINT}${LOGSLINK}/lock
F_LOG=${NFS_MOUNT_POINT}${LOGSLINK}/log
LOCK_DVD=$LOCK

# check and create 'logs' folder if doesn't exist
PWD=`pwd`
cd ${NFS_MOUNT_POINT}
if [ ! -d ./logs ] ; then
	mkdir ./logs
	chmod a+w ./logs
fi
cd $PWD

echo "LOG == "$LOG
echo "LOCK == "$LOCK
echo "ls == "
ls

# get actual MAC of the camera, if exists
MAC=""
MAC_REAL=`bootblocktool -x SERNO`
MAC_CMD=$MAC_REAL

CMDLINE=`cat /proc/cmdline`
for l in ${CMDLINE} ; do
    a=`echo $l | grep 'mac='`
    if [ "$a" != "" ] ; then
        MAC_CMD=`echo $a | sed -e 's/://g' | sed -e 's/mac=//'`
    fi
done

if [ "$1" = "all" ] ; then
    MAC=$MAC_CMD
    LOG=$LOG.$MAC
    LOCK=$LOCK.$MAC
    MAC_REAL=$MAC_CMD
else
    MAC=$MAC_REAL
    LOG=$LOG.$MAC
    LOCK=$LOCK.$MAC
fi

# log files for prod353 system
## try to store IP conf
if [ -n "`mount | grep /mnt/flash`" ] ; then
  echo "Archiving and storing selected files (see /etc/restore.conf, /etc/restore.conf.custom), it is OK if some files are missing"
  echo "These files will be copied back during first boot after reflash (/etc/init.d/restore)"
  mount -t jffs2 /dev/mtdblock5 /mnt/.store
  if [ ! -d /mnt/.store/etc ] ; then
    mkdir /mnt/.store/etc
  fi
#Next will anly be used if the current software is older than 8.1.2
  if [ ! -f /etc/restore.conf ] ; then
  cat << 'EOF' > /etc/restore.conf
/etc/restore.conf.custom
/etc/conf.d/net.eth0
/etc/conf.d/ccamftp.conf
/etc/conf.d/hostname
/etc/autocampars.xml
/etc/10364.config
/etc/passwd
EOF
  fi
# Preserve files to survive through reflash, will be restored at first boot
  cat /etc/restore.conf /etc/restore.conf.custom | xargs tar czf /mnt/.store/restore.tar.gz
#cp -f /etc/conf.d/net.eth0 /mnt/.store/etc/
  sync
  if [ "$1" != "rw" ] ; then # why do we need to keep it mounted in "rw" mode?
    umount /mnt/.store
  fi
else
  echo "nfs_update: /mnt/flash is not mounted, so no configuration files will be preserved" 
fi
# MD5SUM
echo "check MD5SUMs"
PWD_MD5=`pwd`
cd $ENTRYPWD
md5sum part0.img part1.img part2.img part3.img kimage partitions.conf >> /tmp/MD5SUM_new.txt
M1=`cat /tmp/MD5SUM_new.txt`
M2=`cat ./MD5SUM`
if [ "$M1" != "$M2" ] ; then
	echo "MD5SUMs wrong, reflash failed, reboot now"
	sleep 5
	reboot -f
else
	echo "MD5SUMs correct"
fi

# copy images to flash
if [ "$1" = "rw" ] ; then
  rm -Rf /mnt/flash/.images
  echo "copy images to the flash"
  mkdir /mnt/flash/.images
  echo "...copy part0.img"
  cp ./part0.img /mnt/flash/.images/part0.img
  echo "...copy part1.img"
  cp ./part1.img /mnt/flash/.images/part1.img
  echo "...copy part2.img"
  cp ./part2.img /mnt/flash/.images/part2.img
  echo "...copy part3.img"
  cp ./part3.img /mnt/flash/.images/part3.img
  echo "...sync"
  sync
  echo "copy complete"

  IMAGES_PWD=`pwd`
  cd /mnt/flash/.images/
  md5sum part0.img part1.img part2.img part3.img > /tmp/MD5SUM_new.txt
  cd $IMAGES_PWD
  md5sum kimage partitions.conf >> /tmp/MD5SUM_new.txt

  M1=`cat /tmp/MD5SUM_new.txt`
  M2=`cat ./MD5SUM`
  if [ "$M1" != "$M2" ] ; then
    echo "MD5SUMs at flash wrong, reflash failed, reboot now"
    sleep 5
    reboot -f
  else
  	echo "MD5SUMs at flash correct"
  fi
fi

# check NFS filesystem RW/RO mode
LOG_DISABLED="0"
echo "check NFS filesystem RW/RO mode"
echo "test" >> $F_LOG.${MAC_REAL}.txt
if [ -f $F_LOG.${MAC_REAL}.txt ] ; then
	rm $F_LOG.${MAC_REAL}.txt
	echo "NFS filesystem in RW mode"
else
	LOG_DISABLED="1"
	echo "NFS filesystem in RO mode"
fi
cd $PWD_MD5

# looks like IRQ disabling cause soft lockup for streamer...
# TODO: check what is wrong with it
#echo "Disabling DMA from FPGA..."
## turn off IRQ and DMA of the compressor
## to register X313_WA_IRQ_DIS - to disable interrupts
#fpcf -w 1D FFFF
## to register X313_WA_DMACR - to disable DMA
#fpcf -w 01 0000

#should be done by "init ..."
echo "Killing applications..."
killall -q respawnd
KILLLIST=`ps -w | grep " /usr/local" | sed -e 's/^ *\([^ ]*\) *[^ ]* *[^ ]* *[^ ]* *\([^ ]*\).*/\1 \2/' | grep "/usr/local" | sed -e 's/^\([^ ]*\) .*/\1/'`
#troubleshooting getting stuck after "Killing applications..."
ps -w
echo $KILLLIST
if [ -n "$KILLLIST" ] ; then
  kill -9 $KILLLIST
else
  echo "nothing to kill"
fi
# Let's see what is still running
ps -w

echo "Disabling DMA from FPGA..."
# turn off IRQ and DMA of the compressor
# to register X313_WA_IRQ_DIS - to disable interrupts
if [ -n "`which fpcf`" ] ; then
  fpcf -w 1D FFFF
# to register X313_WA_DMACR - to disable DMA
  fpcf -w 01 0000
fi
## prepare for reflash...
echo "prepare for reflash"
2> /dev/console
#init 4
cd /var/tmp/
cp /bin/flash_erase ./
cp /bin/nandwrite ./
cp /bin/nanddump ./
cp /bin/busybox ./
cp /bin/bootblocktool ./
cp /usr/sbin/mii-diag ./

# create links for programs copy at the ramfs, and don't use rootfs
links="mount chmod sleep sync halt rm cp ls"
for link in ${links} ; do
	ln -s ./busybox $link
done
PATH=/var/tmp/
export PATH

if [ "$1" = "rw" ] ; then
  ./ls -l /mnt/flash/.images/part0.img
  ./ls -l /mnt/flash/.images/part1.img
  ./ls -l /mnt/flash/.images/part2.img
  ./ls -l /mnt/flash/.images/part3.img

  mount -r -o remount /mnt/flash

  ./ls -l /mnt/flash/.images/part0.img
  ./ls -l /mnt/flash/.images/part1.img
  ./ls -l /mnt/flash/.images/part2.img
  ./ls -l /mnt/flash/.images/part3.img
fi

if [ "$LOG_DISABLED" != "1" ] ; then
	echo $MAC_REAL > $F_LOG.start.$MAC_CMD
	echo "lock" > $LOCK
	echo "lock" > $LOCK_DVD
	chmod a+w $LOCK
	chmod a+w $LOCK_DVD
fi

if [ "$LOG_DISABLED" = "1" ] ; then
	LOG="/dev/null"
	echo "R/O NFS filesystem - don't write log file"
else
	echo "reflash and write log to $LOG on NFS server"
fi

echo "====" >> $LOG
echo "---- reflash " >> $LOG
echo "----" >> $LOG
echo "You should ignore all messages below like    JFFS2 notice: (864) jffs2_get_inode_nodes: Node header CRC failed at 0x91794c"
echo "  we can't unmount partitions before reflashing, but they are in read-only mode"
echo "  so this notices are confusion of the FS driver about changes in rewritten FS"
echo "  and can't affect the new flashed filesystem."
if [ "$1" != "rw" ] ; then
  ${ENTRYPWD}/nfs_flashitall $1 $MAC ${ENTRYPWD} >> $LOG
else
  ${ENTRYPWD}/nfs_flashitall $1 $MAC ${ENTRYPWD}
fi
echo "----" >> $LOG
echo "---- done " >> $LOG
echo "====" >> $LOG
echo "" >> $LOG
sleep 1
echo "===="
echo "camera reflashing done"
echo "===="
if [ -e /etc/init.d/flash ] ; then
   sync
fi

if [ "$LOG_DISABLED" != "1" ] ; then
	rm -f $LOCK_DVD
	rm -f $LOCK
	echo $MAC_REAL > $F_LOG.stop.$MAC_CMD
fi

if [ "$2" = "no_reboot" ] ; then
    echo "don't reboot - wait for reset by power"
    echo "turn off yellow lamp on the camera"
    ./mii-diag -x 23 -y 14 eth0
    halt
    while [ "1" != "2" ] ; do
	sleep 1
    done
    exit
fi

if [ "$1" != "all" ] ; then
   echo "reboot..."
   sleep 1
   ./busybox reboot -f
   #reboot
fi
