if [ -e ~/.config_comb ];then
	. ~/.config_comb
fi;

get_version() {
	if [ ! -d ${FW_PATH} ];then
		echo "Firmware path not found"
		return 1;
	fi;

	APP_VER=$((ssh -p ${2} ${SSH_OPTS} root@${1} "/legato/systems/current/bin/app info combapp" |awk '/app.version/ {print $2}') 2>/dev/null)
	VER=$((ssh -p ${2} ${SSH_OPTS} root@${1} "if [ \"\$(uname -n |cut -d- -f1)\" != \"raspberrypi\" ];then \
			/legato/systems/current/bin/cm info; \
		else \
			 awk -F: '/^Model/ {printf \"%-30s%s\r\n\", \"Device:\", \$2}' /proc/cpuinfo;\
		fi" |awk '/Device:/ {print $2}' |tr '-' '_') 2>/dev/null)
	ROOTFS_VER="$((ssh -p ${2} ${SSH_OPTS} root@${1} "/bin/cat /etc/rootfsver.txt" |awk '{print $1}' |tr '.' '_') 2>/dev/null)"

	case ${VER} in
		"WP7607_1")
			COMB_VER="3.6"
			CPU_VER="wp76xx"
			;;
		"WP8548")
			COMB_VER="3.5"
			CPU_VER="wp85"
			;;
		"Raspberry")
			return 0
			;;
		*)
			return 1
			;;
	esac;

	if [ "${APP_VER}" ] && [ "$(echo ${APP_VER} |cut -d. -f1,2)" != "${COMB_VER}" ];then
		APP_VER="";
	fi;

	FW=${FW_PATH}/full-${CPU_VER}.spk
	FW_VER=${FW_PATH}/full-${CPU_VER}.ver

	FW_LEGATO=${FW_PATH}/legato-${CPU_VER}.spk
	FW_LEGATO_VER=${FW_PATH}/legato-${CPU_VER}.ver

	FW_RESET=${FW_PATH}/reset-${CPU_VER}.cwe

	FW_UPDATE=${FW_PATH}/update-${CPU_VER}-${ROOTFS_VER}.spk
	FW_UPDATE_VER=${FW_PATH}/update-${CPU_VER}-${ROOTFS_VER}.ver

	DEF_MAJ=$(cat ${FW_VER} |cut -d. -f3)
	DEF_MIN=$(cat ${FW_VER} |cut -d. -f4)
	if [ -e ${FW_UPDATE_VER} ];then
		SYS_FW_MAJ=$(awk -F. '{printf "%s",$3}' ${FW_UPDATE_VER})
		SYS_FW_MIN=$(awk -F. '{printf "%s",$4}' ${FW_UPDATE_VER})
		SYS_FW=${SYS_FW_MAJ}.${SYS_FW_MIN}
	fi;

	return 0
}

# Return 0 if cannot upgrade or is downgrade
# Return 1 if major FW is upgradeable
# Return 2 if rootfs is upgradeable
# Return 3 4 5 for app major minor patch updateable
check_fw_is_downgrade() {
	if [ ! "${1}" ] || [ ! "${2}" ];then
		return 0
	fi;

	if [ $(echo ${2} |cut -d. -f3) -gt $(echo ${1} |cut -d. -f3) ];then
		return 1
	elif [ $(echo ${2} |cut -d. -f3) -eq $(echo ${1} |cut -d. -f3) ];then
		#Root FS
		if [ $(echo ${2} |cut -d. -f4) -gt $(echo ${1} |cut -d. -f4) ];then
			return 2;
		fi;

		#App Major
		if [ $(echo ${2} |cut -d. -f5) -gt $(echo ${1} |cut -d. -f5) ];then
			return 3;
		fi;

		#App Minor
		if [ $(echo ${2} |cut -d. -f6) -gt $(echo ${1} |cut -d. -f6) ];then
			return 4;
		fi;

		#App Patch
		if [ $(echo ${2} |cut -d. -f7) -gt $(echo ${1} |cut -d. -f7) ];then
			return 5;
		fi;
	fi

	return 0;
}

fw_is_upgrade() {
	if [ "${APP_VER}" ] && [ -e ${FW_VER} ];then
		check_fw_is_downgrade ${APP_VER} $(cat ${FW_VER}) || return 0
	fi;
	return 1;
}

