#include "tim.h"

#define DTIM_MAX_SIZE	(128 * 1024)

#if 0

static const char *id2str(unsigned int id)
{
 	switch (id) {
	case IMAGE_ID_ARBEL:
		return "ARBEL";
	case IMAGE_ID_DTIM_A:
		return "DTIM_A";
	case IMAGE_ID_DTIM_B:
		return "DTIM_B";
	case IMAGE_ID_KERNEL:
		return "KERNEL";
	case IMAGE_ID_MSA:
		return "MSA";
	case IMAGE_ID_OEMD:
		return "OEMD";
	case IMAGE_ID_RF:
		return "RF";
	case IMAGE_ID_ROOTFS:
		return "ROOTFS";
	case IMAGE_ID_UBOOT:
		return "UBOOT";
	default:
		OTA_ERR("Unkown id: 0x%x\n", id);
		return "NULL";
	}
}
#endif

static int SetTIMPointers( void *pStartAddr, TIM *pTIM_h)
{
	pTIM_h->pConsTIM = (pCTIM) pStartAddr;	// Overlap Contant Part of TIM with actual TIM...

	if ((pTIM_h->pConsTIM->VersionBind.Identifier != TIMIDENTIFIER) ||
	    (pTIM_h->pConsTIM->VersionBind.Version < TIM_3_2_00)) {
		/* incorrect tim */
		pTIM_h->pConsTIM = NULL;
		return -1;
	}

	// Assign a pointer to start of Images Area
	pTIM_h->pImg = (pIMAGE_INFO_3_4_0) (pStartAddr + sizeof (CTIM));

	// Assign a pointer to start of Key Area
	if (pTIM_h->pConsTIM->VersionBind.Version >= TIM_3_4_00)
		pTIM_h->pKey = (pKEY_MOD_3_4_0) ((UINT_T)pTIM_h->pImg + ((pTIM_h->pConsTIM->NumImages) * sizeof (IMAGE_INFO_3_4_0)));
	else
		pTIM_h->pKey = (pKEY_MOD_3_4_0) ((UINT_T)pTIM_h->pImg + ((pTIM_h->pConsTIM->NumImages) * sizeof (IMAGE_INFO_3_2_0)));

	// Assign a pointer to start of reserved area
	if (pTIM_h->pConsTIM->VersionBind.Version >= TIM_3_4_00)
		pTIM_h->pReserved = (PUINT) ((UINT_T)pTIM_h->pKey + ((pTIM_h->pConsTIM->NumKeys) * sizeof (KEY_MOD_3_4_0)));
	else if (pTIM_h->pConsTIM->VersionBind.Version >= TIM_3_3_00)
		pTIM_h->pReserved = (PUINT) ((UINT_T)pTIM_h->pKey + ((pTIM_h->pConsTIM->NumKeys) * sizeof (KEY_MOD_3_3_0)));
	else
		pTIM_h->pReserved = (PUINT) ((UINT_T)pTIM_h->pKey + ((pTIM_h->pConsTIM->NumKeys) * sizeof (KEY_MOD_3_2_0)));

	// Assign a pointer to start of DS
	pTIM_h->pTBTIM_DS = (pPLAT_DS) ((UINT_T)pTIM_h->pReserved + pTIM_h->pConsTIM->SizeOfReserved);
	return (NoError);
}

