xref: /rkdeveloptool/main.cpp (revision 78884ef4bafbcdb297daf3d3da7adf84677908d7)
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");
58*78884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
59*78884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
6076af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6176af099aSliuyi }
6276af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6376af099aSliuyi {
6476af099aSliuyi 	string strInfoText="";
6576af099aSliuyi 	char szText[256];
6676af099aSliuyi 	switch (promptID) {
6776af099aSliuyi 	case TESTDEVICE_PROGRESS:
6876af099aSliuyi 		sprintf(szText, "Test Device Total(%lld),Current(%lld)", totalValue, currentValue);
6976af099aSliuyi 		strInfoText = szText;
7076af099aSliuyi 		break;
7176af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7276af099aSliuyi 		sprintf(szText, "Lowerformat Device Total(%lld),Current(%lld)", totalValue, currentValue);
7376af099aSliuyi 		strInfoText = szText;
7476af099aSliuyi 		break;
7576af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
7676af099aSliuyi 		sprintf(szText, "Download Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
7776af099aSliuyi 		strInfoText = szText;
7876af099aSliuyi 		break;
7976af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8076af099aSliuyi 		sprintf(szText, "Check Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
8176af099aSliuyi 		strInfoText = szText;
8276af099aSliuyi 		break;
8376af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
8476af099aSliuyi 		sprintf(szText, "Tag Bad Block Total(%lld),Current(%lld)", totalValue, currentValue);
8576af099aSliuyi 		strInfoText = szText;
8676af099aSliuyi 		break;
8776af099aSliuyi 	case TESTBLOCK_PROGRESS:
8876af099aSliuyi 		sprintf(szText, "Test Block Total(%lld),Current(%lld)", totalValue, currentValue);
8976af099aSliuyi 		strInfoText = szText;
9076af099aSliuyi 		break;
9176af099aSliuyi 	case ERASEFLASH_PROGRESS:
9276af099aSliuyi 		sprintf(szText, "Erase Flash Total(%lld),Current(%lld)", totalValue, currentValue);
9376af099aSliuyi 		strInfoText = szText;
9476af099aSliuyi 		break;
9576af099aSliuyi 	case ERASESYSTEM_PROGRESS:
9676af099aSliuyi 		sprintf(szText, "Erase System partition Total(%lld),Current(%lld)", totalValue, currentValue);
9776af099aSliuyi 		strInfoText = szText;
9876af099aSliuyi 		break;
9976af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10076af099aSliuyi 		sprintf(szText, "<LocationID=%x> Erase Userdata partition Total(%lld),Current(%lld)",deviceLayer,totalValue, currentValue);
10176af099aSliuyi 		strInfoText = szText;
10276af099aSliuyi 		break;
10376af099aSliuyi 	}
10476af099aSliuyi 	if (strInfoText.size() > 0){
10576af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
10676af099aSliuyi 		CURSOR_DEL_LINE;
10776af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
10876af099aSliuyi 	}
10976af099aSliuyi 	if (emCall == CALL_LAST)
11076af099aSliuyi 		deviceLayer = 0;
11176af099aSliuyi }
11276af099aSliuyi 
11376af099aSliuyi char *strupr(char *szSrc)
11476af099aSliuyi {
11576af099aSliuyi 	char *p = szSrc;
11676af099aSliuyi 	while(*p){
11776af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
11876af099aSliuyi 			*p = *p - 'a' + 'A';
11976af099aSliuyi 		p++;
12076af099aSliuyi 	}
12176af099aSliuyi 	return szSrc;
12276af099aSliuyi }
12376af099aSliuyi void PrintData(PBYTE pData, int nSize)
12476af099aSliuyi {
12576af099aSliuyi 	char szPrint[17] = "\0";
12676af099aSliuyi 	int i;
12776af099aSliuyi 	for( i = 0; i < nSize; i++){
12876af099aSliuyi 		if(i % 16 == 0){
12976af099aSliuyi 			if(i / 16 > 0)
13076af099aSliuyi 				printf("     %s\r\n", szPrint);
13176af099aSliuyi 			printf("%08d ", i / 16);
13276af099aSliuyi 		}
13376af099aSliuyi 		printf("%02X ", pData[i]);
13476af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
13576af099aSliuyi 	}
13676af099aSliuyi 	if(i / 16 > 0)
13776af099aSliuyi 		printf("     %s\r\n", szPrint);
13876af099aSliuyi }
13976af099aSliuyi 
14076af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
14176af099aSliuyi {
14276af099aSliuyi 	if (!pszSrc)
14376af099aSliuyi 		return false;
14476af099aSliuyi 	int nSrcLen = strlen(pszSrc);
14576af099aSliuyi 	int nDestLen = nSrcLen * 2;
14676af099aSliuyi 
14776af099aSliuyi 	pszDest = NULL;
14876af099aSliuyi 	pszDest = new wchar_t[nDestLen];
14976af099aSliuyi 	if (!pszDest)
15076af099aSliuyi 		return false;
15176af099aSliuyi 	nDestLen = nDestLen * sizeof(wchar_t);
15276af099aSliuyi 	memset(pszDest, 0, nDestLen);
15376af099aSliuyi 	int iRet;
15476af099aSliuyi 	iconv_t cd;
15576af099aSliuyi 	cd = iconv_open("UTF-32", "UTF-8");
15676af099aSliuyi 	if((iconv_t)-1 == cd) {
15776af099aSliuyi 		delete []pszDest;
15876af099aSliuyi 		pszDest = NULL;
15976af099aSliuyi 	      return false;
16076af099aSliuyi 	 }
16176af099aSliuyi 	char *pIn, *pOut;
16276af099aSliuyi 	pIn = (char *)pszSrc;
16376af099aSliuyi 	pOut = (char *)pszDest;
16476af099aSliuyi 
16576af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
16676af099aSliuyi 
16776af099aSliuyi 	if(iRet == -1) {
16876af099aSliuyi 		delete []pszDest;
16976af099aSliuyi 		pszDest = NULL;
17076af099aSliuyi 		iconv_close(cd);
17176af099aSliuyi 		return false;
17276af099aSliuyi 	 }
17376af099aSliuyi 
17476af099aSliuyi 	 iconv_close(cd);
17576af099aSliuyi 
17676af099aSliuyi 	 return true;
17776af099aSliuyi }
17876af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
17976af099aSliuyi {
18076af099aSliuyi 	if (!pszSrc)
18176af099aSliuyi 		return false;
18276af099aSliuyi 	int nSrcLen = wcslen(pszSrc);
18376af099aSliuyi 	int nDestLen = nSrcLen * 2;
18476af099aSliuyi 	nSrcLen = nSrcLen * sizeof(wchar_t);
18576af099aSliuyi 	pszDest = NULL;
18676af099aSliuyi 	pszDest = new char[nDestLen];
18776af099aSliuyi 	if (!pszDest)
18876af099aSliuyi 		return false;
18976af099aSliuyi 	memset(pszDest, 0, nDestLen);
19076af099aSliuyi 	int iRet;
19176af099aSliuyi 	iconv_t cd;
19276af099aSliuyi 	cd = iconv_open("UTF-8", "UTF-32");
19376af099aSliuyi 
19476af099aSliuyi 	if((iconv_t)-1 == cd) {
19576af099aSliuyi 		delete []pszDest;
19676af099aSliuyi 		pszDest = NULL;
19776af099aSliuyi 	      return false;
19876af099aSliuyi 	 }
19976af099aSliuyi 	char *pIn, *pOut;
20076af099aSliuyi 	pIn = (char *)pszSrc;
20176af099aSliuyi 	pOut = (char *)pszDest;
20276af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
20376af099aSliuyi 
20476af099aSliuyi 	if(iRet == -1) {
20576af099aSliuyi 		delete []pszDest;
20676af099aSliuyi 		pszDest = NULL;
20776af099aSliuyi 		iconv_close(cd);
20876af099aSliuyi 		return false;
20976af099aSliuyi 	 }
21076af099aSliuyi 
21176af099aSliuyi 	 iconv_close(cd);
21276af099aSliuyi 
21376af099aSliuyi 	 return true;
21476af099aSliuyi }
21576af099aSliuyi int find_config_item(const char *pszName)
21676af099aSliuyi {
21776af099aSliuyi 	unsigned int i;
21876af099aSliuyi 	for(i = 0; i < g_ConfigItemVec.size(); i++){
21976af099aSliuyi 		if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){
22076af099aSliuyi 			return i;
22176af099aSliuyi 		}
22276af099aSliuyi 	}
22376af099aSliuyi 	return -1;
22476af099aSliuyi }
22576af099aSliuyi 
22676af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
22776af099aSliuyi {
22876af099aSliuyi 
22976af099aSliuyi 	stringstream configStream(pConfig);
23076af099aSliuyi 	string strLine, strItemName, strItemValue;
23176af099aSliuyi 	string::size_type line_size,pos;
23276af099aSliuyi 	STRUCT_CONFIG_ITEM item;
23376af099aSliuyi 	vecItem.clear();
23476af099aSliuyi 	while (!configStream.eof()){
23576af099aSliuyi 		getline(configStream, strLine);
23676af099aSliuyi 		line_size = strLine.size();
23776af099aSliuyi 		if (line_size == 0)
23876af099aSliuyi 			continue;
23976af099aSliuyi 		if (strLine[line_size-1] == '\r'){
24076af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
24176af099aSliuyi 		}
242c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
243c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
244c30d921cSKever Yang 		if (strLine.size()==0 )
245c30d921cSKever Yang 			continue;
246c30d921cSKever Yang 		if (strLine[0] == '#')
247c30d921cSKever Yang 			continue;
24876af099aSliuyi 		pos = strLine.find("=");
24976af099aSliuyi 		if (pos == string::npos){
25076af099aSliuyi 			continue;
25176af099aSliuyi 		}
25276af099aSliuyi 		strItemName = strLine.substr(0, pos);
25376af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
25476af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
25576af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
25676af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
25776af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
25876af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
25976af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
26076af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
26176af099aSliuyi 			vecItem.push_back(item);
26276af099aSliuyi 		}
26376af099aSliuyi 	}
26476af099aSliuyi 	return true;
26576af099aSliuyi 
26676af099aSliuyi }
26776af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
26876af099aSliuyi {
26976af099aSliuyi 	FILE *file = NULL;
27076af099aSliuyi 	file = fopen(pConfigFile, "rb");
27176af099aSliuyi 	if( !file ){
27276af099aSliuyi 		if (g_pLogObject)
27376af099aSliuyi 			g_pLogObject->Record("parse_config_file failed,err=%d,can't open file: %s\r\n", errno, pConfigFile);
27476af099aSliuyi 		return false;
27576af099aSliuyi 	}
27676af099aSliuyi 	int iFileSize;
27776af099aSliuyi 	fseek(file, 0, SEEK_END);
27876af099aSliuyi 	iFileSize = ftell(file);
27976af099aSliuyi 	fseek(file, 0, SEEK_SET);
28076af099aSliuyi 	char *pConfigBuf = NULL;
28176af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
28276af099aSliuyi 	if (!pConfigBuf){
28376af099aSliuyi 		fclose(file);
28476af099aSliuyi 		return false;
28576af099aSliuyi 	}
28676af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
28776af099aSliuyi 	int iRead;
28876af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
28976af099aSliuyi 	if (iRead != iFileSize){
29076af099aSliuyi 		if (g_pLogObject)
29176af099aSliuyi 			g_pLogObject->Record("parse_config_file failed,err=%d, read=%d, total=%d\r\n", errno, iRead, iFileSize);
29276af099aSliuyi 		fclose(file);
29376af099aSliuyi 		delete []pConfigBuf;
29476af099aSliuyi 		return false;
29576af099aSliuyi 	}
29676af099aSliuyi 	fclose(file);
29776af099aSliuyi 	bool bRet;
29876af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
29976af099aSliuyi 	delete []pConfigBuf;
30076af099aSliuyi 	return bRet;
30176af099aSliuyi }
302c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
303c30d921cSKever Yang {
304c30d921cSKever Yang 	string::size_type pos,prevPos;
305c30d921cSKever Yang 	string strOffset,strLen;
306c30d921cSKever Yang 	int iCount;
307c30d921cSKever Yang 	prevPos = pos = 0;
308c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
309c30d921cSKever Yang 		return false;
310c30d921cSKever Yang 	}
311c30d921cSKever Yang 	pos = strPartInfo.find('@');
312c30d921cSKever Yang 	if (pos == string::npos) {
313c30d921cSKever Yang 		return false;
314c30d921cSKever Yang 	}
315c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
316c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
317c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
318c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
319c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
320c30d921cSKever Yang 	} else {
321c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
322c30d921cSKever Yang 		if (iCount != 1) {
323c30d921cSKever Yang 			return false;
324c30d921cSKever Yang 		}
325c30d921cSKever Yang 	}
326c30d921cSKever Yang 
327c30d921cSKever Yang 	prevPos = pos + 1;
328c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
329c30d921cSKever Yang 	if (pos == string::npos) {
330c30d921cSKever Yang 		return false;
331c30d921cSKever Yang 	}
332c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
333c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
334c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
335c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
336c30d921cSKever Yang 	if (iCount != 1) {
337c30d921cSKever Yang 		return false;
338c30d921cSKever Yang 	}
339c30d921cSKever Yang 	prevPos = pos + 1;
340c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
341c30d921cSKever Yang 	if (pos == string::npos) {
342c30d921cSKever Yang 		return false;
343c30d921cSKever Yang 	}
344c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
345c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
346c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
347c30d921cSKever Yang 
348c30d921cSKever Yang 	return true;
349c30d921cSKever Yang }
350c30d921cSKever Yang 
351c30d921cSKever Yang bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem)
352c30d921cSKever Yang {
353c30d921cSKever Yang 	stringstream paramStream(pParameter);
354c30d921cSKever Yang 	bool bRet,bFind = false;
355c30d921cSKever Yang 	string strLine, strPartition, strPartInfo, strPartName;
356c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
357c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
358c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
359c30d921cSKever Yang 	vecItem.clear();
360c30d921cSKever Yang 	while (!paramStream.eof()) {
361c30d921cSKever Yang 		getline(paramStream,strLine);
362c30d921cSKever Yang 		line_size = strLine.size();
363c30d921cSKever Yang 		if (line_size == 0)
364c30d921cSKever Yang 			continue;
365c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
366c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
367c30d921cSKever Yang 		}
368c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
369c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
370c30d921cSKever Yang 		if (strLine.size()==0 )
371c30d921cSKever Yang 			continue;
372c30d921cSKever Yang 		if (strLine[0] == '#')
373c30d921cSKever Yang 			continue;
374c30d921cSKever Yang 		pos = strLine.find("mtdparts");
375c30d921cSKever Yang 		if (pos == string::npos) {
376c30d921cSKever Yang 			continue;
377c30d921cSKever Yang 		}
378c30d921cSKever Yang 		bFind = true;
379c30d921cSKever Yang 		posColon = strLine.find(':', pos);
380c30d921cSKever Yang 		if (posColon == string::npos) {
381c30d921cSKever Yang 			continue;
382c30d921cSKever Yang 		}
383c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
384c30d921cSKever Yang 		pos = 0;
385c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
386c30d921cSKever Yang 		while (posComma != string::npos) {
387c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
388c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
389c30d921cSKever Yang 			if (bRet) {
390c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
391c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
392c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
393c30d921cSKever Yang 				vecItem.push_back(item);
394c30d921cSKever Yang 			}
395c30d921cSKever Yang 			pos = posComma + 1;
396c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
397c30d921cSKever Yang 		}
398c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
399c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
400c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
401c30d921cSKever Yang 			if (bRet) {
402c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
403c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
404c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
405c30d921cSKever Yang 				vecItem.push_back(item);
406c30d921cSKever Yang 			}
407c30d921cSKever Yang 		}
408c30d921cSKever Yang 		break;
409c30d921cSKever Yang 	}
410c30d921cSKever Yang 	return bFind;
411c30d921cSKever Yang 
412c30d921cSKever Yang }
413c30d921cSKever Yang bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem)
414c30d921cSKever Yang {
415c30d921cSKever Yang 	FILE *file = NULL;
416c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
417c30d921cSKever Yang 	if( !file ) {
418c30d921cSKever Yang 		if (g_pLogObject)
419c30d921cSKever Yang 			g_pLogObject->Record("parse_parameter_file failed, err=%d, can't open file: %s\r\n", errno, pParamFile);
420c30d921cSKever Yang 		return false;
421c30d921cSKever Yang 	}
422c30d921cSKever Yang 	int iFileSize;
423c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
424c30d921cSKever Yang 	iFileSize = ftell(file);
425c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
426c30d921cSKever Yang 	char *pParamBuf = NULL;
427c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
428c30d921cSKever Yang 	if (!pParamBuf) {
429c30d921cSKever Yang 		fclose(file);
430c30d921cSKever Yang 		return false;
431c30d921cSKever Yang 	}
432c30d921cSKever Yang 	int iRead;
433c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
434c30d921cSKever Yang 	if (iRead != iFileSize) {
435c30d921cSKever Yang 		if (g_pLogObject)
436c30d921cSKever Yang 			g_pLogObject->Record("parse_parameter_file failed, err=%d, read=%d, total=%d\r\n", errno,iRead,iFileSize);
437c30d921cSKever Yang 		fclose(file);
438c30d921cSKever Yang 		delete []pParamBuf;
439c30d921cSKever Yang 		return false;
440c30d921cSKever Yang 	}
441c30d921cSKever Yang 	fclose(file);
442c30d921cSKever Yang 	bool bRet;
443c30d921cSKever Yang 	bRet = parse_parameter(pParamBuf, vecItem);
444c30d921cSKever Yang 	delete []pParamBuf;
445c30d921cSKever Yang 	return bRet;
446c30d921cSKever Yang }
447c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
448c30d921cSKever Yang {
449c30d921cSKever Yang 	efi_guid_t id;
450c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
451c30d921cSKever Yang 	unsigned int i;
452c30d921cSKever Yang 
453c30d921cSKever Yang 	/* Set all fields randomly */
454c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
455c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
456c30d921cSKever Yang 
457c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
458c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
459c30d921cSKever Yang 
460c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
461c30d921cSKever Yang }
462c30d921cSKever Yang 
463c30d921cSKever Yang void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors)
464c30d921cSKever Yang {
465c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
466c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
467c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
468c30d921cSKever Yang 	u32 i,j;
469c30d921cSKever Yang 	string strPartName;
470c30d921cSKever Yang 	string::size_type colonPos;
471c30d921cSKever Yang 	/*1.protective mbr*/
472c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
473c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
474c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
475c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
476c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
477c30d921cSKever Yang 	/*2.gpt header*/
478c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
479c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
480c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
481c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
482c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
483c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
484c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
485c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
486c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
487c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
488c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
489c30d921cSKever Yang 	gptHead->header_crc32 = 0;
490c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
491c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
492c30d921cSKever Yang 
493c30d921cSKever Yang 	/*3.gpt partition entry*/
494c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
495c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
496c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
497c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
498c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
499c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
500c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
501c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
502c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
503c30d921cSKever Yang 		if (colonPos != string::npos) {
504c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
505c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
506c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
507c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
508c30d921cSKever Yang 		}
509c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
510c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
511c30d921cSKever Yang 		gptEntry++;
512c30d921cSKever Yang 	}
513c30d921cSKever Yang 
514c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
515c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
516c30d921cSKever Yang 
517c30d921cSKever Yang }
518c30d921cSKever Yang bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec)
519c30d921cSKever Yang {
520c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
521c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
522c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
523c30d921cSKever Yang 
524c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
525c30d921cSKever Yang 	pSec0->uiRc4Flag = 1;
526c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
527c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
528c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
529c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
530c30d921cSKever Yang 	return true;
531c30d921cSKever Yang }
532c30d921cSKever Yang 
533c30d921cSKever Yang 
534c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
535c30d921cSKever Yang {
536c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
537c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
538c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
539c30d921cSKever Yang 
540c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
541c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
542c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
543c30d921cSKever Yang 	return true;
544c30d921cSKever Yang }
545c30d921cSKever Yang 
546c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
547c30d921cSKever Yang {
548c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
549c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
550c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
551c30d921cSKever Yang 
552c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
553c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
554c30d921cSKever Yang 	return true;
555c30d921cSKever Yang }
556c30d921cSKever Yang 
557c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
558c30d921cSKever Yang {
559c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
560c30d921cSKever Yang 	return true;
561c30d921cSKever Yang }
562c30d921cSKever Yang 
563c30d921cSKever Yang int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize)
564c30d921cSKever Yang {
565c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
566c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
567c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
568c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
569c30d921cSKever Yang 	UINT i;
570c30d921cSKever Yang 
571c30d921cSKever Yang 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec);
572c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
573c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
574c30d921cSKever Yang 		return -6;
575c30d921cSKever Yang 	}
576c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
577c30d921cSKever Yang 		return -7;
578c30d921cSKever Yang 	}
579c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
580c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
581c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
582c30d921cSKever Yang 
583c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
584c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
585c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
586c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
587c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
588c30d921cSKever Yang 
589c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
590c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
591c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
592c30d921cSKever Yang 		if(i == 1) {
593c30d921cSKever Yang 			continue;
594c30d921cSKever Yang 		} else {
595c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
596c30d921cSKever Yang 		}
597c30d921cSKever Yang 	}
598c30d921cSKever Yang 	return 0;
599c30d921cSKever Yang }
600c30d921cSKever Yang 
601c30d921cSKever Yang 
60276af099aSliuyi 
60376af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
60476af099aSliuyi {
60576af099aSliuyi 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
60676af099aSliuyi 		return true;
60776af099aSliuyi 	else
60876af099aSliuyi 	{
60976af099aSliuyi 		ERROR_COLOR_ATTR;
61076af099aSliuyi 		printf("The  Device did not support this operation!");
61176af099aSliuyi 		NORMAL_COLOR_ATTR;
61276af099aSliuyi 		printf("\r\n");
61376af099aSliuyi 		return false;
61476af099aSliuyi 	}
61576af099aSliuyi }
616c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
617c30d921cSKever Yang {
618c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
619c30d921cSKever Yang 	u32 total_size_sector;
620c30d921cSKever Yang 	CRKComm *pComm = NULL;
621c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
622c30d921cSKever Yang 	int iRet;
623c30d921cSKever Yang 	bool bRet, bSuccess = false;
624c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
625c30d921cSKever Yang 		return false;
626c30d921cSKever Yang 
627c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
628c30d921cSKever Yang 	if (!bRet) {
629c30d921cSKever Yang 		ERROR_COLOR_ATTR;
630c30d921cSKever Yang 		printf("Creating Comm Object failed!");
631c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
632c30d921cSKever Yang 		printf("\r\n");
633c30d921cSKever Yang 		return bSuccess;
634c30d921cSKever Yang 	}
635c30d921cSKever Yang 	printf("Write gpt...\r\n");
636c30d921cSKever Yang 	//1.get flash info
637c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
638c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
639c30d921cSKever Yang 		ERROR_COLOR_ATTR;
640c30d921cSKever Yang 		printf("Reading Flash Info failed!");
641c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
642c30d921cSKever Yang 		printf("\r\n");
643c30d921cSKever Yang 		return bSuccess;
644c30d921cSKever Yang 	}
645c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
646c30d921cSKever Yang 	//2.get partition from parameter
647c30d921cSKever Yang 	bRet = parse_parameter_file(szParameter, vecItems);
648c30d921cSKever Yang 	if (!bRet) {
649c30d921cSKever Yang 		ERROR_COLOR_ATTR;
650c30d921cSKever Yang 		printf("Parsing parameter failed!");
651c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
652c30d921cSKever Yang 		printf("\r\n");
653c30d921cSKever Yang 		return bSuccess;
654c30d921cSKever Yang 	}
655c30d921cSKever Yang 	vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34;
656c30d921cSKever Yang 	//3.generate gpt info
657c30d921cSKever Yang 	create_gpt_buffer(master_gpt, vecItems, total_size_sector);
658c30d921cSKever Yang 	memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
659c30d921cSKever Yang 	memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
660c30d921cSKever Yang 	//4. write gpt
661c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
662c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
663c30d921cSKever Yang 		ERROR_COLOR_ATTR;
664c30d921cSKever Yang 		printf("Writing master gpt failed!");
665c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
666c30d921cSKever Yang 		printf("\r\n");
667c30d921cSKever Yang 		return bSuccess;
668c30d921cSKever Yang 	}
669c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt);
670c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
671c30d921cSKever Yang 		ERROR_COLOR_ATTR;
672c30d921cSKever Yang 		printf("Writing backup gpt failed!");
673c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
674c30d921cSKever Yang 		printf("\r\n");
675c30d921cSKever Yang 		return bSuccess;
676c30d921cSKever Yang 	}
677c30d921cSKever Yang 	bSuccess = true;
678c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
679c30d921cSKever Yang 	CURSOR_DEL_LINE;
680c30d921cSKever Yang 	printf("Write gpt ok.\r\n");
681c30d921cSKever Yang 	return bSuccess;
682c30d921cSKever Yang }
68376af099aSliuyi 
684*78884ef4SEddie Cai #include "boot_merger.h"
685*78884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
686*78884ef4SEddie Cai options gOpts;
687*78884ef4SEddie Cai 
688*78884ef4SEddie Cai 
689*78884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
690*78884ef4SEddie Cai char* gConfigPath;
691*78884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
692*78884ef4SEddie Cai 
693*78884ef4SEddie Cai static inline void fixPath(char* path) {
694*78884ef4SEddie Cai 	int i, len = strlen(path);
695*78884ef4SEddie Cai 	for(i=0; i<len; i++) {
696*78884ef4SEddie Cai 		if (path[i] == '\\')
697*78884ef4SEddie Cai 			path[i] = '/';
698*78884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
699*78884ef4SEddie Cai 			path[i] = '\0';
700*78884ef4SEddie Cai 	}
701*78884ef4SEddie Cai }
702*78884ef4SEddie Cai 
703*78884ef4SEddie Cai static bool parseChip(FILE* file) {
704*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
705*78884ef4SEddie Cai 		return false;
706*78884ef4SEddie Cai 	}
707*78884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
708*78884ef4SEddie Cai 		return false;
709*78884ef4SEddie Cai 	}
710*78884ef4SEddie Cai 	printf("chip:%s\n", gOpts.chip);
711*78884ef4SEddie Cai 	return true;
712*78884ef4SEddie Cai }
713*78884ef4SEddie Cai 
714*78884ef4SEddie Cai static bool parseVersion(FILE* file) {
715*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
716*78884ef4SEddie Cai 		return false;
717*78884ef4SEddie Cai 	}
718*78884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
719*78884ef4SEddie Cai 		return false;
720*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
721*78884ef4SEddie Cai 		return false;
722*78884ef4SEddie Cai 	}
723*78884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
724*78884ef4SEddie Cai 		return false;
725*78884ef4SEddie Cai 	printf("major:%d, minor:%d\n", gOpts.major, gOpts.minor);
726*78884ef4SEddie Cai 	return true;
727*78884ef4SEddie Cai }
728*78884ef4SEddie Cai 
729*78884ef4SEddie Cai static bool parse471(FILE* file) {
730*78884ef4SEddie Cai 	int i, index, pos;
731*78884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
732*78884ef4SEddie Cai 
733*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
734*78884ef4SEddie Cai 		return false;
735*78884ef4SEddie Cai 	}
736*78884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
737*78884ef4SEddie Cai 		return false;
738*78884ef4SEddie Cai 	printf("num:%d\n", gOpts.code471Num);
739*78884ef4SEddie Cai 	if (!gOpts.code471Num)
740*78884ef4SEddie Cai 		return true;
741*78884ef4SEddie Cai 	if (gOpts.code471Num < 0)
742*78884ef4SEddie Cai 		return false;
743*78884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
744*78884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
745*78884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
746*78884ef4SEddie Cai 			return false;
747*78884ef4SEddie Cai 		}
748*78884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
749*78884ef4SEddie Cai 				!= 2)
750*78884ef4SEddie Cai 			return false;
751*78884ef4SEddie Cai 		index--;
752*78884ef4SEddie Cai 		fixPath(buf);
753*78884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
754*78884ef4SEddie Cai 		printf("path%i:%s\n", index, gOpts.code471Path[index]);
755*78884ef4SEddie Cai 	}
756*78884ef4SEddie Cai 	pos = ftell(file);
757*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
758*78884ef4SEddie Cai 		return false;
759*78884ef4SEddie Cai 	}
760*78884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
761*78884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
762*78884ef4SEddie Cai 	printf("sleep:%d\n", gOpts.code471Sleep);
763*78884ef4SEddie Cai 	return true;
764*78884ef4SEddie Cai }
765*78884ef4SEddie Cai 
766*78884ef4SEddie Cai static bool parse472(FILE* file) {
767*78884ef4SEddie Cai 	int i, index, pos;
768*78884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
769*78884ef4SEddie Cai 
770*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
771*78884ef4SEddie Cai 		return false;
772*78884ef4SEddie Cai 	}
773*78884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
774*78884ef4SEddie Cai 		return false;
775*78884ef4SEddie Cai 	printf("num:%d\n", gOpts.code472Num);
776*78884ef4SEddie Cai 	if (!gOpts.code472Num)
777*78884ef4SEddie Cai 		return true;
778*78884ef4SEddie Cai 	if (gOpts.code472Num < 0)
779*78884ef4SEddie Cai 		return false;
780*78884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
781*78884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
782*78884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
783*78884ef4SEddie Cai 			return false;
784*78884ef4SEddie Cai 		}
785*78884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
786*78884ef4SEddie Cai 				!= 2)
787*78884ef4SEddie Cai 			return false;
788*78884ef4SEddie Cai 		fixPath(buf);
789*78884ef4SEddie Cai 		index--;
790*78884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
791*78884ef4SEddie Cai 		printf("path%i:%s\n", index, gOpts.code472Path[index]);
792*78884ef4SEddie Cai 	}
793*78884ef4SEddie Cai 	pos = ftell(file);
794*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
795*78884ef4SEddie Cai 		return false;
796*78884ef4SEddie Cai 	}
797*78884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
798*78884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
799*78884ef4SEddie Cai 	printf("sleep:%d\n", gOpts.code472Sleep);
800*78884ef4SEddie Cai 	return true;
801*78884ef4SEddie Cai }
802*78884ef4SEddie Cai 
803*78884ef4SEddie Cai static bool parseLoader(FILE* file) {
804*78884ef4SEddie Cai 	int i, j, index, pos;
805*78884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
806*78884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
807*78884ef4SEddie Cai 
808*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
809*78884ef4SEddie Cai 		return false;
810*78884ef4SEddie Cai 	}
811*78884ef4SEddie Cai 	pos = ftell(file);
812*78884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
813*78884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
814*78884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
815*78884ef4SEddie Cai 			return false;
816*78884ef4SEddie Cai 		}
817*78884ef4SEddie Cai 	}
818*78884ef4SEddie Cai 	printf("num:%d\n", gOpts.loaderNum);
819*78884ef4SEddie Cai 	if (!gOpts.loaderNum)
820*78884ef4SEddie Cai 		return false;
821*78884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
822*78884ef4SEddie Cai 		return false;
823*78884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
824*78884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
825*78884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
826*78884ef4SEddie Cai 			return false;
827*78884ef4SEddie Cai 		}
828*78884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
829*78884ef4SEddie Cai 				!= 2)
830*78884ef4SEddie Cai 			return false;
831*78884ef4SEddie Cai 		index--;
832*78884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
833*78884ef4SEddie Cai 		printf("name%d:%s\n", index, gOpts.loader[index].name);
834*78884ef4SEddie Cai 	}
835*78884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
836*78884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
837*78884ef4SEddie Cai 			return false;
838*78884ef4SEddie Cai 		}
839*78884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
840*78884ef4SEddie Cai 				!= 2)
841*78884ef4SEddie Cai 			return false;
842*78884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
843*78884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
844*78884ef4SEddie Cai 				fixPath(buf2);
845*78884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
846*78884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
847*78884ef4SEddie Cai 				break;
848*78884ef4SEddie Cai 			}
849*78884ef4SEddie Cai 		}
850*78884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
851*78884ef4SEddie Cai 			return false;
852*78884ef4SEddie Cai 		}
853*78884ef4SEddie Cai 	}
854*78884ef4SEddie Cai 	return true;
855*78884ef4SEddie Cai }
856*78884ef4SEddie Cai 
857*78884ef4SEddie Cai static bool parseOut(FILE* file) {
858*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
859*78884ef4SEddie Cai 		return false;
860*78884ef4SEddie Cai 	}
861*78884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
862*78884ef4SEddie Cai 		return false;
863*78884ef4SEddie Cai 	fixPath(gOpts.outPath);
864*78884ef4SEddie Cai 	printf("out:%s\n", gOpts.outPath);
865*78884ef4SEddie Cai 	return true;
866*78884ef4SEddie Cai }
867*78884ef4SEddie Cai 
868*78884ef4SEddie Cai 
869*78884ef4SEddie Cai void printOpts(FILE* out) {
870*78884ef4SEddie Cai 	int i;
871*78884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
872*78884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
873*78884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
874*78884ef4SEddie Cai 
875*78884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
876*78884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
877*78884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
878*78884ef4SEddie Cai 	}
879*78884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
880*78884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
881*78884ef4SEddie Cai 
882*78884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
883*78884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
884*78884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
885*78884ef4SEddie Cai 	}
886*78884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
887*78884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
888*78884ef4SEddie Cai 
889*78884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
890*78884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
891*78884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
892*78884ef4SEddie Cai 	}
893*78884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
894*78884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
895*78884ef4SEddie Cai 	}
896*78884ef4SEddie Cai 
897*78884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
898*78884ef4SEddie Cai }
899*78884ef4SEddie Cai 
900*78884ef4SEddie Cai static bool parseOpts(void) {
901*78884ef4SEddie Cai 	bool ret = false;
902*78884ef4SEddie Cai 	bool chipOk = false;
903*78884ef4SEddie Cai 	bool versionOk = false;
904*78884ef4SEddie Cai 	bool code471Ok = true;
905*78884ef4SEddie Cai 	bool code472Ok = true;
906*78884ef4SEddie Cai 	bool loaderOk = false;
907*78884ef4SEddie Cai 	bool outOk = false;
908*78884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
909*78884ef4SEddie Cai 
910*78884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
911*78884ef4SEddie Cai 	FILE* file;
912*78884ef4SEddie Cai 	file = fopen(configPath, "r");
913*78884ef4SEddie Cai 	if (!file) {
914*78884ef4SEddie Cai 		fprintf(stderr, "config(%s) not found!\n", configPath);
915*78884ef4SEddie Cai 		if (configPath == (char*)DEF_CONFIG_FILE) {
916*78884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
917*78884ef4SEddie Cai 			if (file) {
918*78884ef4SEddie Cai 				fprintf(stderr, "create defconfig\n");
919*78884ef4SEddie Cai 				printOpts(file);
920*78884ef4SEddie Cai 			}
921*78884ef4SEddie Cai 		}
922*78884ef4SEddie Cai 		goto end;
923*78884ef4SEddie Cai 	}
924*78884ef4SEddie Cai 
925*78884ef4SEddie Cai 	printf("start parse\n");
926*78884ef4SEddie Cai 
927*78884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
928*78884ef4SEddie Cai 		goto end;
929*78884ef4SEddie Cai 	}
930*78884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
931*78884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
932*78884ef4SEddie Cai 			chipOk = parseChip(file);
933*78884ef4SEddie Cai 			if (!chipOk) {
934*78884ef4SEddie Cai 				printf("parseChip failed!\n");
935*78884ef4SEddie Cai 				goto end;
936*78884ef4SEddie Cai 			}
937*78884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
938*78884ef4SEddie Cai 			versionOk = parseVersion(file);
939*78884ef4SEddie Cai 			if (!versionOk) {
940*78884ef4SEddie Cai 				printf("parseVersion failed!\n");
941*78884ef4SEddie Cai 				goto end;
942*78884ef4SEddie Cai 			}
943*78884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
944*78884ef4SEddie Cai 			code471Ok = parse471(file);
945*78884ef4SEddie Cai 			if (!code471Ok) {
946*78884ef4SEddie Cai 				printf("parse471 failed!\n");
947*78884ef4SEddie Cai 				goto end;
948*78884ef4SEddie Cai 			}
949*78884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
950*78884ef4SEddie Cai 			code472Ok = parse472(file);
951*78884ef4SEddie Cai 			if (!code472Ok) {
952*78884ef4SEddie Cai 				printf("parse472 failed!\n");
953*78884ef4SEddie Cai 				goto end;
954*78884ef4SEddie Cai 			}
955*78884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
956*78884ef4SEddie Cai 			loaderOk = parseLoader(file);
957*78884ef4SEddie Cai 			if (!loaderOk) {
958*78884ef4SEddie Cai 				printf("parseLoader failed!\n");
959*78884ef4SEddie Cai 				goto end;
960*78884ef4SEddie Cai 			}
961*78884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
962*78884ef4SEddie Cai 			outOk = parseOut(file);
963*78884ef4SEddie Cai 			if (!outOk) {
964*78884ef4SEddie Cai 				printf("parseOut failed!\n");
965*78884ef4SEddie Cai 				goto end;
966*78884ef4SEddie Cai 			}
967*78884ef4SEddie Cai 		} else if (buf[0] == '#') {
968*78884ef4SEddie Cai 			continue;
969*78884ef4SEddie Cai 		} else {
970*78884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
971*78884ef4SEddie Cai 			goto end;
972*78884ef4SEddie Cai 		}
973*78884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
974*78884ef4SEddie Cai 			goto end;
975*78884ef4SEddie Cai 		}
976*78884ef4SEddie Cai 	}
977*78884ef4SEddie Cai 
978*78884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
979*78884ef4SEddie Cai 			&& loaderOk && outOk)
980*78884ef4SEddie Cai 		ret = true;
981*78884ef4SEddie Cai end:
982*78884ef4SEddie Cai 	if (file)
983*78884ef4SEddie Cai 		fclose(file);
984*78884ef4SEddie Cai 	return ret;
985*78884ef4SEddie Cai }
986*78884ef4SEddie Cai 
987*78884ef4SEddie Cai bool initOpts(void) {
988*78884ef4SEddie Cai 	//set default opts
989*78884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
990*78884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
991*78884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
992*78884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
993*78884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
994*78884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
995*78884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
996*78884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
997*78884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
998*78884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
999*78884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
1000*78884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
1001*78884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
1002*78884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
1003*78884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
1004*78884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
1005*78884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
1006*78884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
1007*78884ef4SEddie Cai 
1008*78884ef4SEddie Cai 	return parseOpts();
1009*78884ef4SEddie Cai }
1010*78884ef4SEddie Cai 
1011*78884ef4SEddie Cai /************merge code****************/
1012*78884ef4SEddie Cai 
1013*78884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
1014*78884ef4SEddie Cai 	uint8_t tmp[2] = {0};
1015*78884ef4SEddie Cai 	int i;
1016*78884ef4SEddie Cai 	uint32_t ret;
1017*78884ef4SEddie Cai 	//if (value > 0xFFFF) {
1018*78884ef4SEddie Cai 	//	return 0;
1019*78884ef4SEddie Cai 	//}
1020*78884ef4SEddie Cai 	for(i=0; i < 2; i++) {
1021*78884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
1022*78884ef4SEddie Cai 		value /= 100;
1023*78884ef4SEddie Cai 	}
1024*78884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
1025*78884ef4SEddie Cai 
1026*78884ef4SEddie Cai 	printf("ret:%x\n",ret);
1027*78884ef4SEddie Cai 	return ret&0xFF;
1028*78884ef4SEddie Cai }
1029*78884ef4SEddie Cai 
1030*78884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
1031*78884ef4SEddie Cai {
1032*78884ef4SEddie Cai 	int i;
1033*78884ef4SEddie Cai 	for (i = 0; i < len; i++) {
1034*78884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
1035*78884ef4SEddie Cai 	}
1036*78884ef4SEddie Cai 	wide[len] = 0;
1037*78884ef4SEddie Cai }
1038*78884ef4SEddie Cai 
1039*78884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
1040*78884ef4SEddie Cai 	char* end;
1041*78884ef4SEddie Cai 	char* start;
1042*78884ef4SEddie Cai 	int len;
1043*78884ef4SEddie Cai 	if (!path || !dst)
1044*78884ef4SEddie Cai 		return;
1045*78884ef4SEddie Cai 	start = strrchr(path, '/');
1046*78884ef4SEddie Cai 	if (!start)
1047*78884ef4SEddie Cai 		start = path;
1048*78884ef4SEddie Cai 	else
1049*78884ef4SEddie Cai 		start++;
1050*78884ef4SEddie Cai 	end = strrchr(path, '.');
1051*78884ef4SEddie Cai 	if (!end)
1052*78884ef4SEddie Cai 		end = path + strlen(path);
1053*78884ef4SEddie Cai 	len = end - start;
1054*78884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
1055*78884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
1056*78884ef4SEddie Cai 	str2wide(start, dst, len);
1057*78884ef4SEddie Cai 
1058*78884ef4SEddie Cai 
1059*78884ef4SEddie Cai 		char name[MAX_NAME_LEN];
1060*78884ef4SEddie Cai 		memset(name, 0, sizeof(name));
1061*78884ef4SEddie Cai 		memcpy(name, start, len);
1062*78884ef4SEddie Cai 		printf("path:%s, name:%s\n", path, name);
1063*78884ef4SEddie Cai 
1064*78884ef4SEddie Cai }
1065*78884ef4SEddie Cai 
1066*78884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
1067*78884ef4SEddie Cai 	struct stat st;
1068*78884ef4SEddie Cai 	if(stat(path, &st) < 0)
1069*78884ef4SEddie Cai 		return false;
1070*78884ef4SEddie Cai 	*size = st.st_size;
1071*78884ef4SEddie Cai 	printf("path:%s, size:%d\n", path, *size);
1072*78884ef4SEddie Cai 	return true;
1073*78884ef4SEddie Cai }
1074*78884ef4SEddie Cai 
1075*78884ef4SEddie Cai static inline rk_time getTime(void) {
1076*78884ef4SEddie Cai 	rk_time rkTime;
1077*78884ef4SEddie Cai 
1078*78884ef4SEddie Cai 	struct tm *tm;
1079*78884ef4SEddie Cai 	time_t tt = time(NULL);
1080*78884ef4SEddie Cai 	tm = localtime(&tt);
1081*78884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
1082*78884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
1083*78884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
1084*78884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
1085*78884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
1086*78884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
1087*78884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
1088*78884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
1089*78884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
1090*78884ef4SEddie Cai 	return rkTime;
1091*78884ef4SEddie Cai }
1092*78884ef4SEddie Cai 
1093*78884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
1094*78884ef4SEddie Cai 	bool ret = false;
1095*78884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
1096*78884ef4SEddie Cai 	uint8_t* buf;
1097*78884ef4SEddie Cai 
1098*78884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
1099*78884ef4SEddie Cai 	if (!inFile)
1100*78884ef4SEddie Cai 		goto end;
1101*78884ef4SEddie Cai 
1102*78884ef4SEddie Cai 	if (!getFileSize(path, &size))
1103*78884ef4SEddie Cai 		goto end;
1104*78884ef4SEddie Cai 	if (fix) {
1105*78884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
1106*78884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
1107*78884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
1108*78884ef4SEddie Cai 		fixSize +=tmp;
1109*78884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
1110*78884ef4SEddie Cai 	} else {
1111*78884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
1112*78884ef4SEddie Cai 	}
1113*78884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
1114*78884ef4SEddie Cai 		goto end;
1115*78884ef4SEddie Cai 
1116*78884ef4SEddie Cai 	if (fix) {
1117*78884ef4SEddie Cai 
1118*78884ef4SEddie Cai 		buf = gBuf;
1119*78884ef4SEddie Cai 		size = fixSize;
1120*78884ef4SEddie Cai 		while(1) {
1121*78884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
1122*78884ef4SEddie Cai 			buf += SMALL_PACKET;
1123*78884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
1124*78884ef4SEddie Cai 				break;
1125*78884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
1126*78884ef4SEddie Cai 		}
1127*78884ef4SEddie Cai 	} else {
1128*78884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
1129*78884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
1130*78884ef4SEddie Cai 		size +=tmp;
1131*78884ef4SEddie Cai 		P_RC4(gBuf, size);
1132*78884ef4SEddie Cai 	}
1133*78884ef4SEddie Cai 
1134*78884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
1135*78884ef4SEddie Cai 		goto end;
1136*78884ef4SEddie Cai 	ret = true;
1137*78884ef4SEddie Cai end:
1138*78884ef4SEddie Cai 	if (inFile)
1139*78884ef4SEddie Cai 		fclose(inFile);
1140*78884ef4SEddie Cai 	if (!ret)
1141*78884ef4SEddie Cai 		printf("write entry(%s) failed\n", path);
1142*78884ef4SEddie Cai 	return ret;
1143*78884ef4SEddie Cai }
1144*78884ef4SEddie Cai 
1145*78884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
1146*78884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
1147*78884ef4SEddie Cai 	printf("write:%s\n", path);
1148*78884ef4SEddie Cai 	uint32_t size;
1149*78884ef4SEddie Cai 	rk_boot_entry entry;
1150*78884ef4SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
1151*78884ef4SEddie Cai 
1152*78884ef4SEddie Cai 	printf("write:%s\n", path);
1153*78884ef4SEddie Cai 
1154*78884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
1155*78884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
1156*78884ef4SEddie Cai 	entry.type = type;
1157*78884ef4SEddie Cai 	entry.dataOffset = *offset;
1158*78884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
1159*78884ef4SEddie Cai 		printf("save entry(%s) failed:\n\tcannot get file size.\n", path);
1160*78884ef4SEddie Cai 		return false;
1161*78884ef4SEddie Cai 	}
1162*78884ef4SEddie Cai 	if (fix)
1163*78884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
1164*78884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
1165*78884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
1166*78884ef4SEddie Cai 	printf("align size:%d\n", size);
1167*78884ef4SEddie Cai 	entry.dataSize = size;
1168*78884ef4SEddie Cai 	entry.dataDelay = delay;
1169*78884ef4SEddie Cai 	*offset += size;
1170*78884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
1171*78884ef4SEddie Cai 	return true;
1172*78884ef4SEddie Cai }
1173*78884ef4SEddie Cai 
1174*78884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
1175*78884ef4SEddie Cai 	char buffer[5];
1176*78884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
1177*78884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
1178*78884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
1179*78884ef4SEddie Cai }
1180*78884ef4SEddie Cai 
1181*78884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
1182*78884ef4SEddie Cai 	printf("chip:%s\n", chip);
1183*78884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
1184*78884ef4SEddie Cai 	if(!chip) {
1185*78884ef4SEddie Cai 		goto end;
1186*78884ef4SEddie Cai 	}
1187*78884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
1188*78884ef4SEddie Cai 		chipType = RK28_DEVICE;
1189*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
1190*78884ef4SEddie Cai 		chipType = RK28_DEVICE;
1191*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
1192*78884ef4SEddie Cai 		chipType = RK281X_DEVICE;
1193*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
1194*78884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
1195*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
1196*78884ef4SEddie Cai 		chipType = RK27_DEVICE;
1197*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
1198*78884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
1199*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
1200*78884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
1201*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
1202*78884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
1203*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
1204*78884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
1205*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
1206*78884ef4SEddie Cai 		chipType = RK29_DEVICE;
1207*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
1208*78884ef4SEddie Cai 		chipType = RK292X_DEVICE;
1209*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
1210*78884ef4SEddie Cai 		chipType = RK30_DEVICE;
1211*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
1212*78884ef4SEddie Cai 		chipType = RK30B_DEVICE;
1213*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
1214*78884ef4SEddie Cai 		chipType = RK31_DEVICE;
1215*78884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
1216*78884ef4SEddie Cai 		chipType = RK32_DEVICE;
1217*78884ef4SEddie Cai 	} else {
1218*78884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
1219*78884ef4SEddie Cai 	}
1220*78884ef4SEddie Cai 
1221*78884ef4SEddie Cai end:
1222*78884ef4SEddie Cai 	printf("type:0x%x\n", chipType);
1223*78884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
1224*78884ef4SEddie Cai 		printf("chip type not support!\n");
1225*78884ef4SEddie Cai 	}
1226*78884ef4SEddie Cai 	return chipType;
1227*78884ef4SEddie Cai }
1228*78884ef4SEddie Cai 
1229*78884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
1230*78884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
1231*78884ef4SEddie Cai 	hdr->tag = TAG;
1232*78884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
1233*78884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
1234*78884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
1235*78884ef4SEddie Cai 	hdr->releaseTime = getTime();
1236*78884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
1237*78884ef4SEddie Cai 
1238*78884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
1239*78884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
1240*78884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
1241*78884ef4SEddie Cai 
1242*78884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
1243*78884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
1244*78884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
1245*78884ef4SEddie Cai 
1246*78884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
1247*78884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
1248*78884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
1249*78884ef4SEddie Cai #ifndef USE_P_RC4
1250*78884ef4SEddie Cai 	hdr->rc4Flag = 1;
1251*78884ef4SEddie Cai #endif
1252*78884ef4SEddie Cai }
1253*78884ef4SEddie Cai 
1254*78884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
1255*78884ef4SEddie Cai 	uint32_t size = 0;
1256*78884ef4SEddie Cai 	uint32_t crc = 0;
1257*78884ef4SEddie Cai 
1258*78884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
1259*78884ef4SEddie Cai 	getFileSize(path, &size);
1260*78884ef4SEddie Cai 	if (!file)
1261*78884ef4SEddie Cai 		goto end;
1262*78884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
1263*78884ef4SEddie Cai 		goto end;
1264*78884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
1265*78884ef4SEddie Cai 	printf("crc:0x%08x\n", crc);
1266*78884ef4SEddie Cai end:
1267*78884ef4SEddie Cai 	if (file)
1268*78884ef4SEddie Cai 		fclose(file);
1269*78884ef4SEddie Cai 	return crc;
1270*78884ef4SEddie Cai }
1271*78884ef4SEddie Cai 
1272*78884ef4SEddie Cai bool mergeBoot(void) {
1273*78884ef4SEddie Cai 	uint32_t dataOffset;
1274*78884ef4SEddie Cai 	bool ret = false;
1275*78884ef4SEddie Cai 	int i;
1276*78884ef4SEddie Cai 	FILE* outFile;
1277*78884ef4SEddie Cai 	uint32_t crc;
1278*78884ef4SEddie Cai 	rk_boot_header hdr;
1279*78884ef4SEddie Cai 
1280*78884ef4SEddie Cai 	if (!initOpts())
1281*78884ef4SEddie Cai 		return false;
1282*78884ef4SEddie Cai 	{
1283*78884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
1284*78884ef4SEddie Cai 		char version[MAX_LINE_LEN];
1285*78884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
1286*78884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
1287*78884ef4SEddie Cai 			subfix[0] = '\0';
1288*78884ef4SEddie Cai 		}
1289*78884ef4SEddie Cai 		strcat(gOpts.outPath, version);
1290*78884ef4SEddie Cai 		printf("fix opt:%s\n", gOpts.outPath);
1291*78884ef4SEddie Cai 	}
1292*78884ef4SEddie Cai 
1293*78884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
1294*78884ef4SEddie Cai 	printOpts(stdout);
1295*78884ef4SEddie Cai 	printf("---------------\n\n");
1296*78884ef4SEddie Cai 
1297*78884ef4SEddie Cai 
1298*78884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
1299*78884ef4SEddie Cai 	if (!outFile) {
1300*78884ef4SEddie Cai 		printf("open out file(%s) failed\n", gOpts.outPath);
1301*78884ef4SEddie Cai 		goto end;
1302*78884ef4SEddie Cai 	}
1303*78884ef4SEddie Cai 
1304*78884ef4SEddie Cai 	getBoothdr(&hdr);
1305*78884ef4SEddie Cai 	printf("write hdr\n");
1306*78884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
1307*78884ef4SEddie Cai 
1308*78884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
1309*78884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
1310*78884ef4SEddie Cai 		sizeof(rk_boot_entry);
1311*78884ef4SEddie Cai 
1312*78884ef4SEddie Cai 	printf("write code 471 entry\n");
1313*78884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
1314*78884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
1315*78884ef4SEddie Cai 					&dataOffset, NULL, false))
1316*78884ef4SEddie Cai 			goto end;
1317*78884ef4SEddie Cai 	}
1318*78884ef4SEddie Cai 	printf("write code 472 entry\n");
1319*78884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
1320*78884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
1321*78884ef4SEddie Cai 					&dataOffset, NULL, false))
1322*78884ef4SEddie Cai 			goto end;
1323*78884ef4SEddie Cai 	}
1324*78884ef4SEddie Cai 	printf("write loader entry\n");
1325*78884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
1326*78884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
1327*78884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
1328*78884ef4SEddie Cai 			goto end;
1329*78884ef4SEddie Cai 	}
1330*78884ef4SEddie Cai 
1331*78884ef4SEddie Cai 	printf("write code 471\n");
1332*78884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
1333*78884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
1334*78884ef4SEddie Cai 			goto end;
1335*78884ef4SEddie Cai 	}
1336*78884ef4SEddie Cai 	printf("write code 472\n");
1337*78884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
1338*78884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
1339*78884ef4SEddie Cai 			goto end;
1340*78884ef4SEddie Cai 	}
1341*78884ef4SEddie Cai 	printf("write loader\n");
1342*78884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
1343*78884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
1344*78884ef4SEddie Cai 			goto end;
1345*78884ef4SEddie Cai 	}
1346*78884ef4SEddie Cai 	fflush(outFile);
1347*78884ef4SEddie Cai 
1348*78884ef4SEddie Cai 	printf("write crc\n");
1349*78884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
1350*78884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
1351*78884ef4SEddie Cai 		goto end;
1352*78884ef4SEddie Cai 	printf("done\n");
1353*78884ef4SEddie Cai 	ret = true;
1354*78884ef4SEddie Cai end:
1355*78884ef4SEddie Cai 	if (outFile)
1356*78884ef4SEddie Cai 		fclose(outFile);
1357*78884ef4SEddie Cai 	return ret;
1358*78884ef4SEddie Cai }
1359*78884ef4SEddie Cai 
1360*78884ef4SEddie Cai /************merge code end************/
1361*78884ef4SEddie Cai /************unpack code***************/
1362*78884ef4SEddie Cai 
1363*78884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
1364*78884ef4SEddie Cai {
1365*78884ef4SEddie Cai 	int i;
1366*78884ef4SEddie Cai 	for (i = 0; i < len; i++) {
1367*78884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
1368*78884ef4SEddie Cai 	}
1369*78884ef4SEddie Cai 	str[len] = 0;
1370*78884ef4SEddie Cai }
1371*78884ef4SEddie Cai 
1372*78884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
1373*78884ef4SEddie Cai 		FILE* inFile) {
1374*78884ef4SEddie Cai 	bool ret = false;
1375*78884ef4SEddie Cai 	int size, i;
1376*78884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
1377*78884ef4SEddie Cai 	if (!outFile)
1378*78884ef4SEddie Cai 		goto end;
1379*78884ef4SEddie Cai 	printf("unpack entry(%s)\n", name);
1380*78884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
1381*78884ef4SEddie Cai 	size = entry->dataSize;
1382*78884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
1383*78884ef4SEddie Cai 		goto end;
1384*78884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
1385*78884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
1386*78884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
1387*78884ef4SEddie Cai 		if (size % SMALL_PACKET)
1388*78884ef4SEddie Cai 		{
1389*78884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
1390*78884ef4SEddie Cai 		}
1391*78884ef4SEddie Cai 	} else {
1392*78884ef4SEddie Cai 		P_RC4(gBuf, size);
1393*78884ef4SEddie Cai 	}
1394*78884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
1395*78884ef4SEddie Cai 		goto end;
1396*78884ef4SEddie Cai 	ret = true;
1397*78884ef4SEddie Cai end:
1398*78884ef4SEddie Cai 	if (outFile)
1399*78884ef4SEddie Cai 		fclose(outFile);
1400*78884ef4SEddie Cai 	return ret;
1401*78884ef4SEddie Cai }
1402*78884ef4SEddie Cai 
1403*78884ef4SEddie Cai bool unpackBoot(char* path) {
1404*78884ef4SEddie Cai 	bool ret = false;
1405*78884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
1406*78884ef4SEddie Cai 	int entryNum, i;
1407*78884ef4SEddie Cai 	char name[MAX_NAME_LEN];
1408*78884ef4SEddie Cai 	rk_boot_entry* entrys;
1409*78884ef4SEddie Cai 	if (!inFile) {
1410*78884ef4SEddie Cai 		fprintf(stderr, "loader(%s) not found\n", path);
1411*78884ef4SEddie Cai 		goto end;
1412*78884ef4SEddie Cai 	}
1413*78884ef4SEddie Cai 
1414*78884ef4SEddie Cai 	rk_boot_header hdr;
1415*78884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
1416*78884ef4SEddie Cai 		fprintf(stderr, "read header failed\n");
1417*78884ef4SEddie Cai 		goto end;
1418*78884ef4SEddie Cai 	}
1419*78884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
1420*78884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
1421*78884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
1422*78884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
1423*78884ef4SEddie Cai 		fprintf(stderr, "read data failed\n");
1424*78884ef4SEddie Cai 		goto end;
1425*78884ef4SEddie Cai 	}
1426*78884ef4SEddie Cai 
1427*78884ef4SEddie Cai 	printf("entry num:%d\n", entryNum);
1428*78884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
1429*78884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
1430*78884ef4SEddie Cai 
1431*78884ef4SEddie Cai 		printf("entry:t=%d, name=%s, off=%d, size=%d\n",
1432*78884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
1433*78884ef4SEddie Cai 				entrys[i].dataSize);
1434*78884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
1435*78884ef4SEddie Cai 			fprintf(stderr, "unpack entry(%s) failed\n", name);
1436*78884ef4SEddie Cai 			goto end;
1437*78884ef4SEddie Cai 		}
1438*78884ef4SEddie Cai 	}
1439*78884ef4SEddie Cai 	printf("done\n");
1440*78884ef4SEddie Cai 	ret = true;
1441*78884ef4SEddie Cai end:
1442*78884ef4SEddie Cai 	if (inFile)
1443*78884ef4SEddie Cai 		fclose(inFile);
1444*78884ef4SEddie Cai 	return ret;
1445*78884ef4SEddie Cai }
1446*78884ef4SEddie Cai 
144776af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
144876af099aSliuyi {
144976af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
145076af099aSliuyi 		return false;
145176af099aSliuyi 	CRKImage *pImage = NULL;
145276af099aSliuyi 	CRKBoot *pBoot = NULL;
145376af099aSliuyi 	bool bRet, bSuccess = false;
145476af099aSliuyi 	int iRet;
145576af099aSliuyi 
145676af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
145776af099aSliuyi 	if (!bRet){
145876af099aSliuyi 		ERROR_COLOR_ATTR;
145976af099aSliuyi 		printf("Open loader failed,exit download boot!");
146076af099aSliuyi 		NORMAL_COLOR_ATTR;
146176af099aSliuyi 		printf("\r\n");
146276af099aSliuyi 		return bSuccess;
146376af099aSliuyi 	} else {
146476af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
146576af099aSliuyi 		CRKComm *pComm = NULL;
146676af099aSliuyi 		CRKDevice *pDevice = NULL;
146776af099aSliuyi 
146876af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
146976af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
147076af099aSliuyi 		if (!bRet) {
147176af099aSliuyi 			if (pImage)
147276af099aSliuyi 				delete pImage;
147376af099aSliuyi 			ERROR_COLOR_ATTR;
147476af099aSliuyi 			printf("Creating Comm Object failed!");
147576af099aSliuyi 			NORMAL_COLOR_ATTR;
147676af099aSliuyi 			printf("\r\n");
147776af099aSliuyi 			return bSuccess;
147876af099aSliuyi 		}
147976af099aSliuyi 
148076af099aSliuyi 		pDevice = new CRKDevice(dev);
148176af099aSliuyi 		if (!pDevice) {
148276af099aSliuyi 			if (pImage)
148376af099aSliuyi 				delete pImage;
148476af099aSliuyi 			if (pComm)
148576af099aSliuyi 				delete pComm;
148676af099aSliuyi 			ERROR_COLOR_ATTR;
148776af099aSliuyi 			printf("Creating device object failed!");
148876af099aSliuyi 			NORMAL_COLOR_ATTR;
148976af099aSliuyi 			printf("\r\n");
149076af099aSliuyi 			return bSuccess;
149176af099aSliuyi 		}
149276af099aSliuyi 
149376af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
149476af099aSliuyi 		printf("Download boot...\r\n");
149576af099aSliuyi 		iRet = pDevice->DownloadBoot();
149676af099aSliuyi 
149776af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
149876af099aSliuyi 		CURSOR_DEL_LINE;
149976af099aSliuyi 		if (iRet == 0) {
150076af099aSliuyi 			pComm->Reset_Usb_Device();
150176af099aSliuyi 			CRKScan *pScan = NULL;
150276af099aSliuyi 			pScan = new CRKScan();
150376af099aSliuyi 			if (pScan) {
150476af099aSliuyi 				pScan->SetVidPid();
150576af099aSliuyi 				pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
150676af099aSliuyi 				delete pScan;
150776af099aSliuyi 			}
150876af099aSliuyi 			bSuccess = true;
150976af099aSliuyi 			printf("Download boot ok.\r\n");
151076af099aSliuyi 		}
151176af099aSliuyi 		else
151276af099aSliuyi 			printf("Download boot failed!\r\n");
151376af099aSliuyi 
151476af099aSliuyi 		if (pImage)
151576af099aSliuyi 			delete pImage;
151676af099aSliuyi 		if(pDevice)
151776af099aSliuyi 			delete pDevice;
151876af099aSliuyi 	}
151976af099aSliuyi 	return bSuccess;
152076af099aSliuyi }
1521c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1522c30d921cSKever Yang {
1523c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1524c30d921cSKever Yang 		return false;
1525c30d921cSKever Yang 	CRKImage *pImage = NULL;
1526c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1527c30d921cSKever Yang 	CRKComm *pComm = NULL;
1528c30d921cSKever Yang 	bool bRet, bSuccess = false;
1529c30d921cSKever Yang 	int iRet;
1530c30d921cSKever Yang 	char index;
1531c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1532c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1533c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1534c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1535c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1536c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1537c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1538c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1539c30d921cSKever Yang 	if (!bRet){
1540c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1541c30d921cSKever Yang 		printf("Open loader failed,exit upgrade loader!");
1542c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1543c30d921cSKever Yang 		printf("\r\n");
1544c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1545c30d921cSKever Yang 	} else {
1546c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1547c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1548c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1549c30d921cSKever Yang 		if (!bRet) {
1550c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1551c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1552c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1553c30d921cSKever Yang 			printf("\r\n");
1554c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1555c30d921cSKever Yang 		}
1556c30d921cSKever Yang 
1557c30d921cSKever Yang 		printf("Upgrade loader...\r\n");
1558c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1559c30d921cSKever Yang 		if (index == -1) {
1560c30d921cSKever Yang 			if (g_pLogObject) {
1561c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed");
1562c30d921cSKever Yang 			}
1563c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1564c30d921cSKever Yang 		}
1565c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1566c30d921cSKever Yang 		if (!bRet) {
1567c30d921cSKever Yang 			if (g_pLogObject) {
1568c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed");
1569c30d921cSKever Yang 			}
1570c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1571c30d921cSKever Yang 		}
1572c30d921cSKever Yang 
1573c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1574c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1575c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1576c30d921cSKever Yang 			if (g_pLogObject) {
1577c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed");
1578c30d921cSKever Yang 			}
1579c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1580c30d921cSKever Yang 		}
1581c30d921cSKever Yang 
1582c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1583c30d921cSKever Yang 		if (index == -1) {
1584c30d921cSKever Yang 			if (g_pLogObject) {
1585c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed");
1586c30d921cSKever Yang 			}
1587c30d921cSKever Yang 			delete []loaderCodeBuffer;
1588c30d921cSKever Yang 			return -4;
1589c30d921cSKever Yang 		}
1590c30d921cSKever Yang 
1591c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1592c30d921cSKever Yang 		if (!bRet) {
1593c30d921cSKever Yang 			if (g_pLogObject) {
1594c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed");
1595c30d921cSKever Yang 			}
1596c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1597c30d921cSKever Yang 		}
1598c30d921cSKever Yang 
1599c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1600c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1601c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1602c30d921cSKever Yang 			if (g_pLogObject) {
1603c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed");
1604c30d921cSKever Yang 			}
1605c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1606c30d921cSKever Yang 		}
1607c30d921cSKever Yang 
1608c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1609c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1610c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1611c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1612c30d921cSKever Yang 		if (!pIDBData) {
1613c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1614c30d921cSKever Yang 			printf("New memory failed!");
1615c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1616c30d921cSKever Yang 			printf("\r\n");
1617c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1618c30d921cSKever Yang 		}
1619c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1620c30d921cSKever Yang 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize);
1621c30d921cSKever Yang 		if (iRet != 0) {
1622c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1623c30d921cSKever Yang 			printf("Make idblock failed!");
1624c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1625c30d921cSKever Yang 			printf("\r\n");
1626c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1627c30d921cSKever Yang 		}
1628c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1629c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1630c30d921cSKever Yang 		CURSOR_DEL_LINE;
1631c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1632c30d921cSKever Yang 			pComm->Reset_Usb_Device();
1633c30d921cSKever Yang 			bSuccess = true;
1634c30d921cSKever Yang 			printf("Upgrade loader ok.\r\n");
1635c30d921cSKever Yang 		} else {
1636c30d921cSKever Yang 			printf("Upgrade loader failed!\r\n");
1637c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1638c30d921cSKever Yang 		}
1639c30d921cSKever Yang 	}
1640c30d921cSKever Yang Exit_UpgradeLoader:
1641c30d921cSKever Yang 	if (pImage)
1642c30d921cSKever Yang 		delete pImage;
1643c30d921cSKever Yang 	if (pComm)
1644c30d921cSKever Yang 		delete pComm;
1645c30d921cSKever Yang 	if (loaderCodeBuffer)
1646c30d921cSKever Yang 		delete []loaderCodeBuffer;
1647c30d921cSKever Yang 	if (loaderDataBuffer)
1648c30d921cSKever Yang 		delete []loaderDataBuffer;
1649c30d921cSKever Yang 	if (pIDBData)
1650c30d921cSKever Yang 		delete []pIDBData;
1651c30d921cSKever Yang 	return bSuccess;
1652c30d921cSKever Yang }
1653c30d921cSKever Yang 
165476af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
165576af099aSliuyi {
165676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
165776af099aSliuyi 		return false;
165876af099aSliuyi 	CRKImage *pImage = NULL;
165976af099aSliuyi 	bool bRet, bSuccess = false;
166076af099aSliuyi 	int iRet;
166176af099aSliuyi 	CRKScan *pScan = NULL;
166276af099aSliuyi 	pScan = new CRKScan();
166376af099aSliuyi 	pScan->SetVidPid();
166476af099aSliuyi 
166576af099aSliuyi 	CRKComm *pComm = NULL;
166676af099aSliuyi 	CRKDevice *pDevice = NULL;
166776af099aSliuyi 
166876af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
166976af099aSliuyi 	if (!bRet) {
167076af099aSliuyi 		if (pScan)
167176af099aSliuyi 			delete pScan;
167276af099aSliuyi 		ERROR_COLOR_ATTR;
167376af099aSliuyi 		printf("Creating Comm Object failed!");
167476af099aSliuyi 		NORMAL_COLOR_ATTR;
167576af099aSliuyi 		printf("\r\n");
167676af099aSliuyi 		return bSuccess;
167776af099aSliuyi 	}
167876af099aSliuyi 
167976af099aSliuyi 	pDevice = new CRKDevice(dev);
168076af099aSliuyi 	if (!pDevice) {
168176af099aSliuyi 		if (pComm)
168276af099aSliuyi 			delete pComm;
168376af099aSliuyi 		if (pScan)
168476af099aSliuyi 			delete pScan;
168576af099aSliuyi 		ERROR_COLOR_ATTR;
168676af099aSliuyi 		printf("Creating device object failed!");
168776af099aSliuyi 		NORMAL_COLOR_ATTR;
168876af099aSliuyi 		printf("\r\n");
168976af099aSliuyi 		return bSuccess;
169076af099aSliuyi 	}
169176af099aSliuyi 
169276af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
169376af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
169476af099aSliuyi 
169576af099aSliuyi 	printf("Start to erase flash...\r\n");
169676af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
169776af099aSliuyi 	if (pDevice)
169876af099aSliuyi 		delete pDevice;
169976af099aSliuyi 
170076af099aSliuyi 	if (iRet == 0) {
170176af099aSliuyi 		if (pScan) {
170276af099aSliuyi 			pScan->SetVidPid();
170376af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
170476af099aSliuyi 			delete pScan;
170576af099aSliuyi 		}
170676af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
170776af099aSliuyi 		CURSOR_DEL_LINE;
170876af099aSliuyi 		bSuccess = true;
170976af099aSliuyi 		printf("Erase flash ok.\r\n");
171076af099aSliuyi 	}
171176af099aSliuyi 
171276af099aSliuyi 	return bSuccess;
171376af099aSliuyi }
171476af099aSliuyi 
171576af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
171676af099aSliuyi {
171776af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
171876af099aSliuyi 		return false;
171976af099aSliuyi 	CRKUsbComm *pComm = NULL;
172076af099aSliuyi 	bool bRet, bSuccess = false;
172176af099aSliuyi 	int iRet;
172276af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
172376af099aSliuyi 	if (bRet) {
172476af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
172576af099aSliuyi 		if (iRet != ERR_SUCCESS) {
172676af099aSliuyi 			if (g_pLogObject)
172776af099aSliuyi 				g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet);
172876af099aSliuyi 			printf("Test Device Fail!\r\n");
172976af099aSliuyi 		} else {
173076af099aSliuyi 			bSuccess = true;
173176af099aSliuyi 			printf("Test Device OK.\r\n");
173276af099aSliuyi 		}
173376af099aSliuyi 	} else {
173476af099aSliuyi 		printf("Test Device quit,Creating comm object failed!\r\n");
173576af099aSliuyi 	}
173676af099aSliuyi 	if (pComm) {
173776af099aSliuyi 		delete pComm;
173876af099aSliuyi 		pComm = NULL;
173976af099aSliuyi 	}
174076af099aSliuyi 	return bSuccess;
174176af099aSliuyi }
174276af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
174376af099aSliuyi {
174476af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
174576af099aSliuyi 		return false;
174676af099aSliuyi 	CRKUsbComm *pComm = NULL;
174776af099aSliuyi 	bool bRet, bSuccess = false;
174876af099aSliuyi 	int iRet;
174976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
175076af099aSliuyi 	if (bRet) {
175176af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
175276af099aSliuyi 		if (iRet != ERR_SUCCESS) {
175376af099aSliuyi 			if (g_pLogObject)
175476af099aSliuyi 				g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet);
175576af099aSliuyi 			printf("Reset Device Fail!\r\n");
175676af099aSliuyi 		} else {
175776af099aSliuyi 			bSuccess = true;
175876af099aSliuyi 			printf("Reset Device OK.\r\n");
175976af099aSliuyi 		}
176076af099aSliuyi 	} else {
176176af099aSliuyi 		printf("Reset Device quit,Creating comm object failed!\r\n");
176276af099aSliuyi 	}
176376af099aSliuyi 	if (pComm) {
176476af099aSliuyi 		delete pComm;
176576af099aSliuyi 		pComm = NULL;
176676af099aSliuyi 	}
176776af099aSliuyi 	return bSuccess;
176876af099aSliuyi }
176976af099aSliuyi 
177076af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
177176af099aSliuyi {
177276af099aSliuyi 	CRKUsbComm *pComm = NULL;
177376af099aSliuyi 	bool bRet, bSuccess = false;
177476af099aSliuyi 	int iRet;
177576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
177676af099aSliuyi 		return bSuccess;
177776af099aSliuyi 
177876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
177976af099aSliuyi 	if (bRet) {
178076af099aSliuyi 		BYTE flashID[5];
178176af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
178276af099aSliuyi 		if (iRet != ERR_SUCCESS) {
178376af099aSliuyi 			if (g_pLogObject)
178476af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet);
178576af099aSliuyi 			printf("Read flash ID Fail!\r\n");
178676af099aSliuyi 		} else {
178776af099aSliuyi 			printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
178876af099aSliuyi 			bSuccess = true;
178976af099aSliuyi 		}
179076af099aSliuyi 	} else {
179176af099aSliuyi 		printf("Read flash ID quit,Creating comm object failed!\r\n");
179276af099aSliuyi 	}
179376af099aSliuyi 	if (pComm) {
179476af099aSliuyi 		delete pComm;
179576af099aSliuyi 		pComm = NULL;
179676af099aSliuyi 	}
179776af099aSliuyi 	return bSuccess;
179876af099aSliuyi }
179976af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
180076af099aSliuyi {
180176af099aSliuyi 	CRKUsbComm *pComm = NULL;
180276af099aSliuyi 	bool bRet, bSuccess = false;
180376af099aSliuyi 	int iRet;
180476af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
180576af099aSliuyi 		return bSuccess;
180676af099aSliuyi 
180776af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
180876af099aSliuyi 	if (bRet) {
180976af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
181076af099aSliuyi 		UINT uiRead;
181176af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
181276af099aSliuyi 		if (iRet != ERR_SUCCESS) {
181376af099aSliuyi 			if (g_pLogObject)
181476af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet);
181576af099aSliuyi 			printf("Read flash Info Fail!\r\n");
181676af099aSliuyi 		} else {
181776af099aSliuyi 			printf("Flash Info:\r\n");
181876af099aSliuyi 			if (info.bManufCode <= 7) {
181976af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
182076af099aSliuyi 			}
182176af099aSliuyi 			else
182276af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode);
182376af099aSliuyi 
182476af099aSliuyi 			printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024);
182576af099aSliuyi 			printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2);
182676af099aSliuyi 			printf("\tPage Size: %dKB\r\n", info.bPageSize / 2);
182776af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
182876af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
182976af099aSliuyi 			printf("\tFlash CS: ");
183076af099aSliuyi 			for(int i = 0; i < 8; i++) {
183176af099aSliuyi 				if( info.bFlashCS & (1 << i) )
183276af099aSliuyi 					printf("Flash<%d> ", i);
183376af099aSliuyi 			}
183476af099aSliuyi 			printf("\r\n");
183576af099aSliuyi 			bSuccess = true;
183676af099aSliuyi 		}
183776af099aSliuyi 	}else {
183876af099aSliuyi 		printf("Read flash Info quit,Creating comm object failed!\r\n");
183976af099aSliuyi 	}
184076af099aSliuyi 	if (pComm) {
184176af099aSliuyi 		delete pComm;
184276af099aSliuyi 		pComm = NULL;
184376af099aSliuyi 	}
184476af099aSliuyi 	return bSuccess;
184576af099aSliuyi }
184676af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
184776af099aSliuyi {
184876af099aSliuyi 	CRKUsbComm *pComm = NULL;
184976af099aSliuyi 	bool bRet, bSuccess = false;
185076af099aSliuyi 	int iRet;
185176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
185276af099aSliuyi 		return bSuccess;
185376af099aSliuyi 
185476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
185576af099aSliuyi 	if (bRet) {
185676af099aSliuyi 		BYTE chipInfo[16];
185776af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
185876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
185976af099aSliuyi 			if (g_pLogObject)
186076af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet);
186176af099aSliuyi 			printf("Read Chip Info Fail!\r\n");
186276af099aSliuyi 		} else {
186376af099aSliuyi 			string strChipInfo;
186476af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
186576af099aSliuyi 			printf("Chip Info:%s\r\n", strChipInfo.c_str());
186676af099aSliuyi 			bSuccess = true;
186776af099aSliuyi 		}
186876af099aSliuyi 	} else {
186976af099aSliuyi 		printf("Read Chip Info quit,Creating comm object failed!\r\n");
187076af099aSliuyi 	}
187176af099aSliuyi 	if (pComm) {
187276af099aSliuyi 		delete pComm;
187376af099aSliuyi 		pComm = NULL;
187476af099aSliuyi 	}
187576af099aSliuyi 	return bSuccess;
187676af099aSliuyi }
187776af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
187876af099aSliuyi {
187976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
188076af099aSliuyi 		return false;
188176af099aSliuyi 	CRKUsbComm *pComm = NULL;
188276af099aSliuyi 	FILE *file = NULL;
188376af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
188476af099aSliuyi 	int iRet;
188576af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
188676af099aSliuyi 	int nSectorSize = 512;
188776af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
188876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
188976af099aSliuyi 	if (bRet) {
189076af099aSliuyi 		if(szFile) {
189176af099aSliuyi 			file = fopen(szFile, "wb+");
189276af099aSliuyi 			if( !file ) {
189376af099aSliuyi 				printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
189476af099aSliuyi 				goto Exit_ReadLBA;
189576af099aSliuyi 			}
189676af099aSliuyi 		}
189776af099aSliuyi 
189876af099aSliuyi 		while(uiLen > 0) {
189976af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
190076af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
190176af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
190276af099aSliuyi 			if(ERR_SUCCESS == iRet) {
190376af099aSliuyi 				uiLen -= iRead;
190476af099aSliuyi 				iTotalRead += iRead;
190576af099aSliuyi 
190676af099aSliuyi 				if(szFile) {
190776af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
190876af099aSliuyi 					if (bFirst){
190976af099aSliuyi 						if (iTotalRead >= 1024)
191076af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
191176af099aSliuyi 						else
191276af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
191376af099aSliuyi 						bFirst = false;
191476af099aSliuyi 					} else {
191576af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
191676af099aSliuyi 						CURSOR_DEL_LINE;
191776af099aSliuyi 						if (iTotalRead >= 1024)
191876af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
191976af099aSliuyi 						else
192076af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
192176af099aSliuyi 					}
192276af099aSliuyi 				}
192376af099aSliuyi 				else
192476af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
192576af099aSliuyi 			} else {
192676af099aSliuyi 				if (g_pLogObject)
192776af099aSliuyi 					g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet);
192876af099aSliuyi 
192976af099aSliuyi 				printf("Read LBA failed!\r\n");
193076af099aSliuyi 				goto Exit_ReadLBA;
193176af099aSliuyi 			}
193276af099aSliuyi 		}
193376af099aSliuyi 		bSuccess = true;
193476af099aSliuyi 	} else {
193576af099aSliuyi 		printf("Read LBA quit,Creating comm object failed!\r\n");
193676af099aSliuyi 	}
193776af099aSliuyi Exit_ReadLBA:
193876af099aSliuyi 	if (pComm) {
193976af099aSliuyi 		delete pComm;
194076af099aSliuyi 		pComm = NULL;
194176af099aSliuyi 	}
194276af099aSliuyi 	if (file)
194376af099aSliuyi 		fclose(file);
194476af099aSliuyi 	return bSuccess;
194576af099aSliuyi }
194676af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
194776af099aSliuyi {
194876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
194976af099aSliuyi 		return false;
195076af099aSliuyi 	CRKUsbComm *pComm = NULL;
195176af099aSliuyi 	FILE *file = NULL;
195276af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
195376af099aSliuyi 	int iRet;
195476af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
195576af099aSliuyi 	UINT iWrite = 0, iRead = 0;
195676af099aSliuyi 	UINT uiLen;
195776af099aSliuyi 	int nSectorSize = 512;
195876af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
195976af099aSliuyi 
196076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
196176af099aSliuyi 	if (bRet) {
196276af099aSliuyi 		file = fopen(szFile, "rb");
196376af099aSliuyi 		if( !file ) {
196476af099aSliuyi 			printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
196576af099aSliuyi 			goto Exit_WriteLBA;
196676af099aSliuyi 		}
196776af099aSliuyi 
196876af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
196976af099aSliuyi 		iFileSize = ftello(file);
197076af099aSliuyi 		fseeko(file, 0, SEEK_SET);
197176af099aSliuyi 		while(iTotalWrite < iFileSize) {
197276af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
197376af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
197476af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
197576af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
197676af099aSliuyi 			if(ERR_SUCCESS == iRet) {
197776af099aSliuyi 				uiBegin += uiLen;
197876af099aSliuyi 				iTotalWrite += iWrite;
197976af099aSliuyi 				if (bFirst) {
198076af099aSliuyi 					if (iTotalWrite >= 1024)
198176af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
198276af099aSliuyi 					else
198376af099aSliuyi 						printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
198476af099aSliuyi 					bFirst = false;
198576af099aSliuyi 				} else {
198676af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
198776af099aSliuyi 					CURSOR_DEL_LINE;
198876af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
198976af099aSliuyi 				}
199076af099aSliuyi 			} else {
199176af099aSliuyi 				if (g_pLogObject)
199276af099aSliuyi 					g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
199376af099aSliuyi 
199476af099aSliuyi 				printf("Write LBA failed!\r\n");
199576af099aSliuyi 				goto Exit_WriteLBA;
199676af099aSliuyi 			}
199776af099aSliuyi 		}
199876af099aSliuyi 		bSuccess = true;
199976af099aSliuyi 	} else {
200076af099aSliuyi 		printf("Write LBA quit,Creating comm object failed!\r\n");
200176af099aSliuyi 	}
200276af099aSliuyi Exit_WriteLBA:
200376af099aSliuyi 	if (pComm) {
200476af099aSliuyi 		delete pComm;
200576af099aSliuyi 		pComm = NULL;
200676af099aSliuyi 	}
200776af099aSliuyi 	if (file)
200876af099aSliuyi 		fclose(file);
200976af099aSliuyi 	return bSuccess;
201076af099aSliuyi }
201176af099aSliuyi 
201276af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
201376af099aSliuyi {
201476af099aSliuyi 	string strItem;
201576af099aSliuyi 	char szItem[100];
201676af099aSliuyi 	char *pos = NULL, *pStart;
201776af099aSliuyi 	pStart = pszItems;
201876af099aSliuyi 	pos = strchr(pStart, ',');
201976af099aSliuyi 	while(pos != NULL) {
202076af099aSliuyi 		memset(szItem, 0, 100);
202176af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
202276af099aSliuyi 		strItem = szItem;
202376af099aSliuyi 		vecItems.push_back(strItem);
202476af099aSliuyi 		pStart = pos + 1;
202576af099aSliuyi 		if (*pStart == 0)
202676af099aSliuyi 			break;
202776af099aSliuyi 		pos = strchr(pStart, ',');
202876af099aSliuyi 	}
202976af099aSliuyi 	if (strlen(pStart) > 0) {
203076af099aSliuyi 		memset(szItem, 0, 100);
203176af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
203276af099aSliuyi 		strItem = szItem;
203376af099aSliuyi 		vecItems.push_back(strItem);
203476af099aSliuyi 	}
203576af099aSliuyi }
2036c30d921cSKever Yang 
203776af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
203876af099aSliuyi {
203976af099aSliuyi 	string strCmd;
204076af099aSliuyi 	strCmd = argv[1];
204176af099aSliuyi 	ssize_t cnt;
204276af099aSliuyi 	bool bRet,bSuccess = false;
20438df2d64aSEddie Cai 	char *s;
20448df2d64aSEddie Cai 	int i, ret;
204576af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
204676af099aSliuyi 
204776af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
20488df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
20498df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
20508df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
2051*78884ef4SEddie Cai 
20528df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
205376af099aSliuyi 		usage();
205476af099aSliuyi 		return true;
20558df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2056c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
205776af099aSliuyi 		return true;
2058*78884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
2059*78884ef4SEddie Cai 		mergeBoot();
2060*78884ef4SEddie Cai 
2061*78884ef4SEddie Cai 		return true;
2062*78884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
2063*78884ef4SEddie Cai 		string strLoader = argv[2];
2064*78884ef4SEddie Cai 
2065*78884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
2066*78884ef4SEddie Cai 		return true;
206776af099aSliuyi 	}
206876af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
206976af099aSliuyi 	if (cnt < 1) {
207076af099aSliuyi 		ERROR_COLOR_ATTR;
207176af099aSliuyi 		printf("No found any rockusb device,please plug device in!");
207276af099aSliuyi 		NORMAL_COLOR_ATTR;
207376af099aSliuyi 		printf("\r\n");
207476af099aSliuyi 		return bSuccess;
207576af099aSliuyi 	} else if (cnt > 1) {
207676af099aSliuyi 		ERROR_COLOR_ATTR;
207776af099aSliuyi 		printf("Found many rockusb devices,please plug device out!");
207876af099aSliuyi 		NORMAL_COLOR_ATTR;
207976af099aSliuyi 		printf("\r\n");
208076af099aSliuyi 		return bSuccess;
208176af099aSliuyi 	}
208276af099aSliuyi 
208376af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
208476af099aSliuyi 	if (!bRet) {
208576af099aSliuyi 		ERROR_COLOR_ATTR;
208676af099aSliuyi 		printf("Getting information of rockusb device failed!");
208776af099aSliuyi 		NORMAL_COLOR_ATTR;
208876af099aSliuyi 		printf("\r\n");
208976af099aSliuyi 		return bSuccess;
209076af099aSliuyi 	}
209176af099aSliuyi 
209276af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
209376af099aSliuyi 		if ((argc != 2) && (argc != 3))
209476af099aSliuyi 			printf("Parameter of [RD] command is invalid,please check help!\r\n");
209576af099aSliuyi 		else {
209676af099aSliuyi 			if (argc == 2)
209776af099aSliuyi 				bSuccess = reset_device(dev);
209876af099aSliuyi 			else {
209976af099aSliuyi 				UINT uiSubCode;
210076af099aSliuyi 				char *pszEnd;
210176af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
210276af099aSliuyi 				if (*pszEnd)
210376af099aSliuyi 					printf("Subcode is invalid,please check!\r\n");
210476af099aSliuyi 				else {
210576af099aSliuyi 					if (uiSubCode <= 5)
210676af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
210776af099aSliuyi 					else
210876af099aSliuyi 						printf("Subcode is invalid,please check!\r\n");
210976af099aSliuyi 				}
211076af099aSliuyi 			}
211176af099aSliuyi 		}
211276af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
211376af099aSliuyi 		bSuccess = test_device(dev);
211476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
211576af099aSliuyi 		bSuccess = read_flash_id(dev);
211676af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
211776af099aSliuyi 		bSuccess = read_flash_info(dev);
211876af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
211976af099aSliuyi 		bSuccess = read_chip_info(dev);
212076af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
212176af099aSliuyi 		if (argc > 2) {
212276af099aSliuyi 			string strLoader;
212376af099aSliuyi 			strLoader = argv[2];
212476af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
212576af099aSliuyi 		} else if (argc == 2) {
212676af099aSliuyi 			ret = find_config_item("loader");
212776af099aSliuyi 			if (ret == -1)
212876af099aSliuyi 				printf("No found loader item from config!\r\n");
212976af099aSliuyi 			else
213076af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
213176af099aSliuyi 		} else
213276af099aSliuyi 			printf("Parameter of [DB] command is invalid,please check help!\r\n");
2133c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
2134c30d921cSKever Yang 		if (argc > 2) {
2135c30d921cSKever Yang 			string strParameter;
2136c30d921cSKever Yang 			strParameter = argv[2];
2137c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
2138c30d921cSKever Yang 		} else
2139c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid,please check help!\r\n");
2140c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
2141c30d921cSKever Yang 		if (argc > 2) {
2142c30d921cSKever Yang 			string strLoader;
2143c30d921cSKever Yang 			strLoader = argv[2];
2144c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
2145c30d921cSKever Yang 		} else
2146c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid,please check help!\r\n");
214776af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
214876af099aSliuyi 		if (argc == 2) {
214976af099aSliuyi 			bSuccess = erase_flash(dev);
215076af099aSliuyi 		} else
215176af099aSliuyi 			printf("Parameter of [EF] command is invalid,please check help!\r\n");
215276af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
215376af099aSliuyi 		if (argc == 4) {
215476af099aSliuyi 			UINT uiBegin;
215576af099aSliuyi 			char *pszEnd;
215676af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
215776af099aSliuyi 			if (*pszEnd)
215876af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
215976af099aSliuyi 			else
216076af099aSliuyi 				bSuccess = write_lba(dev, uiBegin, argv[3]);
216176af099aSliuyi 		} else
216276af099aSliuyi 			printf("Parameter of [WL] command is invalid,please check help!\r\n");
216376af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
216476af099aSliuyi 		char *pszEnd;
216576af099aSliuyi 		UINT uiBegin, uiLen;
216676af099aSliuyi 		if (argc != 5)
216776af099aSliuyi 			printf("Parameter of [RL] command is invalid,please check help!\r\n");
216876af099aSliuyi 		else {
216976af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
217076af099aSliuyi 			if (*pszEnd)
217176af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
217276af099aSliuyi 			else {
217376af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
217476af099aSliuyi 				if (*pszEnd)
217576af099aSliuyi 					printf("Len is invalid,please check!\r\n");
217676af099aSliuyi 				else {
217776af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
217876af099aSliuyi 				}
217976af099aSliuyi 			}
218076af099aSliuyi 		}
218176af099aSliuyi 	} else {
2182c30d921cSKever Yang 		printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n");
218376af099aSliuyi 	}
218476af099aSliuyi 	return bSuccess;
218576af099aSliuyi }
218676af099aSliuyi 
218776af099aSliuyi 
218876af099aSliuyi int main(int argc, char* argv[])
218976af099aSliuyi {
219076af099aSliuyi 	CRKScan *pScan = NULL;
219176af099aSliuyi 	int ret;
219276af099aSliuyi 	char szProgramProcPath[100];
219376af099aSliuyi 	char szProgramDir[256];
219476af099aSliuyi 	string strLogDir,strConfigFile;
219576af099aSliuyi 	struct stat statBuf;
219676af099aSliuyi 
219776af099aSliuyi 	g_ConfigItemVec.clear();
219876af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
219976af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
220076af099aSliuyi 		strcpy(szProgramDir, ".");
220176af099aSliuyi 	else {
220276af099aSliuyi 		char *pSlash;
220376af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
220476af099aSliuyi 		if (pSlash)
220576af099aSliuyi 			*pSlash = '\0';
220676af099aSliuyi 	}
220776af099aSliuyi 	strLogDir = szProgramDir;
220876af099aSliuyi 	strLogDir +=  "/log/";
220976af099aSliuyi 	strConfigFile = szProgramDir;
221076af099aSliuyi 	strConfigFile += "/config.ini";
221176af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
221276af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
221376af099aSliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
221476af099aSliuyi 
221576af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
221676af099aSliuyi 		if (g_pLogObject) {
221776af099aSliuyi 			g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
221876af099aSliuyi 		}
221976af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
222076af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
222176af099aSliuyi 	}
222276af099aSliuyi 
222376af099aSliuyi 	ret = libusb_init(NULL);
222476af099aSliuyi 	if (ret < 0) {
222576af099aSliuyi 		if (g_pLogObject) {
222676af099aSliuyi 			g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
222776af099aSliuyi 			delete g_pLogObject;
222876af099aSliuyi 		}
222976af099aSliuyi 		return -1;
223076af099aSliuyi 	}
223176af099aSliuyi 
223276af099aSliuyi 	pScan = new CRKScan();
223376af099aSliuyi 	if (!pScan) {
223476af099aSliuyi 		if (g_pLogObject) {
223576af099aSliuyi 			g_pLogObject->Record("Error:failed to Create object for searching device");
223676af099aSliuyi 			delete g_pLogObject;
223776af099aSliuyi 		}
223876af099aSliuyi 		libusb_exit(NULL);
223976af099aSliuyi 		return -2;
224076af099aSliuyi 	}
224176af099aSliuyi 	pScan->SetVidPid();
224276af099aSliuyi 
224376af099aSliuyi 	if (argc == 1)
224476af099aSliuyi 		usage();
224576af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
224676af099aSliuyi 			return -0xFF;
224776af099aSliuyi 	if (pScan)
224876af099aSliuyi 		delete pScan;
224976af099aSliuyi 	if (g_pLogObject)
225076af099aSliuyi 		delete g_pLogObject;
225176af099aSliuyi 	libusb_exit(NULL);
225276af099aSliuyi 	return 0;
225376af099aSliuyi }
2254