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

wpnetlink_stop() {
	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;
}

wpnetlink_start() {
	if [ -x /etc/init.d/wpnetlink ] && [ -e /tmp/wpnetlink-start ];then
		rm /tmp/wpnetlink-start
		/etc/init.d/wpnetlink start
	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 [ ! -d /opt/legato ];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/rpm  -e --justdb --nodeps --noscripts kernel-image-image-5.4.72-v8-5.4.72*;/usr/bin/rpm  -e --justdb --nodeps --noscripts kernel-cmdline-5.4.72*;\
		       /usr/bin/rpm  -e --justdb --nodeps --noscripts legato;/usr/bin/rpm  -e --justdb --nodeps --noscripts legato-script;/usr/bin/dnf -y install legato-script;\
		       /usr/bin/dnf -y --exclude kernel-* --exclude bootfiles* --exclude legato* update;/usr/bin/dnf -y --exclude bootfiles* --exclude kernel-* update;\
		       /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 [ ! -d /opt/legato ];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
}

mount_image_export() {
	if [ ! -x /usr/sbin/exportfs ];then
		echo "NFS Server Not Installed"
		return 1
	fi;

	if [ ! -d /sys/module/nfsd ];then
		/sbin/modprobe nfsd
	fi;

	if [ -d ${1}/etc ];then
		date -u +%4Y%2m%2d%2H%2M%2S 2>/dev/null > ${1}/etc/timestamp
	fi;

	exportfs -i -o rw,hide,fsid=1,no_root_squash ${2-*}:${1}
	exportfs -i -o rw,hide,fsid=0,no_root_squash ${2-*}:$(dirname ${1})
}

mount_image_unexport() {
	if [ ! -x /usr/sbin/exportfs ];then
		echo "NFS Server Not Installed"
		return 1
	fi;

	if [ "${1}" ] && [ ! "${2}" ];then
		exportfs -s |awk -v IMG_ROOT="${1}"  '$1 == IMG_ROOT {printf "exportfs -u %s:%s\n",substr($2,1,index($2,"(")-1),$1}' |sh
		exportfs -s |awk -v IMG_ROOT="$(dirname ${1})"  '$1 == IMG_ROOT {printf "exportfs -u %s:%s\n",substr($2,1,index($2,"(")-1),$1}' |sh
	elif [ ! "${2}" ];then
		echo "Client IP not set"
	else
		exportfs -u ${2}:${1}
		exportfs -u ${2}:$(dirname ${1})
	fi;
}

umount_image(){
	wpnetlink_start

	if [ ! -e ${TMPDEV} ];then
		echo "Not mounted"
		return 1
	fi;

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

	mount_image_unexport ${1}

	umount_sys ${1} || return 1

	if losetup ${TMPDEV} >/dev/null 2>&1;then
		losetup -d ${TMPDEV}
	fi;
	rm ${TMPDEV}
}

mount_image_blk() {
	if [ -b ${1}p3 ];then
		fsck_combo ${1}
		mount ${1}p3 ${2}
		BOOT_P="${1}p2"
	elif [ -b ${1}p2 ];then
		fsck_ns ${1}
		mount ${1}p2 ${2}
		BOOT_P="${1}p1"
	elif [ -b ${1}3 ];then
		fsck_combo ${1}
		mount ${1}3 ${2}
		BOOT_P="${1}2"
	elif [ -b ${1}2 ];then
		fsck_ns ${1}
		mount ${1}2 ${2}
		BOOT_P="${1}1"
	fi
	if [ ! -d ${2}/boot ];then
		mkdir ${2}/boot
	fi;
	mount ${BOOT_P} ${2}/boot
}

mount_image() {
	if [ -e ${TMPDEV} ];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} ${TMPDEV}

	losetup -P ${LOOP} ${1}.img
	mount_image_blk ${LOOP} ${1}
	mount_sys ${1}
}

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

fsck_combo(){
	e2fsck -C 0 -fy ${1}p3
	e2fsck -C 0 -fy ${1}p2
}

fsck_ns() {
	fsck.fat -a ${1}p1
	e2fsck -C 0 -fy ${1}p2
}