#if 0
static void dump_dtim(pTIM t)
{
	int i;
	pIMAGE_INFO_3_4_0 pImg;
	OTA_DEBUG("### Image in dtim ###\n");
	OTA_DEBUG("Images number: %d\n", t->pConsTIM->NumImages);
	for (i = 0; i < t->pConsTIM->NumImages; i++) {
		pImg = (pIMAGE_INFO_3_4_0)(t->pImg + i);
		OTA_DEBUG("[%d] ID: %s, NextID: %s, Offset: 0x%x, "
			"LoadAddr: 0x%x, Size: %d, SizeToHash: %d, HashAlgorithmID: 0x%x\n", i,
			id2str(pImg->ImageID), id2str(pImg->NextImageID), pImg->FlashEntryAddr,
			pImg->LoadAddr, pImg->ImageSize, pImg->ImageSizeToHash,
			pImg->HashAlgorithmID);
		OTA_DEBUG("[%d] Hash: 0x%x, 0x%x, 0x%x, 0x%x, "
							 "0x%x, 0x%x, 0x%x, 0x%x, "
							 "0x%x, 0x%x, 0x%x, 0x%x, "
							 "0x%x, 0x%x, 0x%x, 0x%x\n", i,
			pImg->Hash[0], pImg->Hash[1], pImg->Hash[2], pImg->Hash[3],
			pImg->Hash[4], pImg->Hash[5], pImg->Hash[6], pImg->Hash[7],
			pImg->Hash[8], pImg->Hash[9], pImg->Hash[10], pImg->Hash[11],
			pImg->Hash[12], pImg->Hash[13], pImg->Hash[14], pImg->Hash[15]);
	}
}

static void *load_dtim(const char *dev)
{
	int fd = -1;

	char _dev[32] = {0};
	char *buf = malloc(DTIM_MAX_SIZE);
	if (!buf) {
		OTA_ERR("failed to malloc 0x%x for dtim.\n", DTIM_MAX_SIZE);
		goto out;
	}

	sprintf(_dev, "/dev/%s", dev);
	fd = open(_dev, O_RDWR | O_SYNC);
	if (fd < 0) {
		OTA_ERR("failed to open %s.\n", _dev);
		free(buf);
		buf = NULL;
		goto out;
	}

	if (complete_read(fd, buf, DTIM_MAX_SIZE) < 0) {
		OTA_ERR("failed to load %s.\n", _dev);
		free(buf);
		buf = NULL;
		goto out;
	}

out:
	if (fd >= 0)
		close(fd);
	return buf;
}

static int __save_dtim(int fd, pTIM pTIM_h)
{
	int r = -1;
	struct erase_info_user mtdEraseInfo;
	struct mtd_info_user mtdInfo;

	if (ioctl(fd, MEMGETINFO, &mtdInfo)) {
		OTA_ERR("could not get MTD device info.\n");
		goto out;
	}
	mtdEraseInfo.start = 0;
	mtdEraseInfo.length = mtdInfo.erasesize;

	ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
	ioctl(fd, MEMERASE, &mtdEraseInfo);

	if (complete_write(fd, (char *)pTIM_h->pConsTIM, DTIM_MAX_SIZE) < 0)
		goto out;

	r = 0;
out:
	return r;
}

static int save_dtim(const char *dev, pTIM pTIM_h)
{
	int fd = -1;
	int r = -1;
	char _dev[32] = {0};
	sprintf(_dev, "/dev/%s", dev);
	fd = open(_dev, O_RDWR | O_SYNC);
	if (fd < 0) {
		OTA_ERR("failed to open %s.\n", _dev);
		goto out;
	}

	r = __save_dtim(fd, pTIM_h);
	if (r)
		OTA_ERR("failed to save dtim to %s.\n", _dev);
out:
	if (fd >= 0)
		close(fd);
	return r;
}

