#!/bin/sh
# +--------------------------------------------------------------------------+
# | upgrade_script_1.sh                                                        |
# +--------------------------------------------------------------------------+
# | This is the main script for upgrade some parts of the board:             |
# | - items into the DataFlash/NorFlash                                      |
# | - items into the filesystem                                              |
# +--------------------------------------------------------------------------+
#
# +--------------------------------------------------------------------------+
# | Configuration parameters                                                 |
# +--------------------------------------------------------------------------+
SCRIPT_VERSION=0.0.02
DEVICE=/dev/sda1
LOGFILE=upgrade_script.log
LISTFILE=upgrade_list.txt
UPGRADE_SCRIPT=upgrade_script.sh
P_500_UPGRADE_PATTERN=p_500_upgrade_
P_800_UPGRADE_PATTERN=p_800_upgrade_
P_ALL_UPGRADE_PATTERN=p_500_upgrade_
UPGRADE_PATTERN_500=p_500_upgrade
UPGRADE_PATTERN_800=p_800_upgrade
UPGRADE_PATTERN=p_500_upgrade
TARGET_MAIN_DATAFLASH=main
TARGET_GNSS=gnss
DATAFLASHDEV=/dev/mtd3
TOOLSDIR=/usr/local/bin
PM4LOADER=${TOOLSDIR}/pm4loader
PM4LOADER_NAME=pm4loader
GNSSDETECTOR==${TOOLSDIR}/GNSS_Detector
GNSSDETECTOR_NAME=GNSS_Detector
FLASHTOOL=${TOOLSDIR}/dataflash_tool
CRC32TOOL=${TOOLSDIR}/crc32
PRINTTOOL=${TOOLSDIR}/oled_print
DEV_BLOCK1=/dev/mtdblock1
DEV_CONFIG=/mnt/config
EXTRA_DIR=extra

# +--------------------------------------------------------------------------+
# | Functions                                                                |
# +--------------------------------------------------------------------------+

PATH=/usr/local/bin:${PATH}

TARTOOL=$(which tar) > /dev/null 2>&1

#
# Upgrade file must be in USB
#
MOUNTPOINT=/mnt/usbdisk

#
# Start script
#
echo "Starting USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE} 2>&1

#
# Remove the file containing the list of files found on the device
#
if [ -f ${MOUNTPOINT}/${LISTFILE} ];
then
  rm -f ${MOUNTPOINT}/${LISTFILE} > /dev/null 2>&1
fi

#
# List the upgrade files found on the device
#
ls -l ${MOUNTPOINT}/${P_500_UPGRADE_PATTERN}*.tar.bz2 >> /dev/null 2>&1
if [ ! $? -eq 0 ];
then
	ls -l ${MOUNTPOINT}/${P_800_UPGRADE_PATTERN}*.tar.bz2 >> /dev/null 2>&1
	if [ ! $? -eq 0 ];
	then
		echo "No upgrade file found" >> ${MOUNTPOINT}/${LOGFILE}
		echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
		echo "Exit code is 4" >> ${MOUNTPOINT}/${LOGFILE}
		exit 50
	else
		UPGRADE_PATTERN=${UPGRADE_PATTERN_800}
		P_ALL_UPGRADE_PATTERN=${P_800_UPGRADE_PATTERN}
	fi
else
	UPGRADE_PATTERN=${UPGRADE_PATTERN_500}
	P_ALL_UPGRADE_PATTERN=${P_500_UPGRADE_PATTERN}
fi

#
# List all file which match upgrade pattern.
# eg:	p_500_upgrade-main-0.0.1.tar.bz2
#	p_500_upgrade-rescue-0.0.1.tar.bz2
#	p_500_upgrade-gnss-0.4.9.tar.bz2
#	p_500_upgrade-pmu-2.18.0.tar.bz2

#
ls ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2 > ${MOUNTPOINT}/${LISTFILE}
#
# Check for the number of .tar.bz2 files found on the USB key.
# If there are no files, then upgrade procedure is aborted.
#
if [ $(cat ${MOUNTPOINT}/${LISTFILE} | wc -l) -eq 0 ];
then
	echo "No upgrade file found" >> ${MOUNTPOINT}/${LOGFILE}
	echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
	echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
	exit 50
fi