fdisk_combo() {
	parted -a none -s ${1} \
		mklabel gpt \
		mkpart fip 1024s 9215s \
		mkpart boot ext4 9216s 140287s \
		mkpart rootfs ext4 140288s 100% \
		set 2 legacy_boot on
	sgdisk ${1} -u 3: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}
	fsck_combo ${LOOP}
	resize2fs ${LOOP}p3
	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_ns ${LOOP}
	resize2fs ${LOOP}p2
	losetup -d ${LOOP}
}

expand_image() {
	if [ -e ${TMPDEV} ];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}p3 ];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=0 seek=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_image_blk ${LOOP} ${MNTDIR}

	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
		if ! wget ${2} -O ${3}.${4};then
			rm ${3}.${4}
			return 1
		fi;
	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
		;;
		"stm32mp157f_ns_combo")
			bunzip2 -k ${3}.${4} || return 1
		;;
		"stm32mp157c_ns_combo")
			bunzip2 -k ${3}.${4} || return 1
		;;
	esac
}

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

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

	fdisk_combo ${LOOP}

	mkfs.ext4 ${LOOP}p2 -b 1024 -L boot
	mkfs.ext4 ${LOOP}p3 -L rootfs

	e2image -pra -o 4718592 ${1}.pack ${LOOP}p2
	e2image -pra -o 71827456 ${1}.pack ${LOOP}p3

	echo "Checking File System"
	fsck_combo ${LOOP}
	echo "Expanding File System"
	resize2fs ${LOOP}p2
	resize2fs ${LOOP}p3
	losetup -d ${LOOP}
}

unpack_ns_image_raspi() {
	dd status=progress if=/dev/zero of=${1} bs=1M count=0 seek=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_ns ${LOOP}
	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}p3 ];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() {
	for lcnt in 1 2 3;do
		fsck_combo ${2}
		resize2fs -p -M ${2}p2
		resize2fs -p -M ${2}p3
	done;

	if [ "${3}" == "1" ];then
		e2image -pra -O 71827456 ${2}p3 ${1}.pack
	else
		e2image -ra -O 71827456 ${2}p3 ${1}.pack
	fi
	fsck_combo ${2}
	resize2fs -p ${2}p2
	resize2fs -p ${2}p3
	losetup -d ${2}

	dd status=progress conv=nocreat,notrunc if=${1} bs=1K count=70143 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}
	fsck_combo ${LOOP}
	resize2fs -p ${LOOP}p2
	resize2fs -p ${LOOP}p3

	losetup -d ${LOOP}
}

pack_ns_image_raspi() {
	for lcnt in 1 2 3;do
		e2fsck -C 0 -fy ${2}p2
		resize2fs -p -M ${2}p2
	done

	if [ "${3}" == "1" ];then
		e2image -pra -O 99614720 ${2}p2 ${1}.pack
	else
		e2image -ra -O 99614720 ${2}p2 ${1}.pack
	fi
	fsck_ns ${2}
	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_ns ${LOOP}
	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}p3 ];then
		pack_ns_image_combo ${1} ${LOOP} ${2}
	else
		pack_ns_image_raspi ${1} ${LOOP} ${2}
	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
}

mount_ns_board() {
	if [ -e ${TMPDEV} ];then
		umount_image ${1}
		return 0
	fi;

	wpnetlink_stop

	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"
		wpnetlink_start
		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} ${TMPDEV}

	mount_image_blk ${FLASH} ${1}
	mount_sys ${1}
}

flash_ns_bootloader() {
	echo "Updating bootloader"

	if [ -d ${1}/recovery ];then
		rpiboot -d ${1}/recovery
	elif [ -d /usr/share/rpiboot/recovery ];then
		rpiboot -d /usr/share/rpiboot/recovery
	fi;

	echo "Repower board"
	sleep 5
}

flash_prep_pack() {
	#Prepare pack file to flash
	if [ ! -e ${1} ] && [ ! -e ${1}.pack ] && [ ! -e ${1}.pack.xz ] && [ -e ${1}.xz ];then
		xz -d -k ${1}.xz
		pack_ns_image ${1} ${2}
	elif [ -e ${1} ] && [ ! -e ${1}.pack ] && [ ! -e ${1}.pack.xz ];then
		pack_ns_image ${1} ${2}
	elif [ -e ${1} ] && [ -e ${1}.pack ] && [ ${1} -nt ${1}.pack ];then
		pack_ns_image ${1} ${2}
	elif [ ! -e ${1}.pack ] && [ -e ${1}.pack.xz ];then
		xz -d -k ${1}.pack.xz --verbose
#	elif [ -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 ] && [ ! -e ${1} ];then
		return 1
	fi;
}