legato_is_upgrade() {
	if [ "${APP_VER}" ] && [ -e ${FW_LEGATO_VER} ];then
		check_fw_is_downgrade ${APP_VER} $(cat ${FW_LEGATO_VER})
		if [ $? -gt 2 ];then
			return 0;
		fi;
	fi;
	return 1;
}

update_is_upgrade() {
	if [ "${APP_VER}" ] && [ -e ${FW_UPDATE_VER} ];then
		check_fw_is_downgrade ${APP_VER} $(cat ${FW_UPDATE_VER})
		if [ $? -gt 2 ];then
			return 0;
		fi;
	fi;
	return 1;
}

get_latest() {
	if [ "${3}" ];then
		CUR_APP=${3}
	else
		CUR_APP=""
	fi;

	if [ "${2}" ];then
		NEW_FW=${2}
	fi;

	if [ ! "${NEW_FW}" ];then
		if [ ${DEF_MAJ} -gt ${SYS_FW_MAJ} ];then
			NEW_FW=${DEF_MAJ}
		else
			NEW_FW=${SYS_FW}
		fi
	fi;

	NEW_FW_MAJ=$(echo ${NEW_FW}. |cut -d. -f1)
	NEW_FW_MIN=$(echo ${NEW_FW}. |cut -d. -f2)

	#If only the maj version is set not minor and majors are same basically ignore
	if [ ! "${NEW_FW_MIN}" ] && [ "${NEW_FW_MAJ}" == "${SYS_FW_MAJ}" ];then
		NEW_FW=${SYS_FW}
		NEW_FW_MAJ=${SYS_FW_MAJ}
		NEW_FW_MIN=${SYS_FW_MIN}
	fi;

	if [ "${SYS_FW}" == "${NEW_FW}" ];then
		FW_UPDATE_TYPE="legato";
	elif [ "${NEW_FW_MIN}" ] && [ "${SYS_FW_MAJ}" == "${NEW_FW_MAJ}" ] && [ "${SYS_FW_MIN}" != "${NEW_FW_MIN}" ];then
		FW_UPDATE_TYPE="rootfs";
	else
		FW_UPDATE_TYPE="full";
	fi

	if [ ! "${NEW_FW_MIN}" ];then
		NEW_FW=${NEW_FW_MAJ}.'*'
	fi;

	FW_ROOT=${1}/${CPU_VER}/comb-firmware-${CPU_VER}-
	UPDATE_VER=$((ls ${FW_ROOT}${COMB_VER}.${NEW_FW}.${CUR_APP}*/comb-${FW_UPDATE_TYPE}*.spk |sort -n |tail -1 |awk -F- '{printf "%s",substr($NF,1,length($NF)-4)}') 2>/dev/null)

	if [ "${APP_VER}" ] && [ "${UPDATE_VER}" ];then
		if [ "${APP_VER}" == "${UPDATE_VER}" ];then
			echo "Update not required"
			return 0
		fi;
		if check_fw_is_downgrade ${APP_VER} ${UPDATE_VER};then
			echo "Downgrade not available"
			return 0
		fi;
	fi;

	FW_FILE=${FW_ROOT}${UPDATE_VER}/comb-${FW_UPDATE_TYPE}-${CPU_VER}-${UPDATE_VER}.spk

	if [ ! "${FW_FILE}" ] || [ ! -e ${FW_FILE} ];then
		return 1;
	fi;
	return 0
}

load_firmware() {
	if [ ! "${1}" ] || [ ! -e "${1}" ];then
		echo "Firmware file does not exist"
		return 1;
	fi;

	echo "Loading Firmware File $(basename ${1})"
	if ! dd if=${1} |ssh -p ${3} ${SSH_OPTS} root@${2} "/legato/systems/current/bin/fwupdate downloadOnly -";then
		return 1
	fi;

	ssh -f -n -p ${3} ${SSH_OPTS} root@${2} "if [ -e combapp.db ];then /usr/bin/sqlite3 combapp.db \"update organisationsetup set value='0' where key = 'orgID' AND idx = -1\";fi; \
						 /legato/systems/current/bin/fwupdate install"
	return $?
}