/* sync the new to old */
static int __sync_dtim(pTIM pNew, pTIM pOld)
{
	int r = -1, i, j, found = 0, images;
	int flag = 0;
	pIMAGE_INFO_3_4_0 pImgSrc, pImgDst;

	OTA_DEBUG("%s: new dtim mode: %d, old dtim mode: %d.\n", __func__,
		pNew->pConsTIM->VersionBind.Trusted, pOld->pConsTIM->VersionBind.Trusted);
	if (pNew->pConsTIM->VersionBind.Trusted != pOld->pConsTIM->VersionBind.Trusted) {
		OTA_ERR("%s: Fatal Error. Can't sync two different trust mode dtim.\n", __func__);
		return -1;
	}

	for (i = 0; i < pNew->pConsTIM->NumImages; i++) {
		pImgSrc = (pIMAGE_INFO_3_4_0)(pNew->pImg + i);
		for (j = 0; j < pOld->pConsTIM->NumImages; j++) {
			pImgDst = (pIMAGE_INFO_3_4_0)(pOld->pImg + j);
			if (pImgSrc->ImageID == pImgDst->ImageID &&
				pImgSrc->ImageID != IMAGE_ID_DTIM_A &&
				pImgSrc->ImageID != IMAGE_ID_DTIM_B) {
				found++;
				if (pImgSrc->ImageSize != pImgDst->ImageSize ||
					pImgSrc->ImageSizeToHash != pImgDst->ImageSizeToHash ||
					pImgSrc->LoadAddr != pImgDst->LoadAddr ||
					pImgSrc->HashAlgorithmID != pImgDst->HashAlgorithmID ||
					memcmp(pImgSrc->Hash, pImgDst->Hash, sizeof(pImgSrc->Hash)) != 0)
				{
					OTA_DEBUG("Image: %s has been changed.\n", id2str(pImgSrc->ImageID));
					pImgDst->ImageID = pImgSrc->ImageID;
					pImgDst->ImageSize = pImgSrc->ImageSize;
					pImgDst->ImageSizeToHash = pImgSrc->ImageSizeToHash;
					pImgDst->LoadAddr = pImgSrc->LoadAddr;
					pImgDst->HashAlgorithmID = pImgSrc->HashAlgorithmID;
					memcpy(pImgDst->Hash, pImgSrc->Hash, sizeof(pImgSrc->Hash));
					flag = 1;
					break;
				}
			}
		}
	}

	images = pNew->pConsTIM->NumImages - 1;
	/* omit the first image(dtim it self) */
	if (found != images) {
		OTA_ERR("FATAL ERROR: NumImage: %d, found: %d, not exactly match.\n"
				, pNew->pConsTIM->NumImages, found);
		goto out;
	}

	r = flag;
out:
	return r;
}

static int update_dtim(const char *dev, void *bufNew)
{
	int r = -1;
	TIM tNew, tOld;
	char *buf = load_dtim(dev);

	if (!buf) {
		OTA_ERR("%s: failed to load dtim for %s.\n", __func__, dev);
		goto out;
	}

	SetTIMPointers(buf, &tOld);
	SetTIMPointers(bufNew, &tNew);

	OTA_DEBUG("### Dump orignal dtim of %s. ###\n", dev);
	dump_dtim(&tOld);
	OTA_DEBUG("### Dump the new dtim. ###\n");
	dump_dtim(&tNew);

	r = __sync_dtim(&tNew, &tOld);
	if (r < 0)
		goto out;
	if (r > 0) {
		OTA_DEBUG("Images have been changed, update %s\n", dev);
		r = save_dtim(dev, &tOld);
	} else {
		OTA_DEBUG("Images have NO change, DO NOT need to sync.\n");
		r = 0;
	}

	OTA_DEBUG("%s: %s.\n", __func__, (r >= 0) ? "OK" : "FAILED");
out:
	if (buf)
		free(buf);
	return r;
}