ns_find_img() {
	if [ -e ${1}.pack ];then
		ns_img_to_flash ${1}.pack ${FLASH}
	elif [ -e ${1} ];then
		ns_img_to_flash ${1} ${FLASH}
	elif [ -e ${1}.pack.xz ];then
		xz -d -c ${1}.pack.xz |dd status=progress bs=1M of=${FLASH}
		sgdisk -e ${FLASH}
	elif [ -e ${1}.xz ];then
		xz -d -c ${1}.xz |dd status=progress bs=1M of=${FLASH}
		sgdisk -e ${FLASH}
	else
		return 1
	fi
}

flash_ns_board() {
	flash_ns_bootloader ${1}

	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

	if ! flash_prep_pack ${1}/${2}.img 0;then
		echo "No flash file found"
		return 1;
	fi;

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

	if ! ns_find_img ${1}/${2}.img;then
		echo "No flash file found"
		return 1;
	fi

	echo "Resize partition in MBR"
	parted ${FLASH} -s resizepart 2 100%
	echo "Checking File System"
	fsck_ns ${FLASH}
	echo "Expanding File System to fit flash"
	resize2fs ${FLASH}2
}

mount_image_chroot() {
	cp /etc/resolv.conf ${1}/run/resolvconf
	if [ ! -L ${1}/etc/resolv.conf ];then
		rm -f ${1}/etc/resolv.conf
		ln -s /etc/resolvconf/run/resolv.conf ${1}/etc/resolv.conf
	fi;

	echo "export PS1='(${DEF_IMG_NAME})\u@\h:\w\\$ ';cd ~;rm .profile" > ${1}/home/root/.profile
	echo "[ -x /usr/bin/ssh-agent ] && eval \`ssh-agent -k\`;dnf clean all;rm -f .profile .bash_logout .bash_history" > ${1}/home/root/.bash_logout

	env -i TERM=${TERM} HOME=/home/root LANG=${LANG} /usr/sbin/chroot ${1} /bin/bash -l
	for clean_root in .profile .bash_history .bash_logout;do
		if [ -e ${1}/home/root/${clean_root} ];then
			rm ${1}/home/root/${clean_root}
		fi;
	done;
}

mount_image_setup_pxe() {
	if [ ! -d /srv/tftpd ] && [ ! -d /srv/tftp ];then
		return 1;
	fi;

	if [ -d /srv/tftpd ];then
		TFTP_DIR=/srv/tftpd
	elif [ -d /srv/tftp ];then
		TFTP_DIR=/srv/tftp
	fi

	if [ ! -d ${TFTP_DIR}/pxelinux.cfg ];then
		mkdir ${TFTP_DIR}/pxelinux.cfg
	fi;

	SERV_IP=$(ip -4 -o -s route show default  |head -1 |awk '{printf "ip -4 -o -s addr show %s\n", $5}' |sh |awk '{printf "%s\n", substr($4,0,index($4,"/")-1)}' |head -1);

	SYS_CPU=$(echo ${2} |cut -d_ -f1)
	SYS_NAME=$(echo ${2} |tr '_' '-')

	FDT=${SYS_CPU}-comb_ns_combo-mx.dtb
	KERN=uImage-${SYS_NAME}.bin

	if [ -e ${1}/boot/uImage ];then
		cp ${1}/boot/uImage ${TFTP_DIR}/${KERN}
	fi;

	if [ -e ${1}/boot/${FDT} ];then
		cp ${1}/boot/${FDT} ${TFTP_DIR}/${FDT}
	fi

	(cat << __EOF__
menu title Select the boot mode
DEFAULT nfs
TIMEOUT 20
LABEL nfs
        KERNEL ${KERN}
        FDT ${FDT}
        APPEND root=/dev/nfs nfsroot=${SERV_IP}:${1},nfsvers=3,tcp earlyprintk security=smack cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory ip=dhcp,client-id-type,client-id-value console=ttySTM0,115200 init=/sbin/init.nfs
__EOF__
)> ${TFTP_DIR}/pxelinux.cfg/default-arm-stm32mp
}

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="172.20.60.27"
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