check_firmware() {
	echo "Checking Firmware"
	ssh ${SSH_OPTS} root@${ECM_ADDR} "/bin/ls /legato/systems/current/apps/combapp" > /dev/null 2>&1
	return $?
}

setup_resolv_conf() {
	if ! ssh ${SSH_OPTS} root@${ECM_ADDR} "if [ ! -e /etc/resolv.conf ] || [ ! -s /etc/resolv.conf ];then /bin/echo \"nameserver ${DNS}\" > /etc/resolv.conf;exit 1;fi" > /dev/null 2>&1;then
		echo "Setup Resolv.conf"
	else
		echo "Resolv.conf exists"
	fi
}

add_ecm_route() {
	echo "Set up route"
	ssh ${SSH_OPTS} root@${ECM_ADDR} "/sbin/ip route del default metric 0;/sbin/ip route add default via ${1} metric 0" > /dev/null 2>&1
	return $?
}

setup_network() {
	#Setup routing via ECM
	setup_resolv_conf

	if ! add_ecm_route ${1};then
		echo "Route failed/exits"
	fi;
}

dnf_update() {
	if ! ssh ${SSH_OPTS} -p ${2} root@${1} \
		"ulimit -s unlimited; \
		 if ! /usr/bin/dnf --refresh check-update;then \
		 echo '/usr/bin/dnf -y --exclude kernel-* --exclude bootfiles* --exclude legato* update;/usr/bin/dnf -y --exclude bootfiles* --exclude kernel-* update;/usr/bin/dnf -y update legato;/usr/bin/comb-ns-update --fix;\
		 /sbin/reboot' |/usr/bin/at now;fi" 2>/dev/null;then
		return $?
	fi;

	return 0
}

