diff --git a/mbtk/mbtk_otad/inc/tim.c b/mbtk/mbtk_otad/inc/tim.c
new file mode 100755
index 0000000..b7c2ae5
--- /dev/null
+++ b/mbtk/mbtk_otad/inc/tim.c
@@ -0,0 +1,471 @@
+#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;
+}
+