static int sync_dtim(const char *src, const char *dst)
{
	int r = -1;//, i, j, found = 0;
//	int flag = 0;
//	pIMAGE_INFO_3_4_0 pImgSrc, pImgDst;
	TIM tSrc;
	TIM tDst;
	char *bufSrc = load_dtim(src);
	char *bufDst = load_dtim(dst);

	OTA_DEBUG("Start to sync %s to %s.\n", src, dst);
	if (!bufSrc || !bufDst) {
		OTA_ERR("failed to sync %s to %s.\n", src, dst);
		goto out;
	}

	SetTIMPointers(bufSrc, &tSrc);
	SetTIMPointers(bufDst, &tDst);

	OTA_DEBUG("Dump dtim info of %s.\n", src);
	dump_dtim(&tSrc);
	OTA_DEBUG("Dump dtim info of %s.\n", dst);
	dump_dtim(&tDst);

	if (tSrc.pConsTIM->NumImages != tDst.pConsTIM->NumImages) {
		OTA_ERR("FATAL ERROR: NumImages(%s): %d, NumImages(%s): %d.\n",
			src, tSrc.pConsTIM->NumImages, dst, tDst.pConsTIM->NumImages);
		goto out;
	}

	r = __sync_dtim(&tSrc, &tDst);
	if (r < 0)
		goto out;
	if (r > 0) {
		OTA_DEBUG("Images have been changed, need to sync %s to %s.\n", src, dst);
		r = save_dtim(dst, &tDst);
	} else {
		OTA_DEBUG("Images have NO change, DO NOT need to sync.\n");
		r = 0;
	}
out:
	if (bufSrc)
		free(bufSrc);
	if (bufDst)
		free(bufDst);
	return r;
}

/* dev is the mtd device of dtim */
static int get_image_mode(const char *dev)
{
	char *buf = load_dtim(dev);
	TIM tim;
	int mode;

	if (!buf) {
		OTA_ERR("%s: failed to load dtim for %s.\n", __func__, dev);
		return -1;
	}

	SetTIMPointers(buf, &tim);
	mode = tim.pConsTIM->VersionBind.Trusted;
	OTA_DEBUG("%s: it is %s mode(%s).\n", __func__, (mode == 1) ? "Trusted" : "NON-Trusted", dev);
	free(buf);
	return mode;
}
#endif

static UINT_T CheckReserved (pTIM pTIM_h)
{
	pWTP_RESERVED_AREA pWRA	= (pWTP_RESERVED_AREA) pTIM_h->pReserved;

	// Make sure that the TIM has a credible size
	if(pTIM_h->pConsTIM->SizeOfReserved == 0)
		return NotFoundError;

	// Older TIM's had old reserved fields definition
	if (pTIM_h->pConsTIM->VersionBind.Version == (0x00030101))
		return NotFoundError;

	// Was this area in reserved field created by a WTP compliant tool so we can parse?
	if (pWRA->WTPTP_Reserved_Area_ID != WTPRESERVEDAREAID)
		return NotFoundError;

	return NoError;
}

// Finds a Package of WTP recognized information in the reserved area based on identifier
static pWTP_RESERVED_AREA_HEADER FindPackageInReserved (UINT_T * Retval, pTIM pTIM_h, UINT_T Identifier)
{
	UINT_T Count = 0;
	pWTP_RESERVED_AREA_HEADER pWRAH = NULL;
	pWTP_RESERVED_AREA pWRA	= (pWTP_RESERVED_AREA) pTIM_h->pReserved;

	*Retval = CheckReserved(pTIM_h);
	if (*Retval != NoError)
		return NULL;

	// Start from the begining
	pWRAH = (pWTP_RESERVED_AREA_HEADER) (pWRA + 1);

	while ((pWRAH->Identifier != Identifier) && (pWRAH->Identifier != TERMINATORID) && (Count < pWRA->NumReservedPackages))
	{
		pWRAH = (pWTP_RESERVED_AREA_HEADER)((UINT_T)pWRAH + ((pWRAH->Size + 3) & ~3)); // Skip to the next one
		Count++;
	}
	if (pWRAH->Identifier != Identifier)
	{
		*Retval = NotFoundError;
		pWRAH = NULL;
	}

	return pWRAH;
}