system_info() {
	if ! ssh ${SSH_OPTS} -p ${2} root@${1} \
		"echo System info;
		 if [ \"\$(uname -n |cut -d- -f1)\" != \"raspberrypi\" ];then /legato/systems/current/bin/cm info;else \
		 awk -F: '/^Model/ {printf \"%-30s%s\r\n\", \"Device:\", \$2}' /proc/cpuinfo;\
		 awk -F: '/^Serial/ {printf \"%-30s%s\r\n\", \"FSN:\", \$2}' /proc/cpuinfo;fi; \
		 if [ -e /tmp/deviceid.txt ];then printf '%-31s%s\r\n' 'DEVID:' \$(/bin/cat /tmp/deviceid.txt);fi; echo;\
		 if [ -e /etc/lsb-release ];then echo "LSB Info";lsb_release -a;echo;fi; \
		 echo Linux info;/bin/uname -a;echo; \
		 echo Legato info;/legato/systems/current/bin/legato version;echo; \
		 if [ -e /etc/rootfsver.txt ];then echo Root FS info;/bin/cat /etc/rootfsver.txt;echo;fi; \
		 echo Comb App info;/legato/systems/current/bin/app info combapp;echo" 2>/dev/null;then
		return $?
	fi;

	return 0
}

ssh_connect() {
	if [ "${LOCAL_PORT}" ];then
		SSH_OPTS="${SSH_OPTS} -L *:${LOCAL_PORT}:${ECM_ADDR}:22"
	fi;

	ssh ${SSH_OPTS} -p ${2} root@${1}
}

setup_portforward() {
	if [ "${LOCAL_PORT}" ];then
		SSH_OPTS="${SSH_OPTS} -L *:${LOCAL_PORT}:${ECM_ADDR}:22"
	fi;


	ssh -f -N ${SSH_OPTS} root@${ECM_ADDR} > /dev/null 2>&1
}


ssh_test() {
	for test in 1 2 3 4 5 6 7 8 9 10;do
		if ssh ${SSH_TEST_OPTS} -p ${2} root@${1} /bin/true > /dev/null 2>&1;then
			test=0;
			break;
		fi;
		sleep 3
	done

	return ${test}
}

ssh_agent_start() {
	SA_FILE=/tmp/comb-${UID}-ssh-agent

	if [ "${SSH_KEY}" ];then
		SSH_OPTS="-i ${SSH_KEY} ${SSH_OPTS}"
	fi;

	SSH_TEST_OPTS="${SSH_OPTS} -oConnectTimeout=5 -oNumberOfPasswordPrompts=${ASK_TEST_PW}"
	SSH_OPTS="${SSH_OPTS} -oConnectTimeout=30 -oNumberOfPasswordPrompts=${ASK_PW}"

	if [ -e ${SA_FILE} ];then
		. ${SA_FILE} >/dev/null
	fi;

	if [ ! -e ${SA_FILE} ] || [ ! "${SSH_AGENT_PID}" ] || ! ps -p ${SSH_AGENT_PID} > /dev/null;then
		if [ -e ${SA_FILE} ];then
			rm ${SA_FILE}
		fi;
		touch ${SA_FILE}
		chmod 600 ${SA_FILE}
		ssh-agent -s >> ${SA_FILE}
		. ${SA_FILE} >/dev/null
	fi;

	if [ "${ASK_PW}" != "0" ];then
		ssh_agent_add_key >/dev/null
	fi;
}

ssh_agent_add_key() {
	if [ -e ${SSH_KEY} ] && ! (ssh-add -l | grep ${SSH_KEY}) >/dev/null 2>&1;then
		ssh-add ${SSH_KEY}
	fi;
}

mount_sys() {
	for sysdir in dev proc sys run;do
		if [ ! -d ${1}/${sysdir} ];then
			mkdir ${1}/${sysdir}
		fi;
	done;
	mount -t devtmpfs devfs ${1}/dev
	mount -t sysfs sysfs ${1}/sys
	mount -t proc proc ${1}/proc
	mount -t tmpfs none ${1}/run

	if [ ! -d ${1}/var/volatile ];then
		mkdir -p ${1}/var/volatile
	fi;
	mount -t tmpfs none ${1}/var/volatile/

	for voldir in tmp log;do
		if [ ! -d ${1}/var/volatile/${voldir} ];then
			mkdir ${1}/var/volatile/${voldir}
		fi;
	done
	mkdir -p ${1}/run/lock
	mkdir -p ${1}/run/resolvconf
	mount -t devpts none ${1}/dev/pts
}

umount_image(){
	if [ -x /etc/init.d/wpnetlink ] && [ -e /tmp/wpnetlink-start ];then
		rm /tmp/wpnetlink-start
		/etc/init.d/wpnetlink start
	fi;

	if [ ! -e /dev/comb-ns-root ];then
		echo "Not mounted"
		return 1
	fi;

	if [ ! -d ${1} ];then
		echo "Directory missing"
		return 1
	fi;

	umount_sys ${1} || return 1

	if losetup /dev/comb-ns-root >/dev/null 2>&1;then
		losetup -d /dev/comb-ns-root
	fi;
	rm /dev/comb-ns-root
}

mount_image() {
	if [ -e /dev/comb-ns-root ];then
		echo "Already mounted"
		return 0
	fi;

	if ! check_ns_image ${1}.img;then
		echo "Image not found"
		return 1
	fi;

	if [ ! -d ${1} ] && [ -e ${1}.img ];then
		mkdir ${1}
	fi;

	LOOP=$(losetup -f)
	ln -s ${LOOP} /dev/comb-ns-root

	losetup -P ${LOOP} ${1}.img
	if [ -b ${LOOP}p5 ];then
		e2fsck -C 0 -fy ${LOOP}p5
		e2fsck -C 0 -fy ${LOOP}p4
		mount ${LOOP}p5 ${1}
		mount ${LOOP}p4 ${1}/boot
	else
		e2fsck -C 0 -fy ${LOOP}p2
		fsck.fat -a ${LOOP}p1
		mount ${LOOP}p2 ${1}
		mount ${LOOP}p1 ${1}/boot
	fi;
	mount_sys ${1}
}

fdisk_ns() {
	parted -s ${1} \
		mklabel msdos \
		mkpart primary fat32 1M 100M \
		mkpart primary ext4 100M 100%
}

fdisk_combo() {
	parted -a none -s ${1} \
		mklabel gpt \
		mkpart fsbl1 34s 545s \
		mkpart fsbl2 546s 1057s \
		mkpart fip 1058s 9249s \
		mkpart bootfs ext4 9250s 140321s \
		mkpart rootfs ext4 140322s 100% \
		set 4 legacy_boot on
	sgdisk ${1} -u 5:e91c4e10-16e6-4c0e-bd0e-77becf4a3582
}

expand_image_combo() {
	dd status=progress conv=nocreat,notrunc oflag=append if=/dev/zero bs=1M count=512 of=${1}

	LOOP=$(losetup -f -P --show ${1})
	fdisk_combo ${LOOP}
	e2fsck -C 0 -fy ${LOOP}p4
	e2fsck -C 0 -fy ${LOOP}p5
	resize2fs ${LOOP}p5
	losetup -d ${LOOP}
}

expand_image_ns() {
	dd status=progress conv=nocreat,notrunc oflag=append if=/dev/zero bs=1M count=512 of=${1}

	LOOP=$(losetup -f -P --show ${1})
	fdisk_ns ${LOOP}
	fsck.fat -a ${LOOP}p1
	e2fsck -C 0 -fy ${LOOP}p2
	resize2fs ${LOOP}p2
	losetup -d ${LOOP}
}

expand_image() {
	if [ -e /dev/comb-ns-root ];then
		echo "Already mounted"
		return 0
	fi;

	if ! check_ns_image ${1}.img;then
		echo "Image not found"
		return 1
	fi;

	if [ ! -d ${1} ] && [ -e ${1}.img ];then
		mkdir ${1}
	fi;

	LOOP=$(losetup -f -P --show ${1}.img)

	if [ -b ${LOOP}p5 ];then
		losetup -d ${LOOP}
		expand_image_combo ${1}.img
	else
		losetup -d ${LOOP}
		expand_image_ns ${1}.img
	fi

}

create_ns_image() {
	MNTDIR=$(mktemp -d -p /tmp tmpmnt-XXXXXXXXX)

	if [ ! "${MNTDIR}" ];then
		echo "Cannot create mount"
		return 1
	fi;

	dd status=progress if=/dev/zero of=${1} bs=1M count=1536
	fdisk_ns ${1}

	LOOP=$(losetup -P -f --show ${1})
	if [ ! "${LOOP}" ];then
		echo "Could not allocate loop device"
		rm -rf ${MNTDIR}
		rm ${1}
		return 1
	fi;

	mkfs.vfat ${LOOP}p1 -n BOOT
	mkfs.ext4 ${LOOP}p2 -L ROOT

	mount ${LOOP}p2 ${MNTDIR}
	mkdir ${MNTDIR}/boot
	mount ${LOOP}p1 ${MNTDIR}/boot

	tar -C ${MNTDIR} -xf ${2}

	umount ${MNTDIR}/boot ${MNTDIR}
	rm -rf ${MNTDIR}
	losetup -d ${LOOP}
}

create_import_image() {
	if [ ! "${3}" ] || [ ! "${4}" ];then
		echo "No output image specified"
		return 1
	elif [ ! -e ${3}.${4} ];then
		wget ${2} -O ${3}.${4} || return 1
	elif [ ${3}.img -nt ${3}.${4} ];then
		echo "Image exists and older"
		return 0
	fi;

	case ${1} in
		"raspberrypi_cm4_64")
			create_ns_image ${3}.img ${3}.${4} || return 1
		;;
		"stm32mp15_ns_combo")
			bunzip2 -k ${3}.${4} || return 1
		;;
	esac
}