# +==========================================================================+
# +--------------------------------------------------------------------------+
# | UPGRADING DATA FLASH MEMORY   -  MAIN                                    |
# +--------------------------------------------------------------------------+
# +==========================================================================+
grep "${UPGRADE_PATTERN}-${TARGET_MAIN_DATAFLASH}" ${MOUNTPOINT}/${LISTFILE} > /dev/null 2>&1
if [ $? -eq 0 ];
then
	#
	# Look for flash memory upgrade file (outside any filesystem).
	#
	TARGET=$(ls -rt ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_MAIN_DATAFLASH}*.tar.bz2 | tail -1 | awk -F- '{print $2}')
	VERSION=$(ls -rt ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_MAIN_DATAFLASH}*.tar.bz2 | tail -1 | awk -F- '{print $3}' | sed -e 's/\.tar.bz2$//g')
	
	if [ -z "${TARGET}" -o -z "${VERSION}" ]
	then
		echo "No valid upgrade file found for flash memory upgrade" >> ${MOUNTPOINT}/${LOGFILE}
	else
		echo "Valid upgrade file found. Processing..." >> ${MOUNTPOINT}/${LOGFILE} 
		echo "Target is '${TARGET}', version is '${VERSION}'" >> ${MOUNTPOINT}/${LOGFILE}
		echo "Processing file ${UPGRADE_PATTERN}-${TARGET_MAIN_DATAFLASH}-${VERSION}.tar.bz2" >> ${MOUNTPOINT}/${LOGFILE}
	
		TEMP_DIR=tmp_df_$$
		if [ -d ${MOUNTPOINT}/${TEMP_DIR} ];
		then
			rm -f ${MOUNTPOINT}/${TEMP_DIR}
		fi
		mkdir ${MOUNTPOINT}/${TEMP_DIR}
	
		echo "Uncompressing archive file '${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_MAIN_DATAFLASH}-${VERSION}.tar.bz2 '" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
		${TARTOOL} xjf ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_MAIN_DATAFLASH}-${VERSION}.tar.bz2 -C ${MOUNTPOINT}/${TEMP_DIR} >> ${MOUNTPOINT}/${LOGFILE} 2>&1
		
		if [ ! $? -eq 0 ];
		then
			#
			# Remove extracted files
			#
			rm -rf ${MOUNTPOINT}/${TEMP_DIR}
			rm -f ${MOUNTPOINT}/${LISTFILE}
			rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
			#
            echo "Error to extract archive !!!" >> ${MOUNTPOINT}/${LOGFILE}
			echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
			echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
			exit 5
		fi
	
		# Check for the 'mapping.txt' file.
		if [ ! -f ${MOUNTPOINT}/${TEMP_DIR}/mapping.txt ];
		then
			echo "Mapping file not found !" >> ${MOUNTPOINT}/${LOGFILE}
		else
			LIST_FILES=${MOUNTPOINT}/${TEMP_DIR}/list_files_$$
			ls ${MOUNTPOINT}/${TEMP_DIR} > ${LIST_FILES} 
			for file in $(cat ${LIST_FILES});
			do
				if [ ! "${file}" = "mapping.txt" ];
				then
					# Write the file into the flash memory, depending on the mapping.
					ADDRESS=$(grep "${file}" ${MOUNTPOINT}/${TEMP_DIR}/mapping.txt | awk '{print $2}')
					if [ ! -z "${file}" -a ! -z "${ADDRESS}" ];
					then
						echo "Processing file ${file}..."
						echo "File: ${file}, Address: ${ADDRESS}" >> ${MOUNTPOINT}/${LOGFILE}
						echo "Programming file '${file}' at address ${ADDRESS}" >> ${MOUNTPOINT}/${LOGFILE}
						if [ -f ${PRINTTOOL} ];
						then
							${PRINTTOOL} --x 40 --y 20 --text "Writing" --clear
							${PRINTTOOL} --x 5 --y 42 --text "${file}"
						fi
						echo "${FLASHTOOL} -d ${DATAFLASHDEV} -a ${ADDRESS} -i ${MOUNTPOINT}/${TEMP_DIR}/${file}" >> ${MOUNTPOINT}/${LOGFILE}
						${FLASHTOOL} --progress -d ${DATAFLASHDEV} -a ${ADDRESS} -i ${MOUNTPOINT}/${TEMP_DIR}/${file} >> ${MOUNTPOINT}/${LOGFILE} 2>&1
					fi
				fi
				#
				# Special operation must be done for some files. A CRC32 must
				# be computed and written at the beginning of the environments area.
				#
				CHECK_CRC=$(grep "${file}" ${MOUNTPOINT}/${TEMP_DIR}/mapping.txt | awk '{print $4}')
				if [ "${CHECK_CRC}" = "crc" ];
				then
					# Compute the CRC32...
					MY_CRC32=$(${CRC32TOOL} --offset=4 --infile=${MOUNTPOINT}/${TEMP_DIR}/${file})
					if [ -z "${MY_CRC32}" ];
					then
						echo "CRC32 calculation error !" >> ${MOUNTPOINT}/${LOGFILE}
						echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
						echo "Exit code is 6" >> ${MOUNTPOINT}/${LOGFILE}
						rm -rf ${MOUNTPOINT}/${TEMP_DIR}
						rm -f ${MOUNTPOINT}/${LISTFILE}
						rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
		
						if [ -f ${PRINTTOOL} ];
						then
							${PRINTTOOL} --x 30 --y 32 --text "CRC error" --clear
						fi				
						exit 6
					fi
					# Write the CRC32 at the beginning of the environment area.
					CRC32ADDRESS=$(grep ${file} ${MOUNTPOINT}/${TEMP_DIR}/mapping.txt | awk '{print $2}')
					echo "${FLASHTOOL} -d ${DATAFLASHDEV} -a ${CRC32ADDRESS} --data=${MY_CRC32}" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
					${FLASHTOOL} -d ${DATAFLASHDEV} -a ${CRC32ADDRESS} --data=${MY_CRC32} >> ${MOUNTPOINT}/${LOGFILE} 2>&1
				fi
			done

		fi

		
		# Check for the extra files
		if [ ! -d ${MOUNTPOINT}/${TEMP_DIR}/${EXTRA_DIR} ];
		then
			echo "Extra directory not found !" >> ${MOUNTPOINT}/${LOGFILE}
		else
			if [ -f ${PRINTTOOL} ];
			then
				${PRINTTOOL} --x 40 --y 20 --text "Writing" --clear
				${PRINTTOOL} --x 20 --y 42 --text "Extra Datas"
			fi

			mount | grep "${DEV_CONFIG}" > /dev/null 2>&1
			if [ $? -eq 1 ];
			then
				mount -t jffs2 ${DEV_BLOCK1} ${DEV_CONFIG}
			fi

			rm -R -f ${DEV_CONFIG}/WebLanguages
			rm -R -f ${DEV_CONFIG}/www/*
			rm -R -f ${DEV_CONFIG}/ntripcaster/bin/*
			rm -R -f ${DEV_CONFIG}/6*
			rm -R -f ${DEV_CONFIG}/7*
			rm -R -f ${DEV_CONFIG}/rinex*
			chmod 777 ${MOUNTPOINT}/${TEMP_DIR}/${EXTRA_DIR}/*
			cp -R -f ${MOUNTPOINT}/${TEMP_DIR}/${EXTRA_DIR}/* ${DEV_CONFIG}
		fi
		
		
		rm -rf ${MOUNTPOINT}/${TEMP_DIR}/${EXTRA_DIR}
		rm -rf ${MOUNTPOINT}/${TEMP_DIR}
		rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_MAIN_DATAFLASH}-${VERSION}.tar.bz2 
		${FLASHTOOL} --add=0x3927D --size=1 --data=FF
	fi
fi

# +==========================================================================+
# +--------------------------------------------------------------------------+
# | UPGRADING GNSS BOARD                                                     |
# +--------------------------------------------------------------------------+
# +==========================================================================+
grep "${UPGRADE_PATTERN}-${TARGET_GNSS}" ${MOUNTPOINT}/${LISTFILE} > /dev/null 2>&1
if [ $? -eq 0 ];
then
	TARGET=$(ls -rt ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_GNSS}*.tar.bz2 | tail -1 | awk -F- '{print $2}')
	VERSION=$(ls -rt ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_GNSS}*.tar.bz2 | tail -1 | awk -F- '{print $3}' | sed -e 's/\.tar.bz2$//g')
	if [ -z "${TARGET}" -o -z "${VERSION}" ]
	then
		echo "No valid upgrade file found for GNSS board upgrade" >> ${MOUNTPOINT}/${LOGFILE}
	else
		#
		# Creation of a temporary directory.
		#
		TEMP_DIR=tmp_gnss_$$
		EXTRACT=/usr/local/bin
		if [ -d ${EXTRACT}/${TEMP_DIR} ];
		then
			rm -f ${EXTRACT}/${TEMP_DIR}
		fi
		mkdir ${EXTRACT}/${TEMP_DIR}
		#
		# Uncompressing archive file p_500_upgrade-gnss-x.y.z.tar.bz2
		#
		echo "Uncompressing archive file '${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_GNSS}-${VERSION}.tar.bz2 '" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
		${TARTOOL} xjf ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_GNSS}-${VERSION}.tar.bz2 -C ${EXTRACT}/${TEMP_DIR} >> ${MOUNTPOINT}/${LOGFILE} 2>&1
		
		if [ ! $? -eq 0 ];
		then
			echo "Error to extract archive !!!" >> ${MOUNTPOINT}/${LOGFILE}
			#
			# Remove extracted files.
			#
			rm -rf ${EXTRACT}/${TEMP_DIR}
			rm -f ${MOUNTPOINT}/${LISTFILE}
			rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
			#
			echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
			echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
			exit 5
		fi
		
		#
		# Detect GNSS Board
		#
		if [ -f ${EXTRACT}/${TEMP_DIR}/${GNSSDETECTOR_NAME} ];
		then
			echo "Find tool 'GNSS Detector on /usr/local/bin'" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
			chmod 777 ${EXTRACT}/${TEMP_DIR}/${GNSSDETECTOR_NAME}
			GNSSDETECTOR=${EXTRACT}/${TEMP_DIR}/${GNSSDETECTOR_NAME}
		
			/usr/local/bin/oled_print --x 35 --y 20 --text "Detecting" --clear
			/usr/local/bin/oled_print --x 45 --y 40 --text "GNSS"
			#
			# Checking PM500 or PF500
			#
			if [ -f /etc/PM_PF_Detector ];
			then
				/etc/PM_PF_Detector
				PRODUCT=$?
			else
				PRODUCT=0
			fi
			
			if [ ! ${PRODUCT} == 0 ];
			then
				cd ${EXTRACT}/${TEMP_DIR} && ${GNSSDETECTOR} -p pf -i ${EXTRACT}/${TEMP_DIR} >> ${MOUNTPOINT}/${LOGFILE} 2>&1
			else
				cd ${EXTRACT}/${TEMP_DIR} && ${GNSSDETECTOR} -p pm -i ${EXTRACT}/${TEMP_DIR} >> ${MOUNTPOINT}/${LOGFILE} 2>&1
			fi
			
		else
			echo "Unable to find tool 'GNSS Detector'. Exiting" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
			#
			# Remove extracted files.
			#
			rm -rf ${EXTRACT}/${TEMP_DIR}
			rm -f ${MOUNTPOINT}/${LISTFILE}
			rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
			#
			echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
			echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
			exit 5
		fi

		#
		# GNSS upgrade, only if filesystem upgrade.
		#
		GNSS_UPGRADE_FILE=${EXTRACT}/${TEMP_DIR}/gnss_fw.bin
		CGNSS_NEW_TOOL_DIR=${TOOLSDIR}
		if [ -f ${GNSS_UPGRADE_FILE} ];
		then
			if [ -f ${EXTRACT}/${TEMP_DIR}/${PM4LOADER_NAME} ];
			then
			echo "Find tool 'pm4loader on /usr/local/bin'" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
			chmod 777 ${EXTRACT}/${TEMP_DIR}/${PM4LOADER_NAME}
			PM4LOADER=${EXTRACT}/${TEMP_DIR}/${PM4LOADER_NAME}
			CGNSS_NEW_TOOL_DIR=${EXTRACT}/${TEMP_DIR}
			fi

			if [ -f ${PM4LOADER} ];
			then
				/usr/local/bin/oled_print --x 35 --y 20 --text "Upgrading" --clear
				/usr/local/bin/oled_print --x 45 --y 40 --text "GNSS"
				cd ${CGNSS_NEW_TOOL_DIR} && ${PM4LOADER} -v >> ${MOUNTPOINT}/${LOGFILE} 2>&1
				echo "Upgrading GNSS" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
				cd ${CGNSS_NEW_TOOL_DIR} && ${PM4LOADER} -f ${GNSS_UPGRADE_FILE} -p /dev/ttyS2 >> ${EXTRACT}/${TEMP_DIR}/gnss.log 2>&1
				if [ ! $? -eq 0 ];
				then
					echo "Error to upgrade GNSS !!!" >> ${MOUNTPOINT}/${LOGFILE}
					#
					# Remove extracted files.
					#
					cat ${EXTRACT}/${TEMP_DIR}/gnss.log >> ${MOUNTPOINT}/${LOGFILE}

					rm -rf ${EXTRACT}/${TEMP_DIR}
					rm -f ${MOUNTPOINT}/${LISTFILE}
					rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
					#
					echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
					echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
					exit 5
				fi
				${FLASHTOOL} -d ${DATAFLASHDEV} -a 0x3927E --data=FF
			else
				echo "Unable to find tool 'pm4loader'. Exiting" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
				#
				# Remove extracted files.
				#
				rm -rf ${EXTRACT}/${TEMP_DIR}
				rm -f ${MOUNTPOINT}/${LISTFILE}
				rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
				#
				echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
				echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
				exit 5
			fi
		fi
		
		#
		# Head GNSS upgrade, only if filesystem upgrade.
		#
		GNSS_UPGRADE_FILE=${EXTRACT}/${TEMP_DIR}/head_gnss_fw.bin
		CGNSS_NEW_TOOL_DIR=${TOOLSDIR}
		if [ -f ${GNSS_UPGRADE_FILE} ];
		then
			if [ -f ${EXTRACT}/${TEMP_DIR}/${PM4LOADER_NAME} ];
			then
			echo "Find tool 'pm4loader on /usr/local/bin'" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
			chmod 777 ${EXTRACT}/${TEMP_DIR}/${PM4LOADER_NAME}
			PM4LOADER=${EXTRACT}/${TEMP_DIR}/${PM4LOADER_NAME}
			CGNSS_NEW_TOOL_DIR=${EXTRACT}/${TEMP_DIR}
			fi

			if [ -f ${PM4LOADER} ];
			then
				/usr/local/bin/oled_print --x 35 --y 20 --text "Upgrading" --clear
				/usr/local/bin/oled_print --x 35 --y 40 --text "Head GNSS"
				cd ${CGNSS_NEW_TOOL_DIR} && ${PM4LOADER} -v >> ${MOUNTPOINT}/${LOGFILE} 2>&1
				echo "Upgrading GNSS Heading" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
				cd ${CGNSS_NEW_TOOL_DIR} && ${PM4LOADER} -f ${GNSS_UPGRADE_FILE} -p /dev/ttyUSB3 >> ${EXTRACT}/${TEMP_DIR}/gnss.log 2>&1
				if [ ! $? -eq 0 ];
				then
					echo "Error to upgrade Head GNSS !!!" >> ${MOUNTPOINT}/${LOGFILE}
					#
					# Remove extracted files.
					#
					cat ${EXTRACT}/${TEMP_DIR}/gnss.log >> ${MOUNTPOINT}/${LOGFILE}

					rm -rf ${EXTRACT}/${TEMP_DIR}
					rm -f ${MOUNTPOINT}/${LISTFILE}
					rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
					#
					echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
					echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
					exit 5
				fi
				${FLASHTOOL} -d ${DATAFLASHDEV} -a 0x3927E --data=FF
			else
				echo "Unable to find tool 'pm4loader'. Exiting" >> ${MOUNTPOINT}/${LOGFILE} 2>&1
				#
				# Remove extracted files.
				#
				rm -rf ${EXTRACT}/${TEMP_DIR}
				rm -f ${MOUNTPOINT}/${LISTFILE}
				rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-*.tar.bz2
				#
				echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
				echo "Exit code is 5" >> ${MOUNTPOINT}/${LOGFILE}
				exit 5
			fi
		fi
		#
		# Removing temporary directory.
		#
		rm -rf ${EXTRACT}/${TEMP_DIR}
		rm -f ${MOUNTPOINT}/${UPGRADE_PATTERN}-${TARGET_GNSS}-${VERSION}.tar.bz2 
	fi
fi

#
# Remove temporary resource
#
rm -f ${MOUNTPOINT}/${LISTFILE}

${PRINTTOOL} --x=20 --y=32 --text="Upgrade done" --clear

echo "Ending USB script at " $(date) >> ${MOUNTPOINT}/${LOGFILE}
echo "Exit code is 0" >> ${MOUNTPOINT}/${LOGFILE}

# 
# Terminate the script with success return code.
#
exit 0
# +--------------------------------------------------------------------------+
# | End of script.                                                           |
# +--------------------------------------------------------------------------+