// This function has been added to support to isolate backwards compatibility to tim.c
// It will return a point to pIMAGE_INFO based on TIM version.
static pIMAGE_INFO_3_4_0 ReturnPImgPtr(pTIM pTIM_h, UINT_T ImageNumber)
{
	pIMAGE_INFO_3_4_0 pIMG;
	pIMG = (pIMAGE_INFO_3_4_0) &pTIM_h->pImg[ImageNumber];
	return pIMG;
}

// This function is used to find an image information field in the TIM
// of the image with the ID passed in

static pIMAGE_INFO_3_4_0 FindImageInTIM(pTIM pTIM_h, UINT_T ImageID)
{
	pIMAGE_INFO_3_4_0 pImageInfo = NULL;
	UINT8_T i;

	if (pTIM_h)
	{
		for( i = 0; i < pTIM_h->pConsTIM->NumImages; i++)
		{
			pImageInfo = ReturnPImgPtr(pTIM_h, i);
			if(pImageInfo->ImageID == ImageID)
				return pImageInfo;
		}
	}
	return NULL;
}

static int __retrive_timh_by_ddrid(pTIM pTIM_h, unsigned int *DDR_ID, int *imagesize)
{
	int i, DDRTimIndex = -1;
	UINT_T /*LoadAddr, TimSize, */TimLoadAddr, Retval;
	pIMAGE_INFO_3_4_0 pTimInfo = NULL;
	pWTP_RESERVED_AREA_HEADER pWRAH = NULL;
	pDDR_FLASH_MCP_PACKAGE pMCP = NULL;
#if 0
	if (DDR_ID == 0xFFFFFFFF || DDR_ID == 0) {
		OTA_ERR("Warning: no valid DDR ID in ASR Flag\n");
		return NoError;
	}
#endif
	TimLoadAddr = (UINT_T)pTIM_h->pConsTIM;

	pWRAH = FindPackageInReserved(&Retval, pTIM_h, DDR_FLASH_MCP_PACKAGE_ID);
	if(pWRAH == NULL) {
		OTA_ERR("No DFMP found, single DDR TIM\n\r");
		return NoError;
	} else {
		pMCP = (DDR_FLASH_MCP_PACKAGE *) pWRAH;
		for (i = 0; i < pMCP->NumberVendorDdrFlashSpec; i++) {
			if(pMCP->ddrFlashSpec[i].VendorDdrPid == *DDR_ID) {
				DDRTimIndex = i;
				OTA_DEBUG("%s: [%d] got ddr id: 0x%x\n", __func__, i, *DDR_ID);
				break;
			}
		}

		pTimInfo = FindImageInTIM(pTIM_h, IMAGE_ID_TIMH);
		if(pTimInfo == NULL) {
			OTA_ERR("%s %d: No TIMH found, error\n", __func__, __LINE__);
			return TIMNotFound;
		}

		if (DDRTimIndex < 0) {
			OTA_ERR("NOT found ddr id: 0x%x, use the first TIM ddrid: 0x%x",
				*DDR_ID, pMCP->ddrFlashSpec[0].VendorDdrPid);
			*DDR_ID = pMCP->ddrFlashSpec[0].VendorDdrPid;
			goto out;
		}

		/* go through all the TIMs to the right one */
		for (i = 0; i < (DDRTimIndex + 1); i++) {
			Retval = SetTIMPointers((void *)TimLoadAddr, pTIM_h);
			if(Retval) {
				OTA_ERR("%s %d: failed\n", __func__, __LINE__);
				return TIMNotFound;
			}

			pTimInfo = FindImageInTIM(pTIM_h, IMAGE_ID_TIMH);
			if(pTimInfo == NULL) {
				OTA_ERR("%s %d: No TIMH found, error\n", __func__, __LINE__);
				return TIMNotFound;
			}
			TimLoadAddr += pTimInfo->ImageSize;
		}
	}

out:
	*imagesize = pTimInfo->ImageSize;
	OTA_DEBUG("%s: index: %d, size: 0x%x\n", __func__, DDRTimIndex, pTimInfo->ImageSize);
	return NoError;
}