unpack_ns_image_combo() {
	dd status=progress if=/dev/zero of=${1} bs=1M count=1026
	LOOP=$(losetup -f -P --show ${1})

	dd conv=notrunc,nocreat if=${1}.pack status=progress bs=1K skip=17 count=70144 of=${LOOP}

	fdisk_combo ${LOOP}

	mkfs.ext4 ${LOOP}p4 -b 1024 -L bootfs
	mkfs.ext4 ${LOOP}p5 -L rootfs
 
	e2image -pra -o 4736000 ${1}.pack ${LOOP}p4
	e2image -pra -o 71844864 ${1}.pack ${LOOP}p5

	echo "Checking File System"
	e2fsck -C 0 -fy ${LOOP}p4
	e2fsck -C 0 -fy ${LOOP}p5
	echo "Expanding File System"
	resize2fs ${LOOP}p4
	resize2fs ${LOOP}p5
	losetup -d ${LOOP}
}

unpack_ns_image_raspi() {
	dd status=progress if=/dev/zero of=${1} bs=1M count=1536
	LOOP=$(losetup -f -P --show ${1})

	fdisk_ns ${LOOP}

	mkfs.vfat ${LOOP}p1 -n BOOT
	dd conv=notrunc,nocreat if=${1}.pack status=progress bs=1M skip=1 count=94 of=${LOOP}p1

	mkfs.ext4 ${LOOP}p2 -L ROOT
	e2image -pra -o 99614720 ${1}.pack ${LOOP}p2

	echo "Checking File System"
	fsck.fat -a ${LOOP}p1
	e2fsck -C 0 -fy ${LOOP}p2
	echo "Expanding File System"
	resize2fs ${LOOP}p2
	losetup -d ${LOOP}
}

