xref: /rkdeveloptool/main.cpp (revision d71e8c2048c55061f9aed2f50d01382cce3a1c63)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi 
876af099aSliuyi #include   <unistd.h>
976af099aSliuyi #include   <dirent.h>
10c30d921cSKever Yang #include "config.h"
1176af099aSliuyi #include "DefineHeader.h"
12c30d921cSKever Yang #include "gpt.h"
1376af099aSliuyi #include "RKLog.h"
1476af099aSliuyi #include "RKScan.h"
1576af099aSliuyi #include "RKComm.h"
1676af099aSliuyi #include "RKDevice.h"
1776af099aSliuyi #include "RKImage.h"
1876af099aSliuyi extern const char *szManufName[];
1976af099aSliuyi CRKLog *g_pLogObject=NULL;
2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec;
2176af099aSliuyi #define DEFAULT_RW_LBA 128
2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
2676af099aSliuyi #define ERROR_COLOR_ATTR  printf("%c[30;41m", 0x1B);
2776af099aSliuyi #define NORMAL_COLOR_ATTR  printf("%c[37;40m", 0x1B);
28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len);
31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32c30d921cSKever Yang /*
33c30d921cSKever Yang u8 test_gpt_head[] = {
34c30d921cSKever Yang 	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35c30d921cSKever Yang 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36c30d921cSKever Yang 	0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37c30d921cSKever Yang 	0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38c30d921cSKever Yang 	0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39c30d921cSKever Yang 	0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40c30d921cSKever Yang */
41c30d921cSKever Yang 
4276af099aSliuyi void usage()
4376af099aSliuyi {
4476af099aSliuyi 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
45154ee062SEddie Cai 	printf("Help:\t\t\t-h or --version\r\n");
46154ee062SEddie Cai 	printf("Version:\t\t-v or --version\r\n");
47154ee062SEddie Cai 	printf("DownloadBoot:\t\tdb <Loader>\r\n");
48154ee062SEddie Cai 	printf("UpgradeLoader:\t\tul <Loader>\r\n");
49154ee062SEddie Cai 	printf("ReadLBA:\t\trl  <BeginSec> <SectorLen> <File>\r\n");
50154ee062SEddie Cai 	printf("WriteLBA:\t\twl  <BeginSec> <File>\r\n");
51154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
52154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
53154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
54154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
55154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
56154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
57154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
5878884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
5978884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
60*d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6176af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6276af099aSliuyi }
6376af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6476af099aSliuyi {
6576af099aSliuyi 	string strInfoText="";
6676af099aSliuyi 	char szText[256];
6776af099aSliuyi 	switch (promptID) {
6876af099aSliuyi 	case TESTDEVICE_PROGRESS:
6976af099aSliuyi 		sprintf(szText, "Test Device Total(%lld),Current(%lld)", totalValue, currentValue);
7076af099aSliuyi 		strInfoText = szText;
7176af099aSliuyi 		break;
7276af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7376af099aSliuyi 		sprintf(szText, "Lowerformat Device Total(%lld),Current(%lld)", totalValue, currentValue);
7476af099aSliuyi 		strInfoText = szText;
7576af099aSliuyi 		break;
7676af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
7776af099aSliuyi 		sprintf(szText, "Download Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
7876af099aSliuyi 		strInfoText = szText;
7976af099aSliuyi 		break;
8076af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8176af099aSliuyi 		sprintf(szText, "Check Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
8276af099aSliuyi 		strInfoText = szText;
8376af099aSliuyi 		break;
8476af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
8576af099aSliuyi 		sprintf(szText, "Tag Bad Block Total(%lld),Current(%lld)", totalValue, currentValue);
8676af099aSliuyi 		strInfoText = szText;
8776af099aSliuyi 		break;
8876af099aSliuyi 	case TESTBLOCK_PROGRESS:
8976af099aSliuyi 		sprintf(szText, "Test Block Total(%lld),Current(%lld)", totalValue, currentValue);
9076af099aSliuyi 		strInfoText = szText;
9176af099aSliuyi 		break;
9276af099aSliuyi 	case ERASEFLASH_PROGRESS:
9376af099aSliuyi 		sprintf(szText, "Erase Flash Total(%lld),Current(%lld)", totalValue, currentValue);
9476af099aSliuyi 		strInfoText = szText;
9576af099aSliuyi 		break;
9676af099aSliuyi 	case ERASESYSTEM_PROGRESS:
9776af099aSliuyi 		sprintf(szText, "Erase System partition Total(%lld),Current(%lld)", totalValue, currentValue);
9876af099aSliuyi 		strInfoText = szText;
9976af099aSliuyi 		break;
10076af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10176af099aSliuyi 		sprintf(szText, "<LocationID=%x> Erase Userdata partition Total(%lld),Current(%lld)",deviceLayer,totalValue, currentValue);
10276af099aSliuyi 		strInfoText = szText;
10376af099aSliuyi 		break;
10476af099aSliuyi 	}
10576af099aSliuyi 	if (strInfoText.size() > 0){
10676af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
10776af099aSliuyi 		CURSOR_DEL_LINE;
10876af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
10976af099aSliuyi 	}
11076af099aSliuyi 	if (emCall == CALL_LAST)
11176af099aSliuyi 		deviceLayer = 0;
11276af099aSliuyi }
11376af099aSliuyi 
11476af099aSliuyi char *strupr(char *szSrc)
11576af099aSliuyi {
11676af099aSliuyi 	char *p = szSrc;
11776af099aSliuyi 	while(*p){
11876af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
11976af099aSliuyi 			*p = *p - 'a' + 'A';
12076af099aSliuyi 		p++;
12176af099aSliuyi 	}
12276af099aSliuyi 	return szSrc;
12376af099aSliuyi }
12476af099aSliuyi void PrintData(PBYTE pData, int nSize)
12576af099aSliuyi {
12676af099aSliuyi 	char szPrint[17] = "\0";
12776af099aSliuyi 	int i;
12876af099aSliuyi 	for( i = 0; i < nSize; i++){
12976af099aSliuyi 		if(i % 16 == 0){
13076af099aSliuyi 			if(i / 16 > 0)
13176af099aSliuyi 				printf("     %s\r\n", szPrint);
13276af099aSliuyi 			printf("%08d ", i / 16);
13376af099aSliuyi 		}
13476af099aSliuyi 		printf("%02X ", pData[i]);
13576af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
13676af099aSliuyi 	}
13776af099aSliuyi 	if(i / 16 > 0)
13876af099aSliuyi 		printf("     %s\r\n", szPrint);
13976af099aSliuyi }
14076af099aSliuyi 
14176af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
14276af099aSliuyi {
14376af099aSliuyi 	if (!pszSrc)
14476af099aSliuyi 		return false;
14576af099aSliuyi 	int nSrcLen = strlen(pszSrc);
14676af099aSliuyi 	int nDestLen = nSrcLen * 2;
14776af099aSliuyi 
14876af099aSliuyi 	pszDest = NULL;
14976af099aSliuyi 	pszDest = new wchar_t[nDestLen];
15076af099aSliuyi 	if (!pszDest)
15176af099aSliuyi 		return false;
15276af099aSliuyi 	nDestLen = nDestLen * sizeof(wchar_t);
15376af099aSliuyi 	memset(pszDest, 0, nDestLen);
15476af099aSliuyi 	int iRet;
15576af099aSliuyi 	iconv_t cd;
15676af099aSliuyi 	cd = iconv_open("UTF-32", "UTF-8");
15776af099aSliuyi 	if((iconv_t)-1 == cd) {
15876af099aSliuyi 		delete []pszDest;
15976af099aSliuyi 		pszDest = NULL;
16076af099aSliuyi 	      return false;
16176af099aSliuyi 	 }
16276af099aSliuyi 	char *pIn, *pOut;
16376af099aSliuyi 	pIn = (char *)pszSrc;
16476af099aSliuyi 	pOut = (char *)pszDest;
16576af099aSliuyi 
16676af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
16776af099aSliuyi 
16876af099aSliuyi 	if(iRet == -1) {
16976af099aSliuyi 		delete []pszDest;
17076af099aSliuyi 		pszDest = NULL;
17176af099aSliuyi 		iconv_close(cd);
17276af099aSliuyi 		return false;
17376af099aSliuyi 	 }
17476af099aSliuyi 
17576af099aSliuyi 	 iconv_close(cd);
17676af099aSliuyi 
17776af099aSliuyi 	 return true;
17876af099aSliuyi }
17976af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
18076af099aSliuyi {
18176af099aSliuyi 	if (!pszSrc)
18276af099aSliuyi 		return false;
18376af099aSliuyi 	int nSrcLen = wcslen(pszSrc);
18476af099aSliuyi 	int nDestLen = nSrcLen * 2;
18576af099aSliuyi 	nSrcLen = nSrcLen * sizeof(wchar_t);
18676af099aSliuyi 	pszDest = NULL;
18776af099aSliuyi 	pszDest = new char[nDestLen];
18876af099aSliuyi 	if (!pszDest)
18976af099aSliuyi 		return false;
19076af099aSliuyi 	memset(pszDest, 0, nDestLen);
19176af099aSliuyi 	int iRet;
19276af099aSliuyi 	iconv_t cd;
19376af099aSliuyi 	cd = iconv_open("UTF-8", "UTF-32");
19476af099aSliuyi 
19576af099aSliuyi 	if((iconv_t)-1 == cd) {
19676af099aSliuyi 		delete []pszDest;
19776af099aSliuyi 		pszDest = NULL;
19876af099aSliuyi 	      return false;
19976af099aSliuyi 	 }
20076af099aSliuyi 	char *pIn, *pOut;
20176af099aSliuyi 	pIn = (char *)pszSrc;
20276af099aSliuyi 	pOut = (char *)pszDest;
20376af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
20476af099aSliuyi 
20576af099aSliuyi 	if(iRet == -1) {
20676af099aSliuyi 		delete []pszDest;
20776af099aSliuyi 		pszDest = NULL;
20876af099aSliuyi 		iconv_close(cd);
20976af099aSliuyi 		return false;
21076af099aSliuyi 	 }
21176af099aSliuyi 
21276af099aSliuyi 	 iconv_close(cd);
21376af099aSliuyi 
21476af099aSliuyi 	 return true;
21576af099aSliuyi }
21676af099aSliuyi int find_config_item(const char *pszName)
21776af099aSliuyi {
21876af099aSliuyi 	unsigned int i;
21976af099aSliuyi 	for(i = 0; i < g_ConfigItemVec.size(); i++){
22076af099aSliuyi 		if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){
22176af099aSliuyi 			return i;
22276af099aSliuyi 		}
22376af099aSliuyi 	}
22476af099aSliuyi 	return -1;
22576af099aSliuyi }
22676af099aSliuyi 
22776af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
22876af099aSliuyi {
22976af099aSliuyi 
23076af099aSliuyi 	stringstream configStream(pConfig);
23176af099aSliuyi 	string strLine, strItemName, strItemValue;
23276af099aSliuyi 	string::size_type line_size,pos;
23376af099aSliuyi 	STRUCT_CONFIG_ITEM item;
23476af099aSliuyi 	vecItem.clear();
23576af099aSliuyi 	while (!configStream.eof()){
23676af099aSliuyi 		getline(configStream, strLine);
23776af099aSliuyi 		line_size = strLine.size();
23876af099aSliuyi 		if (line_size == 0)
23976af099aSliuyi 			continue;
24076af099aSliuyi 		if (strLine[line_size-1] == '\r'){
24176af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
24276af099aSliuyi 		}
243c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
244c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
245c30d921cSKever Yang 		if (strLine.size()==0 )
246c30d921cSKever Yang 			continue;
247c30d921cSKever Yang 		if (strLine[0] == '#')
248c30d921cSKever Yang 			continue;
24976af099aSliuyi 		pos = strLine.find("=");
25076af099aSliuyi 		if (pos == string::npos){
25176af099aSliuyi 			continue;
25276af099aSliuyi 		}
25376af099aSliuyi 		strItemName = strLine.substr(0, pos);
25476af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
25576af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
25676af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
25776af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
25876af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
25976af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
26076af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
26176af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
26276af099aSliuyi 			vecItem.push_back(item);
26376af099aSliuyi 		}
26476af099aSliuyi 	}
26576af099aSliuyi 	return true;
26676af099aSliuyi 
26776af099aSliuyi }
26876af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
26976af099aSliuyi {
27076af099aSliuyi 	FILE *file = NULL;
27176af099aSliuyi 	file = fopen(pConfigFile, "rb");
27276af099aSliuyi 	if( !file ){
27376af099aSliuyi 		if (g_pLogObject)
27476af099aSliuyi 			g_pLogObject->Record("parse_config_file failed,err=%d,can't open file: %s\r\n", errno, pConfigFile);
27576af099aSliuyi 		return false;
27676af099aSliuyi 	}
27776af099aSliuyi 	int iFileSize;
27876af099aSliuyi 	fseek(file, 0, SEEK_END);
27976af099aSliuyi 	iFileSize = ftell(file);
28076af099aSliuyi 	fseek(file, 0, SEEK_SET);
28176af099aSliuyi 	char *pConfigBuf = NULL;
28276af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
28376af099aSliuyi 	if (!pConfigBuf){
28476af099aSliuyi 		fclose(file);
28576af099aSliuyi 		return false;
28676af099aSliuyi 	}
28776af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
28876af099aSliuyi 	int iRead;
28976af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
29076af099aSliuyi 	if (iRead != iFileSize){
29176af099aSliuyi 		if (g_pLogObject)
29276af099aSliuyi 			g_pLogObject->Record("parse_config_file failed,err=%d, read=%d, total=%d\r\n", errno, iRead, iFileSize);
29376af099aSliuyi 		fclose(file);
29476af099aSliuyi 		delete []pConfigBuf;
29576af099aSliuyi 		return false;
29676af099aSliuyi 	}
29776af099aSliuyi 	fclose(file);
29876af099aSliuyi 	bool bRet;
29976af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
30076af099aSliuyi 	delete []pConfigBuf;
30176af099aSliuyi 	return bRet;
30276af099aSliuyi }
303c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
304c30d921cSKever Yang {
305c30d921cSKever Yang 	string::size_type pos,prevPos;
306c30d921cSKever Yang 	string strOffset,strLen;
307c30d921cSKever Yang 	int iCount;
308c30d921cSKever Yang 	prevPos = pos = 0;
309c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
310c30d921cSKever Yang 		return false;
311c30d921cSKever Yang 	}
312c30d921cSKever Yang 	pos = strPartInfo.find('@');
313c30d921cSKever Yang 	if (pos == string::npos) {
314c30d921cSKever Yang 		return false;
315c30d921cSKever Yang 	}
316c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
317c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
318c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
319c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
320c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
321c30d921cSKever Yang 	} else {
322c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
323c30d921cSKever Yang 		if (iCount != 1) {
324c30d921cSKever Yang 			return false;
325c30d921cSKever Yang 		}
326c30d921cSKever Yang 	}
327c30d921cSKever Yang 
328c30d921cSKever Yang 	prevPos = pos + 1;
329c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
330c30d921cSKever Yang 	if (pos == string::npos) {
331c30d921cSKever Yang 		return false;
332c30d921cSKever Yang 	}
333c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
334c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
335c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
336c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
337c30d921cSKever Yang 	if (iCount != 1) {
338c30d921cSKever Yang 		return false;
339c30d921cSKever Yang 	}
340c30d921cSKever Yang 	prevPos = pos + 1;
341c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
342c30d921cSKever Yang 	if (pos == string::npos) {
343c30d921cSKever Yang 		return false;
344c30d921cSKever Yang 	}
345c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
346c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
347c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
348c30d921cSKever Yang 
349c30d921cSKever Yang 	return true;
350c30d921cSKever Yang }
351c30d921cSKever Yang 
352c30d921cSKever Yang bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem)
353c30d921cSKever Yang {
354c30d921cSKever Yang 	stringstream paramStream(pParameter);
355c30d921cSKever Yang 	bool bRet,bFind = false;
356c30d921cSKever Yang 	string strLine, strPartition, strPartInfo, strPartName;
357c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
358c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
359c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
360c30d921cSKever Yang 	vecItem.clear();
361c30d921cSKever Yang 	while (!paramStream.eof()) {
362c30d921cSKever Yang 		getline(paramStream,strLine);
363c30d921cSKever Yang 		line_size = strLine.size();
364c30d921cSKever Yang 		if (line_size == 0)
365c30d921cSKever Yang 			continue;
366c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
367c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
368c30d921cSKever Yang 		}
369c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
370c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
371c30d921cSKever Yang 		if (strLine.size()==0 )
372c30d921cSKever Yang 			continue;
373c30d921cSKever Yang 		if (strLine[0] == '#')
374c30d921cSKever Yang 			continue;
375c30d921cSKever Yang 		pos = strLine.find("mtdparts");
376c30d921cSKever Yang 		if (pos == string::npos) {
377c30d921cSKever Yang 			continue;
378c30d921cSKever Yang 		}
379c30d921cSKever Yang 		bFind = true;
380c30d921cSKever Yang 		posColon = strLine.find(':', pos);
381c30d921cSKever Yang 		if (posColon == string::npos) {
382c30d921cSKever Yang 			continue;
383c30d921cSKever Yang 		}
384c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
385c30d921cSKever Yang 		pos = 0;
386c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
387c30d921cSKever Yang 		while (posComma != string::npos) {
388c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
389c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
390c30d921cSKever Yang 			if (bRet) {
391c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
392c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
393c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
394c30d921cSKever Yang 				vecItem.push_back(item);
395c30d921cSKever Yang 			}
396c30d921cSKever Yang 			pos = posComma + 1;
397c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
398c30d921cSKever Yang 		}
399c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
400c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
401c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
402c30d921cSKever Yang 			if (bRet) {
403c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
404c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
405c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
406c30d921cSKever Yang 				vecItem.push_back(item);
407c30d921cSKever Yang 			}
408c30d921cSKever Yang 		}
409c30d921cSKever Yang 		break;
410c30d921cSKever Yang 	}
411c30d921cSKever Yang 	return bFind;
412c30d921cSKever Yang 
413c30d921cSKever Yang }
414c30d921cSKever Yang bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem)
415c30d921cSKever Yang {
416c30d921cSKever Yang 	FILE *file = NULL;
417c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
418c30d921cSKever Yang 	if( !file ) {
419c30d921cSKever Yang 		if (g_pLogObject)
420c30d921cSKever Yang 			g_pLogObject->Record("parse_parameter_file failed, err=%d, can't open file: %s\r\n", errno, pParamFile);
421c30d921cSKever Yang 		return false;
422c30d921cSKever Yang 	}
423c30d921cSKever Yang 	int iFileSize;
424c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
425c30d921cSKever Yang 	iFileSize = ftell(file);
426c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
427c30d921cSKever Yang 	char *pParamBuf = NULL;
428c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
429c30d921cSKever Yang 	if (!pParamBuf) {
430c30d921cSKever Yang 		fclose(file);
431c30d921cSKever Yang 		return false;
432c30d921cSKever Yang 	}
433c30d921cSKever Yang 	int iRead;
434c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
435c30d921cSKever Yang 	if (iRead != iFileSize) {
436c30d921cSKever Yang 		if (g_pLogObject)
437c30d921cSKever Yang 			g_pLogObject->Record("parse_parameter_file failed, err=%d, read=%d, total=%d\r\n", errno,iRead,iFileSize);
438c30d921cSKever Yang 		fclose(file);
439c30d921cSKever Yang 		delete []pParamBuf;
440c30d921cSKever Yang 		return false;
441c30d921cSKever Yang 	}
442c30d921cSKever Yang 	fclose(file);
443c30d921cSKever Yang 	bool bRet;
444c30d921cSKever Yang 	bRet = parse_parameter(pParamBuf, vecItem);
445c30d921cSKever Yang 	delete []pParamBuf;
446c30d921cSKever Yang 	return bRet;
447c30d921cSKever Yang }
448c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
449c30d921cSKever Yang {
450c30d921cSKever Yang 	efi_guid_t id;
451c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
452c30d921cSKever Yang 	unsigned int i;
453c30d921cSKever Yang 
454c30d921cSKever Yang 	/* Set all fields randomly */
455c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
456c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
457c30d921cSKever Yang 
458c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
459c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
460c30d921cSKever Yang 
461c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
462c30d921cSKever Yang }
463c30d921cSKever Yang 
464c30d921cSKever Yang void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors)
465c30d921cSKever Yang {
466c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
467c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
468c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
469c30d921cSKever Yang 	u32 i,j;
470c30d921cSKever Yang 	string strPartName;
471c30d921cSKever Yang 	string::size_type colonPos;
472c30d921cSKever Yang 	/*1.protective mbr*/
473c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
474c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
475c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
476c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
477c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
478c30d921cSKever Yang 	/*2.gpt header*/
479c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
480c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
481c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
482c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
483c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
484c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
485c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
486c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
487c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
488c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
489c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
490c30d921cSKever Yang 	gptHead->header_crc32 = 0;
491c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
492c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
493c30d921cSKever Yang 
494c30d921cSKever Yang 	/*3.gpt partition entry*/
495c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
496c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
497c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
498c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
499c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
500c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
501c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
502c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
503c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
504c30d921cSKever Yang 		if (colonPos != string::npos) {
505c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
506c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
507c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
508c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
509c30d921cSKever Yang 		}
510c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
511c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
512c30d921cSKever Yang 		gptEntry++;
513c30d921cSKever Yang 	}
514c30d921cSKever Yang 
515c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
516c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
517c30d921cSKever Yang 
518c30d921cSKever Yang }
519c30d921cSKever Yang bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec)
520c30d921cSKever Yang {
521c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
522c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
523c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
524c30d921cSKever Yang 
525c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
526c30d921cSKever Yang 	pSec0->uiRc4Flag = 1;
527c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
528c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
529c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
530c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
531c30d921cSKever Yang 	return true;
532c30d921cSKever Yang }
533c30d921cSKever Yang 
534c30d921cSKever Yang 
535c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
536c30d921cSKever Yang {
537c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
538c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
539c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
540c30d921cSKever Yang 
541c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
542c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
543c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
544c30d921cSKever Yang 	return true;
545c30d921cSKever Yang }
546c30d921cSKever Yang 
547c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
548c30d921cSKever Yang {
549c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
550c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
551c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
552c30d921cSKever Yang 
553c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
554c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
555c30d921cSKever Yang 	return true;
556c30d921cSKever Yang }
557c30d921cSKever Yang 
558c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
559c30d921cSKever Yang {
560c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
561c30d921cSKever Yang 	return true;
562c30d921cSKever Yang }
563c30d921cSKever Yang 
564c30d921cSKever Yang int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize)
565c30d921cSKever Yang {
566c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
567c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
568c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
569c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
570c30d921cSKever Yang 	UINT i;
571c30d921cSKever Yang 
572c30d921cSKever Yang 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec);
573c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
574c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
575c30d921cSKever Yang 		return -6;
576c30d921cSKever Yang 	}
577c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
578c30d921cSKever Yang 		return -7;
579c30d921cSKever Yang 	}
580c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
581c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
582c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
583c30d921cSKever Yang 
584c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
585c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
586c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
587c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
588c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
589c30d921cSKever Yang 
590c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
591c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
592c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
593c30d921cSKever Yang 		if(i == 1) {
594c30d921cSKever Yang 			continue;
595c30d921cSKever Yang 		} else {
596c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
597c30d921cSKever Yang 		}
598c30d921cSKever Yang 	}
599c30d921cSKever Yang 	return 0;
600c30d921cSKever Yang }
601c30d921cSKever Yang 
602c30d921cSKever Yang 
60376af099aSliuyi 
60476af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
60576af099aSliuyi {
60676af099aSliuyi 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
60776af099aSliuyi 		return true;
60876af099aSliuyi 	else
60976af099aSliuyi 	{
61076af099aSliuyi 		ERROR_COLOR_ATTR;
61176af099aSliuyi 		printf("The  Device did not support this operation!");
61276af099aSliuyi 		NORMAL_COLOR_ATTR;
61376af099aSliuyi 		printf("\r\n");
61476af099aSliuyi 		return false;
61576af099aSliuyi 	}
61676af099aSliuyi }
617c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
618c30d921cSKever Yang {
619c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
620c30d921cSKever Yang 	u32 total_size_sector;
621c30d921cSKever Yang 	CRKComm *pComm = NULL;
622c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
623c30d921cSKever Yang 	int iRet;
624c30d921cSKever Yang 	bool bRet, bSuccess = false;
625c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
626c30d921cSKever Yang 		return false;
627c30d921cSKever Yang 
628c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
629c30d921cSKever Yang 	if (!bRet) {
630c30d921cSKever Yang 		ERROR_COLOR_ATTR;
631c30d921cSKever Yang 		printf("Creating Comm Object failed!");
632c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
633c30d921cSKever Yang 		printf("\r\n");
634c30d921cSKever Yang 		return bSuccess;
635c30d921cSKever Yang 	}
636c30d921cSKever Yang 	printf("Write gpt...\r\n");
637c30d921cSKever Yang 	//1.get flash info
638c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
639c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
640c30d921cSKever Yang 		ERROR_COLOR_ATTR;
641c30d921cSKever Yang 		printf("Reading Flash Info failed!");
642c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
643c30d921cSKever Yang 		printf("\r\n");
644c30d921cSKever Yang 		return bSuccess;
645c30d921cSKever Yang 	}
646c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
647c30d921cSKever Yang 	//2.get partition from parameter
648c30d921cSKever Yang 	bRet = parse_parameter_file(szParameter, vecItems);
649c30d921cSKever Yang 	if (!bRet) {
650c30d921cSKever Yang 		ERROR_COLOR_ATTR;
651c30d921cSKever Yang 		printf("Parsing parameter failed!");
652c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
653c30d921cSKever Yang 		printf("\r\n");
654c30d921cSKever Yang 		return bSuccess;
655c30d921cSKever Yang 	}
656c30d921cSKever Yang 	vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34;
657c30d921cSKever Yang 	//3.generate gpt info
658c30d921cSKever Yang 	create_gpt_buffer(master_gpt, vecItems, total_size_sector);
659c30d921cSKever Yang 	memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
660c30d921cSKever Yang 	memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
661c30d921cSKever Yang 	//4. write gpt
662c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
663c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
664c30d921cSKever Yang 		ERROR_COLOR_ATTR;
665c30d921cSKever Yang 		printf("Writing master gpt failed!");
666c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
667c30d921cSKever Yang 		printf("\r\n");
668c30d921cSKever Yang 		return bSuccess;
669c30d921cSKever Yang 	}
670c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt);
671c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
672c30d921cSKever Yang 		ERROR_COLOR_ATTR;
673c30d921cSKever Yang 		printf("Writing backup gpt failed!");
674c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
675c30d921cSKever Yang 		printf("\r\n");
676c30d921cSKever Yang 		return bSuccess;
677c30d921cSKever Yang 	}
678c30d921cSKever Yang 	bSuccess = true;
679c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
680c30d921cSKever Yang 	CURSOR_DEL_LINE;
681c30d921cSKever Yang 	printf("Write gpt ok.\r\n");
682c30d921cSKever Yang 	return bSuccess;
683c30d921cSKever Yang }
68476af099aSliuyi 
68578884ef4SEddie Cai #include "boot_merger.h"
68678884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
68778884ef4SEddie Cai options gOpts;
68878884ef4SEddie Cai 
68978884ef4SEddie Cai 
69078884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
69178884ef4SEddie Cai char* gConfigPath;
69278884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
69378884ef4SEddie Cai 
69478884ef4SEddie Cai static inline void fixPath(char* path) {
69578884ef4SEddie Cai 	int i, len = strlen(path);
69678884ef4SEddie Cai 	for(i=0; i<len; i++) {
69778884ef4SEddie Cai 		if (path[i] == '\\')
69878884ef4SEddie Cai 			path[i] = '/';
69978884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
70078884ef4SEddie Cai 			path[i] = '\0';
70178884ef4SEddie Cai 	}
70278884ef4SEddie Cai }
70378884ef4SEddie Cai 
70478884ef4SEddie Cai static bool parseChip(FILE* file) {
70578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
70678884ef4SEddie Cai 		return false;
70778884ef4SEddie Cai 	}
70878884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
70978884ef4SEddie Cai 		return false;
71078884ef4SEddie Cai 	}
71178884ef4SEddie Cai 	printf("chip:%s\n", gOpts.chip);
71278884ef4SEddie Cai 	return true;
71378884ef4SEddie Cai }
71478884ef4SEddie Cai 
71578884ef4SEddie Cai static bool parseVersion(FILE* file) {
71678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
71778884ef4SEddie Cai 		return false;
71878884ef4SEddie Cai 	}
71978884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
72078884ef4SEddie Cai 		return false;
72178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
72278884ef4SEddie Cai 		return false;
72378884ef4SEddie Cai 	}
72478884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
72578884ef4SEddie Cai 		return false;
72678884ef4SEddie Cai 	printf("major:%d, minor:%d\n", gOpts.major, gOpts.minor);
72778884ef4SEddie Cai 	return true;
72878884ef4SEddie Cai }
72978884ef4SEddie Cai 
73078884ef4SEddie Cai static bool parse471(FILE* file) {
73178884ef4SEddie Cai 	int i, index, pos;
73278884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
73378884ef4SEddie Cai 
73478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
73578884ef4SEddie Cai 		return false;
73678884ef4SEddie Cai 	}
73778884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
73878884ef4SEddie Cai 		return false;
73978884ef4SEddie Cai 	printf("num:%d\n", gOpts.code471Num);
74078884ef4SEddie Cai 	if (!gOpts.code471Num)
74178884ef4SEddie Cai 		return true;
74278884ef4SEddie Cai 	if (gOpts.code471Num < 0)
74378884ef4SEddie Cai 		return false;
74478884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
74578884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
74678884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
74778884ef4SEddie Cai 			return false;
74878884ef4SEddie Cai 		}
74978884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
75078884ef4SEddie Cai 				!= 2)
75178884ef4SEddie Cai 			return false;
75278884ef4SEddie Cai 		index--;
75378884ef4SEddie Cai 		fixPath(buf);
75478884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
75578884ef4SEddie Cai 		printf("path%i:%s\n", index, gOpts.code471Path[index]);
75678884ef4SEddie Cai 	}
75778884ef4SEddie Cai 	pos = ftell(file);
75878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
75978884ef4SEddie Cai 		return false;
76078884ef4SEddie Cai 	}
76178884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
76278884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
76378884ef4SEddie Cai 	printf("sleep:%d\n", gOpts.code471Sleep);
76478884ef4SEddie Cai 	return true;
76578884ef4SEddie Cai }
76678884ef4SEddie Cai 
76778884ef4SEddie Cai static bool parse472(FILE* file) {
76878884ef4SEddie Cai 	int i, index, pos;
76978884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
77078884ef4SEddie Cai 
77178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
77278884ef4SEddie Cai 		return false;
77378884ef4SEddie Cai 	}
77478884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
77578884ef4SEddie Cai 		return false;
77678884ef4SEddie Cai 	printf("num:%d\n", gOpts.code472Num);
77778884ef4SEddie Cai 	if (!gOpts.code472Num)
77878884ef4SEddie Cai 		return true;
77978884ef4SEddie Cai 	if (gOpts.code472Num < 0)
78078884ef4SEddie Cai 		return false;
78178884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
78278884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
78378884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
78478884ef4SEddie Cai 			return false;
78578884ef4SEddie Cai 		}
78678884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
78778884ef4SEddie Cai 				!= 2)
78878884ef4SEddie Cai 			return false;
78978884ef4SEddie Cai 		fixPath(buf);
79078884ef4SEddie Cai 		index--;
79178884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
79278884ef4SEddie Cai 		printf("path%i:%s\n", index, gOpts.code472Path[index]);
79378884ef4SEddie Cai 	}
79478884ef4SEddie Cai 	pos = ftell(file);
79578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
79678884ef4SEddie Cai 		return false;
79778884ef4SEddie Cai 	}
79878884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
79978884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
80078884ef4SEddie Cai 	printf("sleep:%d\n", gOpts.code472Sleep);
80178884ef4SEddie Cai 	return true;
80278884ef4SEddie Cai }
80378884ef4SEddie Cai 
80478884ef4SEddie Cai static bool parseLoader(FILE* file) {
80578884ef4SEddie Cai 	int i, j, index, pos;
80678884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
80778884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
80878884ef4SEddie Cai 
80978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
81078884ef4SEddie Cai 		return false;
81178884ef4SEddie Cai 	}
81278884ef4SEddie Cai 	pos = ftell(file);
81378884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
81478884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
81578884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
81678884ef4SEddie Cai 			return false;
81778884ef4SEddie Cai 		}
81878884ef4SEddie Cai 	}
81978884ef4SEddie Cai 	printf("num:%d\n", gOpts.loaderNum);
82078884ef4SEddie Cai 	if (!gOpts.loaderNum)
82178884ef4SEddie Cai 		return false;
82278884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
82378884ef4SEddie Cai 		return false;
82478884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
82578884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
82678884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
82778884ef4SEddie Cai 			return false;
82878884ef4SEddie Cai 		}
82978884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
83078884ef4SEddie Cai 				!= 2)
83178884ef4SEddie Cai 			return false;
83278884ef4SEddie Cai 		index--;
83378884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
83478884ef4SEddie Cai 		printf("name%d:%s\n", index, gOpts.loader[index].name);
83578884ef4SEddie Cai 	}
83678884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
83778884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
83878884ef4SEddie Cai 			return false;
83978884ef4SEddie Cai 		}
84078884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
84178884ef4SEddie Cai 				!= 2)
84278884ef4SEddie Cai 			return false;
84378884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
84478884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
84578884ef4SEddie Cai 				fixPath(buf2);
84678884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
84778884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
84878884ef4SEddie Cai 				break;
84978884ef4SEddie Cai 			}
85078884ef4SEddie Cai 		}
85178884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
85278884ef4SEddie Cai 			return false;
85378884ef4SEddie Cai 		}
85478884ef4SEddie Cai 	}
85578884ef4SEddie Cai 	return true;
85678884ef4SEddie Cai }
85778884ef4SEddie Cai 
85878884ef4SEddie Cai static bool parseOut(FILE* file) {
85978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
86078884ef4SEddie Cai 		return false;
86178884ef4SEddie Cai 	}
86278884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
86378884ef4SEddie Cai 		return false;
86478884ef4SEddie Cai 	fixPath(gOpts.outPath);
86578884ef4SEddie Cai 	printf("out:%s\n", gOpts.outPath);
86678884ef4SEddie Cai 	return true;
86778884ef4SEddie Cai }
86878884ef4SEddie Cai 
86978884ef4SEddie Cai 
87078884ef4SEddie Cai void printOpts(FILE* out) {
87178884ef4SEddie Cai 	int i;
87278884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
87378884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
87478884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
87578884ef4SEddie Cai 
87678884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
87778884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
87878884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
87978884ef4SEddie Cai 	}
88078884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
88178884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
88278884ef4SEddie Cai 
88378884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
88478884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
88578884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
88678884ef4SEddie Cai 	}
88778884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
88878884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
88978884ef4SEddie Cai 
89078884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
89178884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
89278884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
89378884ef4SEddie Cai 	}
89478884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
89578884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
89678884ef4SEddie Cai 	}
89778884ef4SEddie Cai 
89878884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
89978884ef4SEddie Cai }
90078884ef4SEddie Cai 
90178884ef4SEddie Cai static bool parseOpts(void) {
90278884ef4SEddie Cai 	bool ret = false;
90378884ef4SEddie Cai 	bool chipOk = false;
90478884ef4SEddie Cai 	bool versionOk = false;
90578884ef4SEddie Cai 	bool code471Ok = true;
90678884ef4SEddie Cai 	bool code472Ok = true;
90778884ef4SEddie Cai 	bool loaderOk = false;
90878884ef4SEddie Cai 	bool outOk = false;
90978884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
91078884ef4SEddie Cai 
91178884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
91278884ef4SEddie Cai 	FILE* file;
91378884ef4SEddie Cai 	file = fopen(configPath, "r");
91478884ef4SEddie Cai 	if (!file) {
91578884ef4SEddie Cai 		fprintf(stderr, "config(%s) not found!\n", configPath);
91678884ef4SEddie Cai 		if (configPath == (char*)DEF_CONFIG_FILE) {
91778884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
91878884ef4SEddie Cai 			if (file) {
91978884ef4SEddie Cai 				fprintf(stderr, "create defconfig\n");
92078884ef4SEddie Cai 				printOpts(file);
92178884ef4SEddie Cai 			}
92278884ef4SEddie Cai 		}
92378884ef4SEddie Cai 		goto end;
92478884ef4SEddie Cai 	}
92578884ef4SEddie Cai 
92678884ef4SEddie Cai 	printf("start parse\n");
92778884ef4SEddie Cai 
92878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
92978884ef4SEddie Cai 		goto end;
93078884ef4SEddie Cai 	}
93178884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
93278884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
93378884ef4SEddie Cai 			chipOk = parseChip(file);
93478884ef4SEddie Cai 			if (!chipOk) {
93578884ef4SEddie Cai 				printf("parseChip failed!\n");
93678884ef4SEddie Cai 				goto end;
93778884ef4SEddie Cai 			}
93878884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
93978884ef4SEddie Cai 			versionOk = parseVersion(file);
94078884ef4SEddie Cai 			if (!versionOk) {
94178884ef4SEddie Cai 				printf("parseVersion failed!\n");
94278884ef4SEddie Cai 				goto end;
94378884ef4SEddie Cai 			}
94478884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
94578884ef4SEddie Cai 			code471Ok = parse471(file);
94678884ef4SEddie Cai 			if (!code471Ok) {
94778884ef4SEddie Cai 				printf("parse471 failed!\n");
94878884ef4SEddie Cai 				goto end;
94978884ef4SEddie Cai 			}
95078884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
95178884ef4SEddie Cai 			code472Ok = parse472(file);
95278884ef4SEddie Cai 			if (!code472Ok) {
95378884ef4SEddie Cai 				printf("parse472 failed!\n");
95478884ef4SEddie Cai 				goto end;
95578884ef4SEddie Cai 			}
95678884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
95778884ef4SEddie Cai 			loaderOk = parseLoader(file);
95878884ef4SEddie Cai 			if (!loaderOk) {
95978884ef4SEddie Cai 				printf("parseLoader failed!\n");
96078884ef4SEddie Cai 				goto end;
96178884ef4SEddie Cai 			}
96278884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
96378884ef4SEddie Cai 			outOk = parseOut(file);
96478884ef4SEddie Cai 			if (!outOk) {
96578884ef4SEddie Cai 				printf("parseOut failed!\n");
96678884ef4SEddie Cai 				goto end;
96778884ef4SEddie Cai 			}
96878884ef4SEddie Cai 		} else if (buf[0] == '#') {
96978884ef4SEddie Cai 			continue;
97078884ef4SEddie Cai 		} else {
97178884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
97278884ef4SEddie Cai 			goto end;
97378884ef4SEddie Cai 		}
97478884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
97578884ef4SEddie Cai 			goto end;
97678884ef4SEddie Cai 		}
97778884ef4SEddie Cai 	}
97878884ef4SEddie Cai 
97978884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
98078884ef4SEddie Cai 			&& loaderOk && outOk)
98178884ef4SEddie Cai 		ret = true;
98278884ef4SEddie Cai end:
98378884ef4SEddie Cai 	if (file)
98478884ef4SEddie Cai 		fclose(file);
98578884ef4SEddie Cai 	return ret;
98678884ef4SEddie Cai }
98778884ef4SEddie Cai 
98878884ef4SEddie Cai bool initOpts(void) {
98978884ef4SEddie Cai 	//set default opts
99078884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
99178884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
99278884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
99378884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
99478884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
99578884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
99678884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
99778884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
99878884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
99978884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
100078884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
100178884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
100278884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
100378884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
100478884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
100578884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
100678884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
100778884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
100878884ef4SEddie Cai 
100978884ef4SEddie Cai 	return parseOpts();
101078884ef4SEddie Cai }
101178884ef4SEddie Cai 
101278884ef4SEddie Cai /************merge code****************/
101378884ef4SEddie Cai 
101478884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
101578884ef4SEddie Cai 	uint8_t tmp[2] = {0};
101678884ef4SEddie Cai 	int i;
101778884ef4SEddie Cai 	uint32_t ret;
101878884ef4SEddie Cai 	//if (value > 0xFFFF) {
101978884ef4SEddie Cai 	//	return 0;
102078884ef4SEddie Cai 	//}
102178884ef4SEddie Cai 	for(i=0; i < 2; i++) {
102278884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
102378884ef4SEddie Cai 		value /= 100;
102478884ef4SEddie Cai 	}
102578884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
102678884ef4SEddie Cai 
102778884ef4SEddie Cai 	printf("ret:%x\n",ret);
102878884ef4SEddie Cai 	return ret&0xFF;
102978884ef4SEddie Cai }
103078884ef4SEddie Cai 
103178884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
103278884ef4SEddie Cai {
103378884ef4SEddie Cai 	int i;
103478884ef4SEddie Cai 	for (i = 0; i < len; i++) {
103578884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
103678884ef4SEddie Cai 	}
103778884ef4SEddie Cai 	wide[len] = 0;
103878884ef4SEddie Cai }
103978884ef4SEddie Cai 
104078884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
104178884ef4SEddie Cai 	char* end;
104278884ef4SEddie Cai 	char* start;
104378884ef4SEddie Cai 	int len;
104478884ef4SEddie Cai 	if (!path || !dst)
104578884ef4SEddie Cai 		return;
104678884ef4SEddie Cai 	start = strrchr(path, '/');
104778884ef4SEddie Cai 	if (!start)
104878884ef4SEddie Cai 		start = path;
104978884ef4SEddie Cai 	else
105078884ef4SEddie Cai 		start++;
105178884ef4SEddie Cai 	end = strrchr(path, '.');
1052641cfa16SEddie Cai 	if (!end || (end < start))
105378884ef4SEddie Cai 		end = path + strlen(path);
105478884ef4SEddie Cai 	len = end - start;
105578884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
105678884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
105778884ef4SEddie Cai 	str2wide(start, dst, len);
105878884ef4SEddie Cai 
105978884ef4SEddie Cai 
106078884ef4SEddie Cai 		char name[MAX_NAME_LEN];
106178884ef4SEddie Cai 		memset(name, 0, sizeof(name));
106278884ef4SEddie Cai 		memcpy(name, start, len);
106378884ef4SEddie Cai 		printf("path:%s, name:%s\n", path, name);
106478884ef4SEddie Cai 
106578884ef4SEddie Cai }
106678884ef4SEddie Cai 
106778884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
106878884ef4SEddie Cai 	struct stat st;
106978884ef4SEddie Cai 	if(stat(path, &st) < 0)
107078884ef4SEddie Cai 		return false;
107178884ef4SEddie Cai 	*size = st.st_size;
107278884ef4SEddie Cai 	printf("path:%s, size:%d\n", path, *size);
107378884ef4SEddie Cai 	return true;
107478884ef4SEddie Cai }
107578884ef4SEddie Cai 
107678884ef4SEddie Cai static inline rk_time getTime(void) {
107778884ef4SEddie Cai 	rk_time rkTime;
107878884ef4SEddie Cai 
107978884ef4SEddie Cai 	struct tm *tm;
108078884ef4SEddie Cai 	time_t tt = time(NULL);
108178884ef4SEddie Cai 	tm = localtime(&tt);
108278884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
108378884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
108478884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
108578884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
108678884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
108778884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
108878884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
108978884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
109078884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
109178884ef4SEddie Cai 	return rkTime;
109278884ef4SEddie Cai }
109378884ef4SEddie Cai 
109478884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
109578884ef4SEddie Cai 	bool ret = false;
109678884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
109778884ef4SEddie Cai 	uint8_t* buf;
109878884ef4SEddie Cai 
109978884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
110078884ef4SEddie Cai 	if (!inFile)
110178884ef4SEddie Cai 		goto end;
110278884ef4SEddie Cai 
110378884ef4SEddie Cai 	if (!getFileSize(path, &size))
110478884ef4SEddie Cai 		goto end;
110578884ef4SEddie Cai 	if (fix) {
110678884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
110778884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
110878884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
110978884ef4SEddie Cai 		fixSize +=tmp;
111078884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
111178884ef4SEddie Cai 	} else {
111278884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
111378884ef4SEddie Cai 	}
111478884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
111578884ef4SEddie Cai 		goto end;
111678884ef4SEddie Cai 
111778884ef4SEddie Cai 	if (fix) {
111878884ef4SEddie Cai 
111978884ef4SEddie Cai 		buf = gBuf;
112078884ef4SEddie Cai 		size = fixSize;
112178884ef4SEddie Cai 		while(1) {
112278884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
112378884ef4SEddie Cai 			buf += SMALL_PACKET;
112478884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
112578884ef4SEddie Cai 				break;
112678884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
112778884ef4SEddie Cai 		}
112878884ef4SEddie Cai 	} else {
112978884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
113078884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
113178884ef4SEddie Cai 		size +=tmp;
113278884ef4SEddie Cai 		P_RC4(gBuf, size);
113378884ef4SEddie Cai 	}
113478884ef4SEddie Cai 
113578884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
113678884ef4SEddie Cai 		goto end;
113778884ef4SEddie Cai 	ret = true;
113878884ef4SEddie Cai end:
113978884ef4SEddie Cai 	if (inFile)
114078884ef4SEddie Cai 		fclose(inFile);
114178884ef4SEddie Cai 	if (!ret)
114278884ef4SEddie Cai 		printf("write entry(%s) failed\n", path);
114378884ef4SEddie Cai 	return ret;
114478884ef4SEddie Cai }
114578884ef4SEddie Cai 
114678884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
114778884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
114878884ef4SEddie Cai 	uint32_t size;
114978884ef4SEddie Cai 	rk_boot_entry entry;
115078884ef4SEddie Cai 
115178884ef4SEddie Cai 	printf("write:%s\n", path);
1152641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
115378884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
115478884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
115578884ef4SEddie Cai 	entry.type = type;
115678884ef4SEddie Cai 	entry.dataOffset = *offset;
115778884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
115878884ef4SEddie Cai 		printf("save entry(%s) failed:\n\tcannot get file size.\n", path);
115978884ef4SEddie Cai 		return false;
116078884ef4SEddie Cai 	}
116178884ef4SEddie Cai 	if (fix)
116278884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
116378884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
116478884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
116578884ef4SEddie Cai 	printf("align size:%d\n", size);
116678884ef4SEddie Cai 	entry.dataSize = size;
116778884ef4SEddie Cai 	entry.dataDelay = delay;
116878884ef4SEddie Cai 	*offset += size;
116978884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
117078884ef4SEddie Cai 	return true;
117178884ef4SEddie Cai }
117278884ef4SEddie Cai 
117378884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
117478884ef4SEddie Cai 	char buffer[5];
117578884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
117678884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
117778884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
117878884ef4SEddie Cai }
117978884ef4SEddie Cai 
118078884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
118178884ef4SEddie Cai 	printf("chip:%s\n", chip);
118278884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
118378884ef4SEddie Cai 	if(!chip) {
118478884ef4SEddie Cai 		goto end;
118578884ef4SEddie Cai 	}
118678884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
118778884ef4SEddie Cai 		chipType = RK28_DEVICE;
118878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
118978884ef4SEddie Cai 		chipType = RK28_DEVICE;
119078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
119178884ef4SEddie Cai 		chipType = RK281X_DEVICE;
119278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
119378884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
119478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
119578884ef4SEddie Cai 		chipType = RK27_DEVICE;
119678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
119778884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
119878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
119978884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
120078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
120178884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
120278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
120378884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
120478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
120578884ef4SEddie Cai 		chipType = RK29_DEVICE;
120678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
120778884ef4SEddie Cai 		chipType = RK292X_DEVICE;
120878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
120978884ef4SEddie Cai 		chipType = RK30_DEVICE;
121078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
121178884ef4SEddie Cai 		chipType = RK30B_DEVICE;
121278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
121378884ef4SEddie Cai 		chipType = RK31_DEVICE;
121478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
121578884ef4SEddie Cai 		chipType = RK32_DEVICE;
121678884ef4SEddie Cai 	} else {
121778884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
121878884ef4SEddie Cai 	}
121978884ef4SEddie Cai 
122078884ef4SEddie Cai end:
122178884ef4SEddie Cai 	printf("type:0x%x\n", chipType);
122278884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
122378884ef4SEddie Cai 		printf("chip type not support!\n");
122478884ef4SEddie Cai 	}
122578884ef4SEddie Cai 	return chipType;
122678884ef4SEddie Cai }
122778884ef4SEddie Cai 
122878884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
122978884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
123078884ef4SEddie Cai 	hdr->tag = TAG;
123178884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
123278884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
123378884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
123478884ef4SEddie Cai 	hdr->releaseTime = getTime();
123578884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
123678884ef4SEddie Cai 
123778884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
123878884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
123978884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
124078884ef4SEddie Cai 
124178884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
124278884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
124378884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
124478884ef4SEddie Cai 
124578884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
124678884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
124778884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
124878884ef4SEddie Cai #ifndef USE_P_RC4
124978884ef4SEddie Cai 	hdr->rc4Flag = 1;
125078884ef4SEddie Cai #endif
125178884ef4SEddie Cai }
125278884ef4SEddie Cai 
125378884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
125478884ef4SEddie Cai 	uint32_t size = 0;
125578884ef4SEddie Cai 	uint32_t crc = 0;
125678884ef4SEddie Cai 
125778884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
125878884ef4SEddie Cai 	getFileSize(path, &size);
125978884ef4SEddie Cai 	if (!file)
126078884ef4SEddie Cai 		goto end;
126178884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
126278884ef4SEddie Cai 		goto end;
126378884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
126478884ef4SEddie Cai 	printf("crc:0x%08x\n", crc);
126578884ef4SEddie Cai end:
126678884ef4SEddie Cai 	if (file)
126778884ef4SEddie Cai 		fclose(file);
126878884ef4SEddie Cai 	return crc;
126978884ef4SEddie Cai }
127078884ef4SEddie Cai 
127178884ef4SEddie Cai bool mergeBoot(void) {
127278884ef4SEddie Cai 	uint32_t dataOffset;
127378884ef4SEddie Cai 	bool ret = false;
127478884ef4SEddie Cai 	int i;
127578884ef4SEddie Cai 	FILE* outFile;
127678884ef4SEddie Cai 	uint32_t crc;
127778884ef4SEddie Cai 	rk_boot_header hdr;
127878884ef4SEddie Cai 
127978884ef4SEddie Cai 	if (!initOpts())
128078884ef4SEddie Cai 		return false;
128178884ef4SEddie Cai 	{
128278884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
128378884ef4SEddie Cai 		char version[MAX_LINE_LEN];
128478884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
128578884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
128678884ef4SEddie Cai 			subfix[0] = '\0';
128778884ef4SEddie Cai 		}
128878884ef4SEddie Cai 		strcat(gOpts.outPath, version);
128978884ef4SEddie Cai 		printf("fix opt:%s\n", gOpts.outPath);
129078884ef4SEddie Cai 	}
129178884ef4SEddie Cai 
129278884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
129378884ef4SEddie Cai 	printOpts(stdout);
129478884ef4SEddie Cai 	printf("---------------\n\n");
129578884ef4SEddie Cai 
129678884ef4SEddie Cai 
129778884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
129878884ef4SEddie Cai 	if (!outFile) {
129978884ef4SEddie Cai 		printf("open out file(%s) failed\n", gOpts.outPath);
130078884ef4SEddie Cai 		goto end;
130178884ef4SEddie Cai 	}
130278884ef4SEddie Cai 
130378884ef4SEddie Cai 	getBoothdr(&hdr);
130478884ef4SEddie Cai 	printf("write hdr\n");
130578884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
130678884ef4SEddie Cai 
130778884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
130878884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
130978884ef4SEddie Cai 		sizeof(rk_boot_entry);
131078884ef4SEddie Cai 
131178884ef4SEddie Cai 	printf("write code 471 entry\n");
131278884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
131378884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
131478884ef4SEddie Cai 					&dataOffset, NULL, false))
131578884ef4SEddie Cai 			goto end;
131678884ef4SEddie Cai 	}
131778884ef4SEddie Cai 	printf("write code 472 entry\n");
131878884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
131978884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
132078884ef4SEddie Cai 					&dataOffset, NULL, false))
132178884ef4SEddie Cai 			goto end;
132278884ef4SEddie Cai 	}
132378884ef4SEddie Cai 	printf("write loader entry\n");
132478884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
132578884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
132678884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
132778884ef4SEddie Cai 			goto end;
132878884ef4SEddie Cai 	}
132978884ef4SEddie Cai 
133078884ef4SEddie Cai 	printf("write code 471\n");
133178884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
133278884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
133378884ef4SEddie Cai 			goto end;
133478884ef4SEddie Cai 	}
133578884ef4SEddie Cai 	printf("write code 472\n");
133678884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
133778884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
133878884ef4SEddie Cai 			goto end;
133978884ef4SEddie Cai 	}
134078884ef4SEddie Cai 	printf("write loader\n");
134178884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
134278884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
134378884ef4SEddie Cai 			goto end;
134478884ef4SEddie Cai 	}
134578884ef4SEddie Cai 	fflush(outFile);
134678884ef4SEddie Cai 
134778884ef4SEddie Cai 	printf("write crc\n");
134878884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
134978884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
135078884ef4SEddie Cai 		goto end;
135178884ef4SEddie Cai 	printf("done\n");
135278884ef4SEddie Cai 	ret = true;
135378884ef4SEddie Cai end:
135478884ef4SEddie Cai 	if (outFile)
135578884ef4SEddie Cai 		fclose(outFile);
135678884ef4SEddie Cai 	return ret;
135778884ef4SEddie Cai }
135878884ef4SEddie Cai 
135978884ef4SEddie Cai /************merge code end************/
136078884ef4SEddie Cai /************unpack code***************/
136178884ef4SEddie Cai 
136278884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
136378884ef4SEddie Cai {
136478884ef4SEddie Cai 	int i;
136578884ef4SEddie Cai 	for (i = 0; i < len; i++) {
136678884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
136778884ef4SEddie Cai 	}
136878884ef4SEddie Cai 	str[len] = 0;
136978884ef4SEddie Cai }
137078884ef4SEddie Cai 
137178884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
137278884ef4SEddie Cai 		FILE* inFile) {
137378884ef4SEddie Cai 	bool ret = false;
137478884ef4SEddie Cai 	int size, i;
137578884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
137678884ef4SEddie Cai 	if (!outFile)
137778884ef4SEddie Cai 		goto end;
137878884ef4SEddie Cai 	printf("unpack entry(%s)\n", name);
137978884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
138078884ef4SEddie Cai 	size = entry->dataSize;
138178884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
138278884ef4SEddie Cai 		goto end;
138378884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
138478884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
138578884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
138678884ef4SEddie Cai 		if (size % SMALL_PACKET)
138778884ef4SEddie Cai 		{
138878884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
138978884ef4SEddie Cai 		}
139078884ef4SEddie Cai 	} else {
139178884ef4SEddie Cai 		P_RC4(gBuf, size);
139278884ef4SEddie Cai 	}
139378884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
139478884ef4SEddie Cai 		goto end;
139578884ef4SEddie Cai 	ret = true;
139678884ef4SEddie Cai end:
139778884ef4SEddie Cai 	if (outFile)
139878884ef4SEddie Cai 		fclose(outFile);
139978884ef4SEddie Cai 	return ret;
140078884ef4SEddie Cai }
140178884ef4SEddie Cai 
140278884ef4SEddie Cai bool unpackBoot(char* path) {
140378884ef4SEddie Cai 	bool ret = false;
140478884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
140578884ef4SEddie Cai 	int entryNum, i;
140678884ef4SEddie Cai 	char name[MAX_NAME_LEN];
140778884ef4SEddie Cai 	rk_boot_entry* entrys;
140878884ef4SEddie Cai 	if (!inFile) {
140978884ef4SEddie Cai 		fprintf(stderr, "loader(%s) not found\n", path);
141078884ef4SEddie Cai 		goto end;
141178884ef4SEddie Cai 	}
141278884ef4SEddie Cai 
141378884ef4SEddie Cai 	rk_boot_header hdr;
141478884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
141578884ef4SEddie Cai 		fprintf(stderr, "read header failed\n");
141678884ef4SEddie Cai 		goto end;
141778884ef4SEddie Cai 	}
141878884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
141978884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
142078884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
142178884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
142278884ef4SEddie Cai 		fprintf(stderr, "read data failed\n");
142378884ef4SEddie Cai 		goto end;
142478884ef4SEddie Cai 	}
142578884ef4SEddie Cai 
142678884ef4SEddie Cai 	printf("entry num:%d\n", entryNum);
142778884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
142878884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
142978884ef4SEddie Cai 
143078884ef4SEddie Cai 		printf("entry:t=%d, name=%s, off=%d, size=%d\n",
143178884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
143278884ef4SEddie Cai 				entrys[i].dataSize);
143378884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
143478884ef4SEddie Cai 			fprintf(stderr, "unpack entry(%s) failed\n", name);
143578884ef4SEddie Cai 			goto end;
143678884ef4SEddie Cai 		}
143778884ef4SEddie Cai 	}
143878884ef4SEddie Cai 	printf("done\n");
143978884ef4SEddie Cai 	ret = true;
144078884ef4SEddie Cai end:
144178884ef4SEddie Cai 	if (inFile)
144278884ef4SEddie Cai 		fclose(inFile);
144378884ef4SEddie Cai 	return ret;
144478884ef4SEddie Cai }
144578884ef4SEddie Cai 
144676af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
144776af099aSliuyi {
144876af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
144976af099aSliuyi 		return false;
145076af099aSliuyi 	CRKImage *pImage = NULL;
145176af099aSliuyi 	CRKBoot *pBoot = NULL;
145276af099aSliuyi 	bool bRet, bSuccess = false;
145376af099aSliuyi 	int iRet;
145476af099aSliuyi 
145576af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
145676af099aSliuyi 	if (!bRet){
145776af099aSliuyi 		ERROR_COLOR_ATTR;
145876af099aSliuyi 		printf("Open loader failed,exit download boot!");
145976af099aSliuyi 		NORMAL_COLOR_ATTR;
146076af099aSliuyi 		printf("\r\n");
146176af099aSliuyi 		return bSuccess;
146276af099aSliuyi 	} else {
146376af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
146476af099aSliuyi 		CRKComm *pComm = NULL;
146576af099aSliuyi 		CRKDevice *pDevice = NULL;
146676af099aSliuyi 
146776af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
146876af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
146976af099aSliuyi 		if (!bRet) {
147076af099aSliuyi 			if (pImage)
147176af099aSliuyi 				delete pImage;
147276af099aSliuyi 			ERROR_COLOR_ATTR;
147376af099aSliuyi 			printf("Creating Comm Object failed!");
147476af099aSliuyi 			NORMAL_COLOR_ATTR;
147576af099aSliuyi 			printf("\r\n");
147676af099aSliuyi 			return bSuccess;
147776af099aSliuyi 		}
147876af099aSliuyi 
147976af099aSliuyi 		pDevice = new CRKDevice(dev);
148076af099aSliuyi 		if (!pDevice) {
148176af099aSliuyi 			if (pImage)
148276af099aSliuyi 				delete pImage;
148376af099aSliuyi 			if (pComm)
148476af099aSliuyi 				delete pComm;
148576af099aSliuyi 			ERROR_COLOR_ATTR;
148676af099aSliuyi 			printf("Creating device object failed!");
148776af099aSliuyi 			NORMAL_COLOR_ATTR;
148876af099aSliuyi 			printf("\r\n");
148976af099aSliuyi 			return bSuccess;
149076af099aSliuyi 		}
149176af099aSliuyi 
149276af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
149376af099aSliuyi 		printf("Download boot...\r\n");
149476af099aSliuyi 		iRet = pDevice->DownloadBoot();
149576af099aSliuyi 
149676af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
149776af099aSliuyi 		CURSOR_DEL_LINE;
149876af099aSliuyi 		if (iRet == 0) {
149976af099aSliuyi 			bSuccess = true;
150076af099aSliuyi 			printf("Download boot ok.\r\n");
150176af099aSliuyi 		}
150276af099aSliuyi 		else
150376af099aSliuyi 			printf("Download boot failed!\r\n");
150476af099aSliuyi 
150576af099aSliuyi 		if (pImage)
150676af099aSliuyi 			delete pImage;
150776af099aSliuyi 		if(pDevice)
150876af099aSliuyi 			delete pDevice;
150976af099aSliuyi 	}
151076af099aSliuyi 	return bSuccess;
151176af099aSliuyi }
1512c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1513c30d921cSKever Yang {
1514c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1515c30d921cSKever Yang 		return false;
1516c30d921cSKever Yang 	CRKImage *pImage = NULL;
1517c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1518c30d921cSKever Yang 	CRKComm *pComm = NULL;
1519c30d921cSKever Yang 	bool bRet, bSuccess = false;
1520c30d921cSKever Yang 	int iRet;
1521c30d921cSKever Yang 	char index;
1522c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1523c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1524c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1525c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1526c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1527c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1528c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1529c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1530c30d921cSKever Yang 	if (!bRet){
1531c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1532c30d921cSKever Yang 		printf("Open loader failed,exit upgrade loader!");
1533c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1534c30d921cSKever Yang 		printf("\r\n");
1535c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1536c30d921cSKever Yang 	} else {
1537c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1538c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1539c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1540c30d921cSKever Yang 		if (!bRet) {
1541c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1542c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1543c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1544c30d921cSKever Yang 			printf("\r\n");
1545c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1546c30d921cSKever Yang 		}
1547c30d921cSKever Yang 
1548c30d921cSKever Yang 		printf("Upgrade loader...\r\n");
1549c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1550c30d921cSKever Yang 		if (index == -1) {
1551c30d921cSKever Yang 			if (g_pLogObject) {
1552c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed");
1553c30d921cSKever Yang 			}
1554c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1555c30d921cSKever Yang 		}
1556c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1557c30d921cSKever Yang 		if (!bRet) {
1558c30d921cSKever Yang 			if (g_pLogObject) {
1559c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed");
1560c30d921cSKever Yang 			}
1561c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1562c30d921cSKever Yang 		}
1563c30d921cSKever Yang 
1564c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1565c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1566c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1567c30d921cSKever Yang 			if (g_pLogObject) {
1568c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed");
1569c30d921cSKever Yang 			}
1570c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1571c30d921cSKever Yang 		}
1572c30d921cSKever Yang 
1573c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1574c30d921cSKever Yang 		if (index == -1) {
1575c30d921cSKever Yang 			if (g_pLogObject) {
1576c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed");
1577c30d921cSKever Yang 			}
1578c30d921cSKever Yang 			delete []loaderCodeBuffer;
1579c30d921cSKever Yang 			return -4;
1580c30d921cSKever Yang 		}
1581c30d921cSKever Yang 
1582c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1583c30d921cSKever Yang 		if (!bRet) {
1584c30d921cSKever Yang 			if (g_pLogObject) {
1585c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed");
1586c30d921cSKever Yang 			}
1587c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1588c30d921cSKever Yang 		}
1589c30d921cSKever Yang 
1590c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1591c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1592c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1593c30d921cSKever Yang 			if (g_pLogObject) {
1594c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed");
1595c30d921cSKever Yang 			}
1596c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1597c30d921cSKever Yang 		}
1598c30d921cSKever Yang 
1599c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1600c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1601c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1602c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1603c30d921cSKever Yang 		if (!pIDBData) {
1604c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1605c30d921cSKever Yang 			printf("New memory failed!");
1606c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1607c30d921cSKever Yang 			printf("\r\n");
1608c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1609c30d921cSKever Yang 		}
1610c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1611c30d921cSKever Yang 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize);
1612c30d921cSKever Yang 		if (iRet != 0) {
1613c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1614c30d921cSKever Yang 			printf("Make idblock failed!");
1615c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1616c30d921cSKever Yang 			printf("\r\n");
1617c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1618c30d921cSKever Yang 		}
1619c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1620c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1621c30d921cSKever Yang 		CURSOR_DEL_LINE;
1622c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1623c30d921cSKever Yang 			pComm->Reset_Usb_Device();
1624c30d921cSKever Yang 			bSuccess = true;
1625c30d921cSKever Yang 			printf("Upgrade loader ok.\r\n");
1626c30d921cSKever Yang 		} else {
1627c30d921cSKever Yang 			printf("Upgrade loader failed!\r\n");
1628c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1629c30d921cSKever Yang 		}
1630c30d921cSKever Yang 	}
1631c30d921cSKever Yang Exit_UpgradeLoader:
1632c30d921cSKever Yang 	if (pImage)
1633c30d921cSKever Yang 		delete pImage;
1634c30d921cSKever Yang 	if (pComm)
1635c30d921cSKever Yang 		delete pComm;
1636c30d921cSKever Yang 	if (loaderCodeBuffer)
1637c30d921cSKever Yang 		delete []loaderCodeBuffer;
1638c30d921cSKever Yang 	if (loaderDataBuffer)
1639c30d921cSKever Yang 		delete []loaderDataBuffer;
1640c30d921cSKever Yang 	if (pIDBData)
1641c30d921cSKever Yang 		delete []pIDBData;
1642c30d921cSKever Yang 	return bSuccess;
1643c30d921cSKever Yang }
1644c30d921cSKever Yang 
164576af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
164676af099aSliuyi {
164776af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
164876af099aSliuyi 		return false;
164976af099aSliuyi 	CRKImage *pImage = NULL;
165076af099aSliuyi 	bool bRet, bSuccess = false;
165176af099aSliuyi 	int iRet;
165276af099aSliuyi 	CRKScan *pScan = NULL;
165376af099aSliuyi 	pScan = new CRKScan();
165476af099aSliuyi 	pScan->SetVidPid();
165576af099aSliuyi 
165676af099aSliuyi 	CRKComm *pComm = NULL;
165776af099aSliuyi 	CRKDevice *pDevice = NULL;
165876af099aSliuyi 
165976af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
166076af099aSliuyi 	if (!bRet) {
166176af099aSliuyi 		if (pScan)
166276af099aSliuyi 			delete pScan;
166376af099aSliuyi 		ERROR_COLOR_ATTR;
166476af099aSliuyi 		printf("Creating Comm Object failed!");
166576af099aSliuyi 		NORMAL_COLOR_ATTR;
166676af099aSliuyi 		printf("\r\n");
166776af099aSliuyi 		return bSuccess;
166876af099aSliuyi 	}
166976af099aSliuyi 
167076af099aSliuyi 	pDevice = new CRKDevice(dev);
167176af099aSliuyi 	if (!pDevice) {
167276af099aSliuyi 		if (pComm)
167376af099aSliuyi 			delete pComm;
167476af099aSliuyi 		if (pScan)
167576af099aSliuyi 			delete pScan;
167676af099aSliuyi 		ERROR_COLOR_ATTR;
167776af099aSliuyi 		printf("Creating device object failed!");
167876af099aSliuyi 		NORMAL_COLOR_ATTR;
167976af099aSliuyi 		printf("\r\n");
168076af099aSliuyi 		return bSuccess;
168176af099aSliuyi 	}
168276af099aSliuyi 
168376af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
168476af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
168576af099aSliuyi 
168676af099aSliuyi 	printf("Start to erase flash...\r\n");
168776af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
168876af099aSliuyi 	if (pDevice)
168976af099aSliuyi 		delete pDevice;
169076af099aSliuyi 
169176af099aSliuyi 	if (iRet == 0) {
169276af099aSliuyi 		if (pScan) {
169376af099aSliuyi 			pScan->SetVidPid();
169476af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
169576af099aSliuyi 			delete pScan;
169676af099aSliuyi 		}
169776af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
169876af099aSliuyi 		CURSOR_DEL_LINE;
169976af099aSliuyi 		bSuccess = true;
170076af099aSliuyi 		printf("Erase flash ok.\r\n");
170176af099aSliuyi 	}
170276af099aSliuyi 
170376af099aSliuyi 	return bSuccess;
170476af099aSliuyi }
170576af099aSliuyi 
170676af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
170776af099aSliuyi {
170876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
170976af099aSliuyi 		return false;
171076af099aSliuyi 	CRKUsbComm *pComm = NULL;
171176af099aSliuyi 	bool bRet, bSuccess = false;
171276af099aSliuyi 	int iRet;
171376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
171476af099aSliuyi 	if (bRet) {
171576af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
171676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
171776af099aSliuyi 			if (g_pLogObject)
171876af099aSliuyi 				g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet);
171976af099aSliuyi 			printf("Test Device Fail!\r\n");
172076af099aSliuyi 		} else {
172176af099aSliuyi 			bSuccess = true;
172276af099aSliuyi 			printf("Test Device OK.\r\n");
172376af099aSliuyi 		}
172476af099aSliuyi 	} else {
172576af099aSliuyi 		printf("Test Device quit,Creating comm object failed!\r\n");
172676af099aSliuyi 	}
172776af099aSliuyi 	if (pComm) {
172876af099aSliuyi 		delete pComm;
172976af099aSliuyi 		pComm = NULL;
173076af099aSliuyi 	}
173176af099aSliuyi 	return bSuccess;
173276af099aSliuyi }
173376af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
173476af099aSliuyi {
173576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
173676af099aSliuyi 		return false;
173776af099aSliuyi 	CRKUsbComm *pComm = NULL;
173876af099aSliuyi 	bool bRet, bSuccess = false;
173976af099aSliuyi 	int iRet;
174076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
174176af099aSliuyi 	if (bRet) {
174276af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
174376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
174476af099aSliuyi 			if (g_pLogObject)
174576af099aSliuyi 				g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet);
174676af099aSliuyi 			printf("Reset Device Fail!\r\n");
174776af099aSliuyi 		} else {
174876af099aSliuyi 			bSuccess = true;
174976af099aSliuyi 			printf("Reset Device OK.\r\n");
175076af099aSliuyi 		}
175176af099aSliuyi 	} else {
175276af099aSliuyi 		printf("Reset Device quit,Creating comm object failed!\r\n");
175376af099aSliuyi 	}
175476af099aSliuyi 	if (pComm) {
175576af099aSliuyi 		delete pComm;
175676af099aSliuyi 		pComm = NULL;
175776af099aSliuyi 	}
175876af099aSliuyi 	return bSuccess;
175976af099aSliuyi }
176076af099aSliuyi 
176176af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
176276af099aSliuyi {
176376af099aSliuyi 	CRKUsbComm *pComm = NULL;
176476af099aSliuyi 	bool bRet, bSuccess = false;
176576af099aSliuyi 	int iRet;
176676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
176776af099aSliuyi 		return bSuccess;
176876af099aSliuyi 
176976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
177076af099aSliuyi 	if (bRet) {
177176af099aSliuyi 		BYTE flashID[5];
177276af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
177376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
177476af099aSliuyi 			if (g_pLogObject)
177576af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet);
177676af099aSliuyi 			printf("Read flash ID Fail!\r\n");
177776af099aSliuyi 		} else {
177876af099aSliuyi 			printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
177976af099aSliuyi 			bSuccess = true;
178076af099aSliuyi 		}
178176af099aSliuyi 	} else {
178276af099aSliuyi 		printf("Read flash ID quit,Creating comm object failed!\r\n");
178376af099aSliuyi 	}
178476af099aSliuyi 	if (pComm) {
178576af099aSliuyi 		delete pComm;
178676af099aSliuyi 		pComm = NULL;
178776af099aSliuyi 	}
178876af099aSliuyi 	return bSuccess;
178976af099aSliuyi }
179076af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
179176af099aSliuyi {
179276af099aSliuyi 	CRKUsbComm *pComm = NULL;
179376af099aSliuyi 	bool bRet, bSuccess = false;
179476af099aSliuyi 	int iRet;
179576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
179676af099aSliuyi 		return bSuccess;
179776af099aSliuyi 
179876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
179976af099aSliuyi 	if (bRet) {
180076af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
180176af099aSliuyi 		UINT uiRead;
180276af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
180376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
180476af099aSliuyi 			if (g_pLogObject)
180576af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet);
180676af099aSliuyi 			printf("Read flash Info Fail!\r\n");
180776af099aSliuyi 		} else {
180876af099aSliuyi 			printf("Flash Info:\r\n");
180976af099aSliuyi 			if (info.bManufCode <= 7) {
181076af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
181176af099aSliuyi 			}
181276af099aSliuyi 			else
181376af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode);
181476af099aSliuyi 
181576af099aSliuyi 			printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024);
181676af099aSliuyi 			printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2);
181776af099aSliuyi 			printf("\tPage Size: %dKB\r\n", info.bPageSize / 2);
181876af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
181976af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
182076af099aSliuyi 			printf("\tFlash CS: ");
182176af099aSliuyi 			for(int i = 0; i < 8; i++) {
182276af099aSliuyi 				if( info.bFlashCS & (1 << i) )
182376af099aSliuyi 					printf("Flash<%d> ", i);
182476af099aSliuyi 			}
182576af099aSliuyi 			printf("\r\n");
182676af099aSliuyi 			bSuccess = true;
182776af099aSliuyi 		}
182876af099aSliuyi 	}else {
182976af099aSliuyi 		printf("Read flash Info quit,Creating comm object failed!\r\n");
183076af099aSliuyi 	}
183176af099aSliuyi 	if (pComm) {
183276af099aSliuyi 		delete pComm;
183376af099aSliuyi 		pComm = NULL;
183476af099aSliuyi 	}
183576af099aSliuyi 	return bSuccess;
183676af099aSliuyi }
183776af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
183876af099aSliuyi {
183976af099aSliuyi 	CRKUsbComm *pComm = NULL;
184076af099aSliuyi 	bool bRet, bSuccess = false;
184176af099aSliuyi 	int iRet;
184276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
184376af099aSliuyi 		return bSuccess;
184476af099aSliuyi 
184576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
184676af099aSliuyi 	if (bRet) {
184776af099aSliuyi 		BYTE chipInfo[16];
184876af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
184976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
185076af099aSliuyi 			if (g_pLogObject)
185176af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet);
185276af099aSliuyi 			printf("Read Chip Info Fail!\r\n");
185376af099aSliuyi 		} else {
185476af099aSliuyi 			string strChipInfo;
185576af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
185676af099aSliuyi 			printf("Chip Info:%s\r\n", strChipInfo.c_str());
185776af099aSliuyi 			bSuccess = true;
185876af099aSliuyi 		}
185976af099aSliuyi 	} else {
186076af099aSliuyi 		printf("Read Chip Info quit,Creating comm object failed!\r\n");
186176af099aSliuyi 	}
186276af099aSliuyi 	if (pComm) {
186376af099aSliuyi 		delete pComm;
186476af099aSliuyi 		pComm = NULL;
186576af099aSliuyi 	}
186676af099aSliuyi 	return bSuccess;
186776af099aSliuyi }
186876af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
186976af099aSliuyi {
187076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
187176af099aSliuyi 		return false;
187276af099aSliuyi 	CRKUsbComm *pComm = NULL;
187376af099aSliuyi 	FILE *file = NULL;
187476af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
187576af099aSliuyi 	int iRet;
187676af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
187776af099aSliuyi 	int nSectorSize = 512;
187876af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
187976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
188076af099aSliuyi 	if (bRet) {
188176af099aSliuyi 		if(szFile) {
188276af099aSliuyi 			file = fopen(szFile, "wb+");
188376af099aSliuyi 			if( !file ) {
188476af099aSliuyi 				printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
188576af099aSliuyi 				goto Exit_ReadLBA;
188676af099aSliuyi 			}
188776af099aSliuyi 		}
188876af099aSliuyi 
188976af099aSliuyi 		while(uiLen > 0) {
189076af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
189176af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
189276af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
189376af099aSliuyi 			if(ERR_SUCCESS == iRet) {
189476af099aSliuyi 				uiLen -= iRead;
189576af099aSliuyi 				iTotalRead += iRead;
189676af099aSliuyi 
189776af099aSliuyi 				if(szFile) {
189876af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
189976af099aSliuyi 					if (bFirst){
190076af099aSliuyi 						if (iTotalRead >= 1024)
190176af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
190276af099aSliuyi 						else
190376af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
190476af099aSliuyi 						bFirst = false;
190576af099aSliuyi 					} else {
190676af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
190776af099aSliuyi 						CURSOR_DEL_LINE;
190876af099aSliuyi 						if (iTotalRead >= 1024)
190976af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
191076af099aSliuyi 						else
191176af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
191276af099aSliuyi 					}
191376af099aSliuyi 				}
191476af099aSliuyi 				else
191576af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
191676af099aSliuyi 			} else {
191776af099aSliuyi 				if (g_pLogObject)
191876af099aSliuyi 					g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet);
191976af099aSliuyi 
192076af099aSliuyi 				printf("Read LBA failed!\r\n");
192176af099aSliuyi 				goto Exit_ReadLBA;
192276af099aSliuyi 			}
192376af099aSliuyi 		}
192476af099aSliuyi 		bSuccess = true;
192576af099aSliuyi 	} else {
192676af099aSliuyi 		printf("Read LBA quit,Creating comm object failed!\r\n");
192776af099aSliuyi 	}
192876af099aSliuyi Exit_ReadLBA:
192976af099aSliuyi 	if (pComm) {
193076af099aSliuyi 		delete pComm;
193176af099aSliuyi 		pComm = NULL;
193276af099aSliuyi 	}
193376af099aSliuyi 	if (file)
193476af099aSliuyi 		fclose(file);
193576af099aSliuyi 	return bSuccess;
193676af099aSliuyi }
193776af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
193876af099aSliuyi {
193976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
194076af099aSliuyi 		return false;
194176af099aSliuyi 	CRKUsbComm *pComm = NULL;
194276af099aSliuyi 	FILE *file = NULL;
194376af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
194476af099aSliuyi 	int iRet;
194576af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
194676af099aSliuyi 	UINT iWrite = 0, iRead = 0;
194776af099aSliuyi 	UINT uiLen;
194876af099aSliuyi 	int nSectorSize = 512;
194976af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
195076af099aSliuyi 
195176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
195276af099aSliuyi 	if (bRet) {
195376af099aSliuyi 		file = fopen(szFile, "rb");
195476af099aSliuyi 		if( !file ) {
195576af099aSliuyi 			printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
195676af099aSliuyi 			goto Exit_WriteLBA;
195776af099aSliuyi 		}
195876af099aSliuyi 
195976af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
196076af099aSliuyi 		iFileSize = ftello(file);
196176af099aSliuyi 		fseeko(file, 0, SEEK_SET);
196276af099aSliuyi 		while(iTotalWrite < iFileSize) {
196376af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
196476af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
196576af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
196676af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
196776af099aSliuyi 			if(ERR_SUCCESS == iRet) {
196876af099aSliuyi 				uiBegin += uiLen;
196976af099aSliuyi 				iTotalWrite += iWrite;
197076af099aSliuyi 				if (bFirst) {
197176af099aSliuyi 					if (iTotalWrite >= 1024)
197276af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
197376af099aSliuyi 					else
197476af099aSliuyi 						printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
197576af099aSliuyi 					bFirst = false;
197676af099aSliuyi 				} else {
197776af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
197876af099aSliuyi 					CURSOR_DEL_LINE;
197976af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
198076af099aSliuyi 				}
198176af099aSliuyi 			} else {
198276af099aSliuyi 				if (g_pLogObject)
198376af099aSliuyi 					g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
198476af099aSliuyi 
198576af099aSliuyi 				printf("Write LBA failed!\r\n");
198676af099aSliuyi 				goto Exit_WriteLBA;
198776af099aSliuyi 			}
198876af099aSliuyi 		}
198976af099aSliuyi 		bSuccess = true;
199076af099aSliuyi 	} else {
199176af099aSliuyi 		printf("Write LBA quit,Creating comm object failed!\r\n");
199276af099aSliuyi 	}
199376af099aSliuyi Exit_WriteLBA:
199476af099aSliuyi 	if (pComm) {
199576af099aSliuyi 		delete pComm;
199676af099aSliuyi 		pComm = NULL;
199776af099aSliuyi 	}
199876af099aSliuyi 	if (file)
199976af099aSliuyi 		fclose(file);
200076af099aSliuyi 	return bSuccess;
200176af099aSliuyi }
200276af099aSliuyi 
200376af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
200476af099aSliuyi {
200576af099aSliuyi 	string strItem;
200676af099aSliuyi 	char szItem[100];
200776af099aSliuyi 	char *pos = NULL, *pStart;
200876af099aSliuyi 	pStart = pszItems;
200976af099aSliuyi 	pos = strchr(pStart, ',');
201076af099aSliuyi 	while(pos != NULL) {
201176af099aSliuyi 		memset(szItem, 0, 100);
201276af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
201376af099aSliuyi 		strItem = szItem;
201476af099aSliuyi 		vecItems.push_back(strItem);
201576af099aSliuyi 		pStart = pos + 1;
201676af099aSliuyi 		if (*pStart == 0)
201776af099aSliuyi 			break;
201876af099aSliuyi 		pos = strchr(pStart, ',');
201976af099aSliuyi 	}
202076af099aSliuyi 	if (strlen(pStart) > 0) {
202176af099aSliuyi 		memset(szItem, 0, 100);
202276af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
202376af099aSliuyi 		strItem = szItem;
202476af099aSliuyi 		vecItems.push_back(strItem);
202576af099aSliuyi 	}
202676af099aSliuyi }
2027c30d921cSKever Yang 
2028*d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2029*d71e8c20SEddie Cai {
2030*d71e8c20SEddie Cai 	FILE *file = NULL;
2031*d71e8c20SEddie Cai 	int len;
2032*d71e8c20SEddie Cai 
2033*d71e8c20SEddie Cai 	if(!tag || !spl)
2034*d71e8c20SEddie Cai 		return;
2035*d71e8c20SEddie Cai 	len = strlen(tag);
2036*d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2037*d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2038*d71e8c20SEddie Cai 	if( !file ){
2039*d71e8c20SEddie Cai 		return;
2040*d71e8c20SEddie Cai 	}
2041*d71e8c20SEddie Cai 	int iFileSize;
2042*d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2043*d71e8c20SEddie Cai 	iFileSize = ftell(file);
2044*d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2045*d71e8c20SEddie Cai 	char *Buf = NULL;
2046*d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2047*d71e8c20SEddie Cai 	if (!Buf){
2048*d71e8c20SEddie Cai 		fclose(file);
2049*d71e8c20SEddie Cai 		return;
2050*d71e8c20SEddie Cai 	}
2051*d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2052*d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2053*d71e8c20SEddie Cai 	int iRead;
2054*d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2055*d71e8c20SEddie Cai 	if (iRead != iFileSize){
2056*d71e8c20SEddie Cai 		fclose(file);
2057*d71e8c20SEddie Cai 		delete []Buf;
2058*d71e8c20SEddie Cai 		return;
2059*d71e8c20SEddie Cai 	}
2060*d71e8c20SEddie Cai 	fclose(file);
2061*d71e8c20SEddie Cai 
2062*d71e8c20SEddie Cai 	len = strlen(spl);
2063*d71e8c20SEddie Cai 	char *tagedspl = new char[len + 5];
2064*d71e8c20SEddie Cai 	strcpy(tagedspl, spl);
2065*d71e8c20SEddie Cai 	strcpy(tagedspl + len, ".tag");
2066*d71e8c20SEddie Cai 	tagedspl[len+4] = 0;
2067*d71e8c20SEddie Cai 	printf("taged spl writed to %s\n", tagedspl);
2068*d71e8c20SEddie Cai 
2069*d71e8c20SEddie Cai 	file = fopen(tagedspl, "wb");
2070*d71e8c20SEddie Cai 	if( !file ){
2071*d71e8c20SEddie Cai 		delete []tagedspl;
2072*d71e8c20SEddie Cai 		delete []Buf;
2073*d71e8c20SEddie Cai 		return;
2074*d71e8c20SEddie Cai 	}
2075*d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
2076*d71e8c20SEddie Cai 	fclose(file);
2077*d71e8c20SEddie Cai 	delete []tagedspl;
2078*d71e8c20SEddie Cai 	delete []Buf;
2079*d71e8c20SEddie Cai 	printf("done\n");
2080*d71e8c20SEddie Cai 	return;
2081*d71e8c20SEddie Cai }
2082*d71e8c20SEddie Cai 
208376af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
208476af099aSliuyi {
208576af099aSliuyi 	string strCmd;
208676af099aSliuyi 	strCmd = argv[1];
208776af099aSliuyi 	ssize_t cnt;
208876af099aSliuyi 	bool bRet,bSuccess = false;
20898df2d64aSEddie Cai 	char *s;
20908df2d64aSEddie Cai 	int i, ret;
209176af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
209276af099aSliuyi 
209376af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
20948df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
20958df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
20968df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
209778884ef4SEddie Cai 
20988df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
209976af099aSliuyi 		usage();
210076af099aSliuyi 		return true;
21018df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2102c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
210376af099aSliuyi 		return true;
210478884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
210578884ef4SEddie Cai 		mergeBoot();
210678884ef4SEddie Cai 
210778884ef4SEddie Cai 		return true;
210878884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
210978884ef4SEddie Cai 		string strLoader = argv[2];
211078884ef4SEddie Cai 
211178884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
211278884ef4SEddie Cai 		return true;
2113*d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
2114*d71e8c20SEddie Cai 		if (argc == 4) {
2115*d71e8c20SEddie Cai 			string tag = argv[2];
2116*d71e8c20SEddie Cai 			string spl = argv[3];
2117*d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
2118*d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
2119*d71e8c20SEddie Cai 			return true;
2120*d71e8c20SEddie Cai 		}
2121*d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
2122*d71e8c20SEddie Cai 		usage();
212376af099aSliuyi 	}
212476af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
212576af099aSliuyi 	if (cnt < 1) {
212676af099aSliuyi 		ERROR_COLOR_ATTR;
212776af099aSliuyi 		printf("No found any rockusb device,please plug device in!");
212876af099aSliuyi 		NORMAL_COLOR_ATTR;
212976af099aSliuyi 		printf("\r\n");
213076af099aSliuyi 		return bSuccess;
213176af099aSliuyi 	} else if (cnt > 1) {
213276af099aSliuyi 		ERROR_COLOR_ATTR;
213376af099aSliuyi 		printf("Found many rockusb devices,please plug device out!");
213476af099aSliuyi 		NORMAL_COLOR_ATTR;
213576af099aSliuyi 		printf("\r\n");
213676af099aSliuyi 		return bSuccess;
213776af099aSliuyi 	}
213876af099aSliuyi 
213976af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
214076af099aSliuyi 	if (!bRet) {
214176af099aSliuyi 		ERROR_COLOR_ATTR;
214276af099aSliuyi 		printf("Getting information of rockusb device failed!");
214376af099aSliuyi 		NORMAL_COLOR_ATTR;
214476af099aSliuyi 		printf("\r\n");
214576af099aSliuyi 		return bSuccess;
214676af099aSliuyi 	}
214776af099aSliuyi 
214876af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
214976af099aSliuyi 		if ((argc != 2) && (argc != 3))
215076af099aSliuyi 			printf("Parameter of [RD] command is invalid,please check help!\r\n");
215176af099aSliuyi 		else {
215276af099aSliuyi 			if (argc == 2)
215376af099aSliuyi 				bSuccess = reset_device(dev);
215476af099aSliuyi 			else {
215576af099aSliuyi 				UINT uiSubCode;
215676af099aSliuyi 				char *pszEnd;
215776af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
215876af099aSliuyi 				if (*pszEnd)
215976af099aSliuyi 					printf("Subcode is invalid,please check!\r\n");
216076af099aSliuyi 				else {
216176af099aSliuyi 					if (uiSubCode <= 5)
216276af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
216376af099aSliuyi 					else
216476af099aSliuyi 						printf("Subcode is invalid,please check!\r\n");
216576af099aSliuyi 				}
216676af099aSliuyi 			}
216776af099aSliuyi 		}
216876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
216976af099aSliuyi 		bSuccess = test_device(dev);
217076af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
217176af099aSliuyi 		bSuccess = read_flash_id(dev);
217276af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
217376af099aSliuyi 		bSuccess = read_flash_info(dev);
217476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
217576af099aSliuyi 		bSuccess = read_chip_info(dev);
217676af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
217776af099aSliuyi 		if (argc > 2) {
217876af099aSliuyi 			string strLoader;
217976af099aSliuyi 			strLoader = argv[2];
218076af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
218176af099aSliuyi 		} else if (argc == 2) {
218276af099aSliuyi 			ret = find_config_item("loader");
218376af099aSliuyi 			if (ret == -1)
218476af099aSliuyi 				printf("No found loader item from config!\r\n");
218576af099aSliuyi 			else
218676af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
218776af099aSliuyi 		} else
218876af099aSliuyi 			printf("Parameter of [DB] command is invalid,please check help!\r\n");
2189c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
2190c30d921cSKever Yang 		if (argc > 2) {
2191c30d921cSKever Yang 			string strParameter;
2192c30d921cSKever Yang 			strParameter = argv[2];
2193c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
2194c30d921cSKever Yang 		} else
2195c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid,please check help!\r\n");
2196c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
2197c30d921cSKever Yang 		if (argc > 2) {
2198c30d921cSKever Yang 			string strLoader;
2199c30d921cSKever Yang 			strLoader = argv[2];
2200c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
2201c30d921cSKever Yang 		} else
2202c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid,please check help!\r\n");
220376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
220476af099aSliuyi 		if (argc == 2) {
220576af099aSliuyi 			bSuccess = erase_flash(dev);
220676af099aSliuyi 		} else
220776af099aSliuyi 			printf("Parameter of [EF] command is invalid,please check help!\r\n");
220876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
220976af099aSliuyi 		if (argc == 4) {
221076af099aSliuyi 			UINT uiBegin;
221176af099aSliuyi 			char *pszEnd;
221276af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
221376af099aSliuyi 			if (*pszEnd)
221476af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
221576af099aSliuyi 			else
221676af099aSliuyi 				bSuccess = write_lba(dev, uiBegin, argv[3]);
221776af099aSliuyi 		} else
221876af099aSliuyi 			printf("Parameter of [WL] command is invalid,please check help!\r\n");
221976af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
222076af099aSliuyi 		char *pszEnd;
222176af099aSliuyi 		UINT uiBegin, uiLen;
222276af099aSliuyi 		if (argc != 5)
222376af099aSliuyi 			printf("Parameter of [RL] command is invalid,please check help!\r\n");
222476af099aSliuyi 		else {
222576af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
222676af099aSliuyi 			if (*pszEnd)
222776af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
222876af099aSliuyi 			else {
222976af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
223076af099aSliuyi 				if (*pszEnd)
223176af099aSliuyi 					printf("Len is invalid,please check!\r\n");
223276af099aSliuyi 				else {
223376af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
223476af099aSliuyi 				}
223576af099aSliuyi 			}
223676af099aSliuyi 		}
223776af099aSliuyi 	} else {
2238c30d921cSKever Yang 		printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n");
223976af099aSliuyi 	}
224076af099aSliuyi 	return bSuccess;
224176af099aSliuyi }
224276af099aSliuyi 
224376af099aSliuyi 
224476af099aSliuyi int main(int argc, char* argv[])
224576af099aSliuyi {
224676af099aSliuyi 	CRKScan *pScan = NULL;
224776af099aSliuyi 	int ret;
224876af099aSliuyi 	char szProgramProcPath[100];
224976af099aSliuyi 	char szProgramDir[256];
225076af099aSliuyi 	string strLogDir,strConfigFile;
225176af099aSliuyi 	struct stat statBuf;
225276af099aSliuyi 
225376af099aSliuyi 	g_ConfigItemVec.clear();
225476af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
225576af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
225676af099aSliuyi 		strcpy(szProgramDir, ".");
225776af099aSliuyi 	else {
225876af099aSliuyi 		char *pSlash;
225976af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
226076af099aSliuyi 		if (pSlash)
226176af099aSliuyi 			*pSlash = '\0';
226276af099aSliuyi 	}
226376af099aSliuyi 	strLogDir = szProgramDir;
226476af099aSliuyi 	strLogDir +=  "/log/";
226576af099aSliuyi 	strConfigFile = szProgramDir;
226676af099aSliuyi 	strConfigFile += "/config.ini";
226776af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
226876af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
226976af099aSliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
227076af099aSliuyi 
227176af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
227276af099aSliuyi 		if (g_pLogObject) {
227376af099aSliuyi 			g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
227476af099aSliuyi 		}
227576af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
227676af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
227776af099aSliuyi 	}
227876af099aSliuyi 
227976af099aSliuyi 	ret = libusb_init(NULL);
228076af099aSliuyi 	if (ret < 0) {
228176af099aSliuyi 		if (g_pLogObject) {
228276af099aSliuyi 			g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
228376af099aSliuyi 			delete g_pLogObject;
228476af099aSliuyi 		}
228576af099aSliuyi 		return -1;
228676af099aSliuyi 	}
228776af099aSliuyi 
228876af099aSliuyi 	pScan = new CRKScan();
228976af099aSliuyi 	if (!pScan) {
229076af099aSliuyi 		if (g_pLogObject) {
229176af099aSliuyi 			g_pLogObject->Record("Error:failed to Create object for searching device");
229276af099aSliuyi 			delete g_pLogObject;
229376af099aSliuyi 		}
229476af099aSliuyi 		libusb_exit(NULL);
229576af099aSliuyi 		return -2;
229676af099aSliuyi 	}
229776af099aSliuyi 	pScan->SetVidPid();
229876af099aSliuyi 
229976af099aSliuyi 	if (argc == 1)
230076af099aSliuyi 		usage();
230176af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
230276af099aSliuyi 			return -0xFF;
230376af099aSliuyi 	if (pScan)
230476af099aSliuyi 		delete pScan;
230576af099aSliuyi 	if (g_pLogObject)
230676af099aSliuyi 		delete g_pLogObject;
230776af099aSliuyi 	libusb_exit(NULL);
230876af099aSliuyi 	return 0;
230976af099aSliuyi }
2310