unpack_ns_image() {
	if [ -e ${1} ];then
		echo "Image exists"
		return 1;
	fi;

	if [ -e ${1}.pack ] && [ -e ${1}.pack.xz ] && [ ${1}.pack.xz -nt ${1}.pack ];then
		rm ${1}.pack
		xz -d -k ${1}.pack.xz --verbose
	elif [ -e ${1}.pack.xz ] && [ ${1}.pack.xz -nt ${1}.pack ];then
		xz -d -k ${1}.pack.xz --verbose
	fi;

	if [ ! -e ${1}.pack ];then
		echo "No packed image found"
		return 1
	fi;

	LOOP=$(losetup -f -P --show ${1}.pack)
	if [ -b ${LOOP}p5 ];then
		losetup -d ${LOOP}
		unpack_ns_image_combo ${1}
	else
		losetup -d ${LOOP}
		unpack_ns_image_raspi ${1}
	fi
}

check_ns_image() {
	if [ ! "${1}" ];then
		return 1;
	elif [ -e ${1} ];then
		return 0;
	elif [ -e ${1}.pack ] || [ -e ${1}.pack.xz ];then
		unpack_ns_image ${1}
	elif [ -e ${1}.xz ];then
		xz -d -k ${1}.xz --verbose
	elif [ "${ARCH}" ] && [ "${IMPORT_URL}" ] && [ "${IMPORT_EXT}" ];then
		create_import_image ${ARCH} ${IMPORT_URL} $(dirname ${1})/$(basename -s .img ${1}) ${IMPORT_EXT} || return 1
	else
		return 1;
	fi;
}

pack_ns_image_combo() {
	e2fsck -C 0 -fy ${2}p5
	resize2fs -p -M ${2}p5
	e2fsck -C 0 -fy ${2}p5
	resize2fs -p -M ${2}p5
	e2fsck -C 0 -fy ${2}p5
	resize2fs -p -M ${2}p5

	e2fsck -C 0 -fy ${2}p4
	resize2fs -p -M ${2}p4
	e2fsck -C 0 -fy ${2}p4
	resize2fs -p -M ${2}p4
	e2fsck -C 0 -fy ${2}p4
	resize2fs -p -M ${2}p4

	e2image -pra -O 71844864 ${2}p5 ${1}.pack
	resize2fs -p ${2}p4
	resize2fs -p ${2}p5
	losetup -d ${2}

	dd status=progress conv=nocreat,notrunc if=${1} bs=1K count=70160 of=${1}.pack
	dd status=progress conv=nocreat,notrunc oflag=append if=/dev/zero bs=1M count=1 of=${1}.pack

	LOOP=$(losetup -f -P --show ${1}.pack)

	fdisk_combo ${LOOP}

	e2fsck -C 0 -fy ${LOOP}p4
	e2fsck -C 0 -fy ${LOOP}p5
	resize2fs -p ${LOOP}p4
	resize2fs -p ${LOOP}p5

	losetup -d ${LOOP}
}

pack_ns_image_raspi() {
	fsck.fat -a ${2}p1
	e2fsck -C 0 -fy ${2}p2
	resize2fs -p -M ${2}p2
	e2fsck -C 0 -fy ${2}p2
	resize2fs -p -M ${2}p2
	e2fsck -C 0 -fy ${2}p2
	resize2fs -p -M ${2}p2
	e2image -pra -O 99614720 ${2}p2 ${1}.pack
	resize2fs -p ${2}p2
	losetup -d ${2}

	dd status=progress conv=nocreat,notrunc if=${1} bs=1M count=95 of=${1}.pack
	dd status=progress conv=nocreat,notrunc oflag=append if=/dev/zero bs=1M count=1 of=${1}.pack
	LOOP=$(losetup -f -P --show ${1}.pack)

	fdisk_ns ${LOOP}
	fsck.fat -a ${LOOP}p1
	e2fsck -C 0 -fy ${LOOP}p2
	resize2fs -p ${LOOP}p2

	losetup -d ${LOOP}
}

pack_ns_image() {
	if ! check_ns_image ${1};then
		echo "Image not found"
		return 1;
	fi;

	if [ -e ${1}.pack ] && [ ${1}.pack -nt ${1} ];then
		echo "Already packed"
		return 0;
	fi;

	if [ -e ${1}.pack ];then
		rm ${1}.pack
	fi;

	LOOP=$(losetup -f -P --show ${1})
	if [ -b ${LOOP}p5 ];then
		pack_ns_image_combo ${1} ${LOOP}
	else
		pack_ns_image_raspi ${1} ${LOOP}
	fi;
}

xz_ns_image() {
	if [ ! "${1}" ] || [ ! -e ${1} ];then
		echo "Image not found"
		return 1;
	fi;

	if [ -e ${1}.xz ] && [ ${1}.xz -nt ${1} ];then
		echo "Already compressed"
		return 0;
	fi;

	if [ ! -e ${1}.xz ] || [ ${1} -nt ${1}.xz ];then
		if [ -e ${1}.xz ];then
			rm ${1}.xz
		fi;
		xz -T 0 -k --verbose ${1}
	fi;
}

umount_sys(){
	for sysdir in /dev/pts /dev /proc /sys /var/volatile /boot /run;do
		umount ${1}${sysdir}
	done;
	umount ${1} || return 1
}

ns_img_to_flash() {
		fdisk_ns ${2}

		mkfs.vfat ${2}1 -n BOOT
		dd conv=notrunc,nocreat if=${1} status=progress bs=1M skip=1 count=94 of=${2}1

		mkfs.ext4 ${2}2 -L ROOT
		e2image -ra -o 99614720 ${1} ${2}2
}

flash_ns_bootloader() {
	echo "Updating bootloader"

	if [ -d ${FW_PATH}/raspberrypi-cm4-64/recovery ];then
		rpiboot -d ${FW_PATH}/raspberrypi-cm4-64/recovery
	elif [ -d /usr/share/rpiboot/recovery ];then
		rpiboot -d /usr/share/rpiboot/recovery
	fi;

	if [ "$?" == "0" ];then
		echo "Repower board"
		sleep 5
	fi;
}

mount_ns_board() {
	if [ -x /etc/init.d/wpnetlink ] && /etc/init.d/wpnetlink status;then
		/etc/init.d/wpnetlink stop
		if /etc/init.d/wpnetlink status >/dev/null 2>&1;then
			killall -9 wpnetlink
		fi;
		if /etc/init.d/wpnetlink status;then
			echo "wpnetlink not stopped"
			exit 1;
		fi;
		touch /tmp/wpnetlink-start
	fi;

	rpiboot
	echo "Waiting For Flash"
	sleep 10
	for FLASH in /dev/sd?;do
		continue;
	done;

	if [ ! "${FLASH}" ] || [ ! -b "${FLASH}" ];then
		echo "Block device does not exit"
		return 1;
	fi

	echo "Unmounting existing file system"
	awk -v BLK=${FLASH} '$1 ~ BLK {printf "umount %s\n",$2}' /proc/mounts |sh

	ln -s ${FLASH} /dev/comb-ns-root

	e2fsck -C 0 -fy ${FLASH}2
	fsck.fat -fy ${FLASH}1

	mount ${FLASH}2 ${1}
	mount ${FLASH}1 ${1}/boot

	mount_sys ${1}
}

flash_ns_board() {
	if [ ! -d ${FW_PATH} ];then
		echo "Firmware path not found"
		return 1;
	fi;

	flash_ns_bootloader

	rpiboot
	echo "Waiting For Flash"
	sleep 10
	for FLASH in /dev/sd?;do
		continue;
	done;

	if [ ! "${FLASH}" ] || [ ! -b "${FLASH}" ];then
		echo "Block device does not exit"
		return 1;
	fi

	echo "Sending flash image"
	if [ -e ${FW_PATH}/raspberrypi-cm4-64/comb-ns.img ];then
		FW_FILE=${FW_PATH}/raspberrypi-cm4-64/comb-ns.img
	elif [ -e ~/comb-ns.img ];then
		FW_FILE=~/comb-ns.img
	fi;
	if [ -e ${FW_FILE} ] && [ ! -e ${FW_FILE}.pack ];then
		pack_ns_image ${FW_FILE}
	elif [ -e ${FW_FILE} ] && [ -e ${FW_FILE}.pack ] && [ ${FW_FILE} -nt ${FW_FILE}.pack ];then
		pack_ns_image ${FW_FILE}
	elif [ ! -e ${FW_FILE}.pack ] && [ -e ${FW_FILE}.pack.xz ];then
		xz -d -k ${FW_FILE}.pack.xz --verbose
	elif [ -e ${FW_FILE}.pack ] && [ -e ${FW_FILE}.pack.xz ] && [ ${FW_FILE}.pack.xz -nt ${FW_FILE}.pack ];then
		rm ${FW_FILE}.pack
		xz -d -k ${FW_FILE}.pack.xz --verbose
	fi;

	echo "Unmounting existing file system"
	awk -v BLK=${FLASH} '$1 ~ BLK {printf "umount %s\n",$2}' /proc/mounts |sh

	if [ -e ${FW_FILE}.pack ];then
		ns_img_to_flash ${FW_FILE}.pack ${FLASH}
	elif [ -e ${FW_FILE} ];then
		ns_img_to_flash ${FW_FILE} ${FLASH}
	elif [ -e ${FW_FILE}.pack.xz ];then
		xz -d -c ${FW_FILE}.pack.xz |dd status=progress bs=1M of=${FLASH}
	elif [ -e ${FW_FILE}.xz ];then
		xz -d -c ${FW_FILE}.xz |dd status=progress bs=1M of=${FLASH}
	else
		echo "No flash file found"
		return 1;
	fi

	echo "Resize partition in MBR"
	parted ${FLASH} -s resizepart 2 100%
	echo "Checking File System"
	fsck.fat -a ${FLASH}1
	e2fsck -C 0 -fy ${FLASH}2
	echo "Expanding File System to fit flash"
	resize2fs ${FLASH}2
}

if [ ! "${ECM_ADDR}" ];then
	ECM_ADDR=192.168.2.2
fi;

if [ ! "${USB_ADDR}" ];then
	USB_ADDR=192.168.2.3
fi;

if [ ! "${DNS}" ];then
	DNS=8.8.8.8
fi;

if [ ! "${LOCAL_PORT}" ];then
	LOCAL_PORT=2222
fi;

if [ ! "${REMOTE_ADDR}" ];then
	REMOTE_ADDR="192.168.10.59"
fi;

if [ ! "${SSH_KEY}" ] && [ -e ~/.ssh/id_rsa ];then
	SSH_KEY=~/.ssh/id_rsa
fi;

if [ ! "${ASK_PW}" ];then
	ASK_PW=3;
fi;

if [ "${ASK_PW}" == "0" ];then
	ASK_TEST_PW=0
else
	ASK_TEST_PW=1
fi;

if [ ! "${PID_FILE}" ];then
	PID_FILE=/run/lock/wpnetlink
fi;

if [ ! "${FLOCK_TIME}" ];then
	FLOCK_TIME=30
fi;

if [ ! ${FW_PATH} ];then
	FW_PATH=/var/opt/comb
fi;

if [ ! "${FW_SRV_DIR}" ];then
	FW_SRV_DIR=${FW_PATH}
fi;

if [ ! "${SSH_OPTS}" ];then
	SSH_OPTS="-q -oUserKnownHostsFile=/dev/null -oHostKeyAlgorithms=+ssh-rsa -oPubkeyAcceptedKeyTypes=+ssh-rsa -oStrictHostKeyChecking=no -oTCPKeepAlive=yes -oServerAliveInterval=30"
fi;

ssh_agent_start
