xref: /rkdeveloptool/main.cpp (revision 641cfa16d6d52b78ded6d85f20c2a9bbfcf46c59)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi 
876af099aSliuyi #include   <unistd.h>
976af099aSliuyi #include   <dirent.h>
10c30d921cSKever Yang #include "config.h"
1176af099aSliuyi #include "DefineHeader.h"
12c30d921cSKever Yang #include "gpt.h"
1376af099aSliuyi #include "RKLog.h"
1476af099aSliuyi #include "RKScan.h"
1576af099aSliuyi #include "RKComm.h"
1676af099aSliuyi #include "RKDevice.h"
1776af099aSliuyi #include "RKImage.h"
1876af099aSliuyi extern const char *szManufName[];
1976af099aSliuyi CRKLog *g_pLogObject=NULL;
2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec;
2176af099aSliuyi #define DEFAULT_RW_LBA 128
2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
2676af099aSliuyi #define ERROR_COLOR_ATTR  printf("%c[30;41m", 0x1B);
2776af099aSliuyi #define NORMAL_COLOR_ATTR  printf("%c[37;40m", 0x1B);
28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len);
31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32c30d921cSKever Yang /*
33c30d921cSKever Yang u8 test_gpt_head[] = {
34c30d921cSKever Yang 	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35c30d921cSKever Yang 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36c30d921cSKever Yang 	0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37c30d921cSKever Yang 	0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38c30d921cSKever Yang 	0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39c30d921cSKever Yang 	0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40c30d921cSKever Yang */
41c30d921cSKever Yang 
4276af099aSliuyi void usage()
4376af099aSliuyi {
4476af099aSliuyi 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
45154ee062SEddie Cai 	printf("Help:\t\t\t-h or --version\r\n");
46154ee062SEddie Cai 	printf("Version:\t\t-v or --version\r\n");
47154ee062SEddie Cai 	printf("DownloadBoot:\t\tdb <Loader>\r\n");
48154ee062SEddie Cai 	printf("UpgradeLoader:\t\tul <Loader>\r\n");
49154ee062SEddie Cai 	printf("ReadLBA:\t\trl  <BeginSec> <SectorLen> <File>\r\n");
50154ee062SEddie Cai 	printf("WriteLBA:\t\twl  <BeginSec> <File>\r\n");
51154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
52154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
53154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
54154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
55154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
56154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
57154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
5878884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
5978884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
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 
68478884ef4SEddie Cai #include "boot_merger.h"
68578884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
68678884ef4SEddie Cai options gOpts;
68778884ef4SEddie Cai 
68878884ef4SEddie Cai 
68978884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
69078884ef4SEddie Cai char* gConfigPath;
69178884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
69278884ef4SEddie Cai 
69378884ef4SEddie Cai static inline void fixPath(char* path) {
69478884ef4SEddie Cai 	int i, len = strlen(path);
69578884ef4SEddie Cai 	for(i=0; i<len; i++) {
69678884ef4SEddie Cai 		if (path[i] == '\\')
69778884ef4SEddie Cai 			path[i] = '/';
69878884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
69978884ef4SEddie Cai 			path[i] = '\0';
70078884ef4SEddie Cai 	}
70178884ef4SEddie Cai }
70278884ef4SEddie Cai 
70378884ef4SEddie Cai static bool parseChip(FILE* file) {
70478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
70578884ef4SEddie Cai 		return false;
70678884ef4SEddie Cai 	}
70778884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
70878884ef4SEddie Cai 		return false;
70978884ef4SEddie Cai 	}
71078884ef4SEddie Cai 	printf("chip:%s\n", gOpts.chip);
71178884ef4SEddie Cai 	return true;
71278884ef4SEddie Cai }
71378884ef4SEddie Cai 
71478884ef4SEddie Cai static bool parseVersion(FILE* file) {
71578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
71678884ef4SEddie Cai 		return false;
71778884ef4SEddie Cai 	}
71878884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
71978884ef4SEddie Cai 		return false;
72078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
72178884ef4SEddie Cai 		return false;
72278884ef4SEddie Cai 	}
72378884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
72478884ef4SEddie Cai 		return false;
72578884ef4SEddie Cai 	printf("major:%d, minor:%d\n", gOpts.major, gOpts.minor);
72678884ef4SEddie Cai 	return true;
72778884ef4SEddie Cai }
72878884ef4SEddie Cai 
72978884ef4SEddie Cai static bool parse471(FILE* file) {
73078884ef4SEddie Cai 	int i, index, pos;
73178884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
73278884ef4SEddie Cai 
73378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
73478884ef4SEddie Cai 		return false;
73578884ef4SEddie Cai 	}
73678884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
73778884ef4SEddie Cai 		return false;
73878884ef4SEddie Cai 	printf("num:%d\n", gOpts.code471Num);
73978884ef4SEddie Cai 	if (!gOpts.code471Num)
74078884ef4SEddie Cai 		return true;
74178884ef4SEddie Cai 	if (gOpts.code471Num < 0)
74278884ef4SEddie Cai 		return false;
74378884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
74478884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
74578884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
74678884ef4SEddie Cai 			return false;
74778884ef4SEddie Cai 		}
74878884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
74978884ef4SEddie Cai 				!= 2)
75078884ef4SEddie Cai 			return false;
75178884ef4SEddie Cai 		index--;
75278884ef4SEddie Cai 		fixPath(buf);
75378884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
75478884ef4SEddie Cai 		printf("path%i:%s\n", index, gOpts.code471Path[index]);
75578884ef4SEddie Cai 	}
75678884ef4SEddie Cai 	pos = ftell(file);
75778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
75878884ef4SEddie Cai 		return false;
75978884ef4SEddie Cai 	}
76078884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
76178884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
76278884ef4SEddie Cai 	printf("sleep:%d\n", gOpts.code471Sleep);
76378884ef4SEddie Cai 	return true;
76478884ef4SEddie Cai }
76578884ef4SEddie Cai 
76678884ef4SEddie Cai static bool parse472(FILE* file) {
76778884ef4SEddie Cai 	int i, index, pos;
76878884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
76978884ef4SEddie Cai 
77078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
77178884ef4SEddie Cai 		return false;
77278884ef4SEddie Cai 	}
77378884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
77478884ef4SEddie Cai 		return false;
77578884ef4SEddie Cai 	printf("num:%d\n", gOpts.code472Num);
77678884ef4SEddie Cai 	if (!gOpts.code472Num)
77778884ef4SEddie Cai 		return true;
77878884ef4SEddie Cai 	if (gOpts.code472Num < 0)
77978884ef4SEddie Cai 		return false;
78078884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
78178884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
78278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
78378884ef4SEddie Cai 			return false;
78478884ef4SEddie Cai 		}
78578884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
78678884ef4SEddie Cai 				!= 2)
78778884ef4SEddie Cai 			return false;
78878884ef4SEddie Cai 		fixPath(buf);
78978884ef4SEddie Cai 		index--;
79078884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
79178884ef4SEddie Cai 		printf("path%i:%s\n", index, gOpts.code472Path[index]);
79278884ef4SEddie Cai 	}
79378884ef4SEddie Cai 	pos = ftell(file);
79478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
79578884ef4SEddie Cai 		return false;
79678884ef4SEddie Cai 	}
79778884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
79878884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
79978884ef4SEddie Cai 	printf("sleep:%d\n", gOpts.code472Sleep);
80078884ef4SEddie Cai 	return true;
80178884ef4SEddie Cai }
80278884ef4SEddie Cai 
80378884ef4SEddie Cai static bool parseLoader(FILE* file) {
80478884ef4SEddie Cai 	int i, j, index, pos;
80578884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
80678884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
80778884ef4SEddie Cai 
80878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
80978884ef4SEddie Cai 		return false;
81078884ef4SEddie Cai 	}
81178884ef4SEddie Cai 	pos = ftell(file);
81278884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
81378884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
81478884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
81578884ef4SEddie Cai 			return false;
81678884ef4SEddie Cai 		}
81778884ef4SEddie Cai 	}
81878884ef4SEddie Cai 	printf("num:%d\n", gOpts.loaderNum);
81978884ef4SEddie Cai 	if (!gOpts.loaderNum)
82078884ef4SEddie Cai 		return false;
82178884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
82278884ef4SEddie Cai 		return false;
82378884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
82478884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
82578884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
82678884ef4SEddie Cai 			return false;
82778884ef4SEddie Cai 		}
82878884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
82978884ef4SEddie Cai 				!= 2)
83078884ef4SEddie Cai 			return false;
83178884ef4SEddie Cai 		index--;
83278884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
83378884ef4SEddie Cai 		printf("name%d:%s\n", index, gOpts.loader[index].name);
83478884ef4SEddie Cai 	}
83578884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
83678884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
83778884ef4SEddie Cai 			return false;
83878884ef4SEddie Cai 		}
83978884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
84078884ef4SEddie Cai 				!= 2)
84178884ef4SEddie Cai 			return false;
84278884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
84378884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
84478884ef4SEddie Cai 				fixPath(buf2);
84578884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
84678884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
84778884ef4SEddie Cai 				break;
84878884ef4SEddie Cai 			}
84978884ef4SEddie Cai 		}
85078884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
85178884ef4SEddie Cai 			return false;
85278884ef4SEddie Cai 		}
85378884ef4SEddie Cai 	}
85478884ef4SEddie Cai 	return true;
85578884ef4SEddie Cai }
85678884ef4SEddie Cai 
85778884ef4SEddie Cai static bool parseOut(FILE* file) {
85878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
85978884ef4SEddie Cai 		return false;
86078884ef4SEddie Cai 	}
86178884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
86278884ef4SEddie Cai 		return false;
86378884ef4SEddie Cai 	fixPath(gOpts.outPath);
86478884ef4SEddie Cai 	printf("out:%s\n", gOpts.outPath);
86578884ef4SEddie Cai 	return true;
86678884ef4SEddie Cai }
86778884ef4SEddie Cai 
86878884ef4SEddie Cai 
86978884ef4SEddie Cai void printOpts(FILE* out) {
87078884ef4SEddie Cai 	int i;
87178884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
87278884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
87378884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
87478884ef4SEddie Cai 
87578884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
87678884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
87778884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
87878884ef4SEddie Cai 	}
87978884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
88078884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
88178884ef4SEddie Cai 
88278884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
88378884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
88478884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
88578884ef4SEddie Cai 	}
88678884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
88778884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
88878884ef4SEddie Cai 
88978884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
89078884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
89178884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
89278884ef4SEddie Cai 	}
89378884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
89478884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
89578884ef4SEddie Cai 	}
89678884ef4SEddie Cai 
89778884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
89878884ef4SEddie Cai }
89978884ef4SEddie Cai 
90078884ef4SEddie Cai static bool parseOpts(void) {
90178884ef4SEddie Cai 	bool ret = false;
90278884ef4SEddie Cai 	bool chipOk = false;
90378884ef4SEddie Cai 	bool versionOk = false;
90478884ef4SEddie Cai 	bool code471Ok = true;
90578884ef4SEddie Cai 	bool code472Ok = true;
90678884ef4SEddie Cai 	bool loaderOk = false;
90778884ef4SEddie Cai 	bool outOk = false;
90878884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
90978884ef4SEddie Cai 
91078884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
91178884ef4SEddie Cai 	FILE* file;
91278884ef4SEddie Cai 	file = fopen(configPath, "r");
91378884ef4SEddie Cai 	if (!file) {
91478884ef4SEddie Cai 		fprintf(stderr, "config(%s) not found!\n", configPath);
91578884ef4SEddie Cai 		if (configPath == (char*)DEF_CONFIG_FILE) {
91678884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
91778884ef4SEddie Cai 			if (file) {
91878884ef4SEddie Cai 				fprintf(stderr, "create defconfig\n");
91978884ef4SEddie Cai 				printOpts(file);
92078884ef4SEddie Cai 			}
92178884ef4SEddie Cai 		}
92278884ef4SEddie Cai 		goto end;
92378884ef4SEddie Cai 	}
92478884ef4SEddie Cai 
92578884ef4SEddie Cai 	printf("start parse\n");
92678884ef4SEddie Cai 
92778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
92878884ef4SEddie Cai 		goto end;
92978884ef4SEddie Cai 	}
93078884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
93178884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
93278884ef4SEddie Cai 			chipOk = parseChip(file);
93378884ef4SEddie Cai 			if (!chipOk) {
93478884ef4SEddie Cai 				printf("parseChip failed!\n");
93578884ef4SEddie Cai 				goto end;
93678884ef4SEddie Cai 			}
93778884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
93878884ef4SEddie Cai 			versionOk = parseVersion(file);
93978884ef4SEddie Cai 			if (!versionOk) {
94078884ef4SEddie Cai 				printf("parseVersion failed!\n");
94178884ef4SEddie Cai 				goto end;
94278884ef4SEddie Cai 			}
94378884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
94478884ef4SEddie Cai 			code471Ok = parse471(file);
94578884ef4SEddie Cai 			if (!code471Ok) {
94678884ef4SEddie Cai 				printf("parse471 failed!\n");
94778884ef4SEddie Cai 				goto end;
94878884ef4SEddie Cai 			}
94978884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
95078884ef4SEddie Cai 			code472Ok = parse472(file);
95178884ef4SEddie Cai 			if (!code472Ok) {
95278884ef4SEddie Cai 				printf("parse472 failed!\n");
95378884ef4SEddie Cai 				goto end;
95478884ef4SEddie Cai 			}
95578884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
95678884ef4SEddie Cai 			loaderOk = parseLoader(file);
95778884ef4SEddie Cai 			if (!loaderOk) {
95878884ef4SEddie Cai 				printf("parseLoader failed!\n");
95978884ef4SEddie Cai 				goto end;
96078884ef4SEddie Cai 			}
96178884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
96278884ef4SEddie Cai 			outOk = parseOut(file);
96378884ef4SEddie Cai 			if (!outOk) {
96478884ef4SEddie Cai 				printf("parseOut failed!\n");
96578884ef4SEddie Cai 				goto end;
96678884ef4SEddie Cai 			}
96778884ef4SEddie Cai 		} else if (buf[0] == '#') {
96878884ef4SEddie Cai 			continue;
96978884ef4SEddie Cai 		} else {
97078884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
97178884ef4SEddie Cai 			goto end;
97278884ef4SEddie Cai 		}
97378884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
97478884ef4SEddie Cai 			goto end;
97578884ef4SEddie Cai 		}
97678884ef4SEddie Cai 	}
97778884ef4SEddie Cai 
97878884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
97978884ef4SEddie Cai 			&& loaderOk && outOk)
98078884ef4SEddie Cai 		ret = true;
98178884ef4SEddie Cai end:
98278884ef4SEddie Cai 	if (file)
98378884ef4SEddie Cai 		fclose(file);
98478884ef4SEddie Cai 	return ret;
98578884ef4SEddie Cai }
98678884ef4SEddie Cai 
98778884ef4SEddie Cai bool initOpts(void) {
98878884ef4SEddie Cai 	//set default opts
98978884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
99078884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
99178884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
99278884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
99378884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
99478884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
99578884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
99678884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
99778884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
99878884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
99978884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
100078884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
100178884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
100278884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
100378884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
100478884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
100578884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
100678884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
100778884ef4SEddie Cai 
100878884ef4SEddie Cai 	return parseOpts();
100978884ef4SEddie Cai }
101078884ef4SEddie Cai 
101178884ef4SEddie Cai /************merge code****************/
101278884ef4SEddie Cai 
101378884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
101478884ef4SEddie Cai 	uint8_t tmp[2] = {0};
101578884ef4SEddie Cai 	int i;
101678884ef4SEddie Cai 	uint32_t ret;
101778884ef4SEddie Cai 	//if (value > 0xFFFF) {
101878884ef4SEddie Cai 	//	return 0;
101978884ef4SEddie Cai 	//}
102078884ef4SEddie Cai 	for(i=0; i < 2; i++) {
102178884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
102278884ef4SEddie Cai 		value /= 100;
102378884ef4SEddie Cai 	}
102478884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
102578884ef4SEddie Cai 
102678884ef4SEddie Cai 	printf("ret:%x\n",ret);
102778884ef4SEddie Cai 	return ret&0xFF;
102878884ef4SEddie Cai }
102978884ef4SEddie Cai 
103078884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
103178884ef4SEddie Cai {
103278884ef4SEddie Cai 	int i;
103378884ef4SEddie Cai 	for (i = 0; i < len; i++) {
103478884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
103578884ef4SEddie Cai 	}
103678884ef4SEddie Cai 	wide[len] = 0;
103778884ef4SEddie Cai }
103878884ef4SEddie Cai 
103978884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
104078884ef4SEddie Cai 	char* end;
104178884ef4SEddie Cai 	char* start;
104278884ef4SEddie Cai 	int len;
104378884ef4SEddie Cai 	if (!path || !dst)
104478884ef4SEddie Cai 		return;
104578884ef4SEddie Cai 	start = strrchr(path, '/');
104678884ef4SEddie Cai 	if (!start)
104778884ef4SEddie Cai 		start = path;
104878884ef4SEddie Cai 	else
104978884ef4SEddie Cai 		start++;
105078884ef4SEddie Cai 	end = strrchr(path, '.');
1051*641cfa16SEddie Cai 	if (!end || (end < start))
105278884ef4SEddie Cai 		end = path + strlen(path);
105378884ef4SEddie Cai 	len = end - start;
105478884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
105578884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
105678884ef4SEddie Cai 	str2wide(start, dst, len);
105778884ef4SEddie Cai 
105878884ef4SEddie Cai 
105978884ef4SEddie Cai 		char name[MAX_NAME_LEN];
106078884ef4SEddie Cai 		memset(name, 0, sizeof(name));
106178884ef4SEddie Cai 		memcpy(name, start, len);
106278884ef4SEddie Cai 		printf("path:%s, name:%s\n", path, name);
106378884ef4SEddie Cai 
106478884ef4SEddie Cai }
106578884ef4SEddie Cai 
106678884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
106778884ef4SEddie Cai 	struct stat st;
106878884ef4SEddie Cai 	if(stat(path, &st) < 0)
106978884ef4SEddie Cai 		return false;
107078884ef4SEddie Cai 	*size = st.st_size;
107178884ef4SEddie Cai 	printf("path:%s, size:%d\n", path, *size);
107278884ef4SEddie Cai 	return true;
107378884ef4SEddie Cai }
107478884ef4SEddie Cai 
107578884ef4SEddie Cai static inline rk_time getTime(void) {
107678884ef4SEddie Cai 	rk_time rkTime;
107778884ef4SEddie Cai 
107878884ef4SEddie Cai 	struct tm *tm;
107978884ef4SEddie Cai 	time_t tt = time(NULL);
108078884ef4SEddie Cai 	tm = localtime(&tt);
108178884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
108278884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
108378884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
108478884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
108578884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
108678884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
108778884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
108878884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
108978884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
109078884ef4SEddie Cai 	return rkTime;
109178884ef4SEddie Cai }
109278884ef4SEddie Cai 
109378884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
109478884ef4SEddie Cai 	bool ret = false;
109578884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
109678884ef4SEddie Cai 	uint8_t* buf;
109778884ef4SEddie Cai 
109878884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
109978884ef4SEddie Cai 	if (!inFile)
110078884ef4SEddie Cai 		goto end;
110178884ef4SEddie Cai 
110278884ef4SEddie Cai 	if (!getFileSize(path, &size))
110378884ef4SEddie Cai 		goto end;
110478884ef4SEddie Cai 	if (fix) {
110578884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
110678884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
110778884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
110878884ef4SEddie Cai 		fixSize +=tmp;
110978884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
111078884ef4SEddie Cai 	} else {
111178884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
111278884ef4SEddie Cai 	}
111378884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
111478884ef4SEddie Cai 		goto end;
111578884ef4SEddie Cai 
111678884ef4SEddie Cai 	if (fix) {
111778884ef4SEddie Cai 
111878884ef4SEddie Cai 		buf = gBuf;
111978884ef4SEddie Cai 		size = fixSize;
112078884ef4SEddie Cai 		while(1) {
112178884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
112278884ef4SEddie Cai 			buf += SMALL_PACKET;
112378884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
112478884ef4SEddie Cai 				break;
112578884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
112678884ef4SEddie Cai 		}
112778884ef4SEddie Cai 	} else {
112878884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
112978884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
113078884ef4SEddie Cai 		size +=tmp;
113178884ef4SEddie Cai 		P_RC4(gBuf, size);
113278884ef4SEddie Cai 	}
113378884ef4SEddie Cai 
113478884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
113578884ef4SEddie Cai 		goto end;
113678884ef4SEddie Cai 	ret = true;
113778884ef4SEddie Cai end:
113878884ef4SEddie Cai 	if (inFile)
113978884ef4SEddie Cai 		fclose(inFile);
114078884ef4SEddie Cai 	if (!ret)
114178884ef4SEddie Cai 		printf("write entry(%s) failed\n", path);
114278884ef4SEddie Cai 	return ret;
114378884ef4SEddie Cai }
114478884ef4SEddie Cai 
114578884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
114678884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
114778884ef4SEddie Cai 	uint32_t size;
114878884ef4SEddie Cai 	rk_boot_entry entry;
114978884ef4SEddie Cai 
115078884ef4SEddie Cai 	printf("write:%s\n", path);
1151*641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
115278884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
115378884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
115478884ef4SEddie Cai 	entry.type = type;
115578884ef4SEddie Cai 	entry.dataOffset = *offset;
115678884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
115778884ef4SEddie Cai 		printf("save entry(%s) failed:\n\tcannot get file size.\n", path);
115878884ef4SEddie Cai 		return false;
115978884ef4SEddie Cai 	}
116078884ef4SEddie Cai 	if (fix)
116178884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
116278884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
116378884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
116478884ef4SEddie Cai 	printf("align size:%d\n", size);
116578884ef4SEddie Cai 	entry.dataSize = size;
116678884ef4SEddie Cai 	entry.dataDelay = delay;
116778884ef4SEddie Cai 	*offset += size;
116878884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
116978884ef4SEddie Cai 	return true;
117078884ef4SEddie Cai }
117178884ef4SEddie Cai 
117278884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
117378884ef4SEddie Cai 	char buffer[5];
117478884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
117578884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
117678884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
117778884ef4SEddie Cai }
117878884ef4SEddie Cai 
117978884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
118078884ef4SEddie Cai 	printf("chip:%s\n", chip);
118178884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
118278884ef4SEddie Cai 	if(!chip) {
118378884ef4SEddie Cai 		goto end;
118478884ef4SEddie Cai 	}
118578884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
118678884ef4SEddie Cai 		chipType = RK28_DEVICE;
118778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
118878884ef4SEddie Cai 		chipType = RK28_DEVICE;
118978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
119078884ef4SEddie Cai 		chipType = RK281X_DEVICE;
119178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
119278884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
119378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
119478884ef4SEddie Cai 		chipType = RK27_DEVICE;
119578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
119678884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
119778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
119878884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
119978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
120078884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
120178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
120278884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
120378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
120478884ef4SEddie Cai 		chipType = RK29_DEVICE;
120578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
120678884ef4SEddie Cai 		chipType = RK292X_DEVICE;
120778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
120878884ef4SEddie Cai 		chipType = RK30_DEVICE;
120978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
121078884ef4SEddie Cai 		chipType = RK30B_DEVICE;
121178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
121278884ef4SEddie Cai 		chipType = RK31_DEVICE;
121378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
121478884ef4SEddie Cai 		chipType = RK32_DEVICE;
121578884ef4SEddie Cai 	} else {
121678884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
121778884ef4SEddie Cai 	}
121878884ef4SEddie Cai 
121978884ef4SEddie Cai end:
122078884ef4SEddie Cai 	printf("type:0x%x\n", chipType);
122178884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
122278884ef4SEddie Cai 		printf("chip type not support!\n");
122378884ef4SEddie Cai 	}
122478884ef4SEddie Cai 	return chipType;
122578884ef4SEddie Cai }
122678884ef4SEddie Cai 
122778884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
122878884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
122978884ef4SEddie Cai 	hdr->tag = TAG;
123078884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
123178884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
123278884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
123378884ef4SEddie Cai 	hdr->releaseTime = getTime();
123478884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
123578884ef4SEddie Cai 
123678884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
123778884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
123878884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
123978884ef4SEddie Cai 
124078884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
124178884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
124278884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
124378884ef4SEddie Cai 
124478884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
124578884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
124678884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
124778884ef4SEddie Cai #ifndef USE_P_RC4
124878884ef4SEddie Cai 	hdr->rc4Flag = 1;
124978884ef4SEddie Cai #endif
125078884ef4SEddie Cai }
125178884ef4SEddie Cai 
125278884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
125378884ef4SEddie Cai 	uint32_t size = 0;
125478884ef4SEddie Cai 	uint32_t crc = 0;
125578884ef4SEddie Cai 
125678884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
125778884ef4SEddie Cai 	getFileSize(path, &size);
125878884ef4SEddie Cai 	if (!file)
125978884ef4SEddie Cai 		goto end;
126078884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
126178884ef4SEddie Cai 		goto end;
126278884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
126378884ef4SEddie Cai 	printf("crc:0x%08x\n", crc);
126478884ef4SEddie Cai end:
126578884ef4SEddie Cai 	if (file)
126678884ef4SEddie Cai 		fclose(file);
126778884ef4SEddie Cai 	return crc;
126878884ef4SEddie Cai }
126978884ef4SEddie Cai 
127078884ef4SEddie Cai bool mergeBoot(void) {
127178884ef4SEddie Cai 	uint32_t dataOffset;
127278884ef4SEddie Cai 	bool ret = false;
127378884ef4SEddie Cai 	int i;
127478884ef4SEddie Cai 	FILE* outFile;
127578884ef4SEddie Cai 	uint32_t crc;
127678884ef4SEddie Cai 	rk_boot_header hdr;
127778884ef4SEddie Cai 
127878884ef4SEddie Cai 	if (!initOpts())
127978884ef4SEddie Cai 		return false;
128078884ef4SEddie Cai 	{
128178884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
128278884ef4SEddie Cai 		char version[MAX_LINE_LEN];
128378884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
128478884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
128578884ef4SEddie Cai 			subfix[0] = '\0';
128678884ef4SEddie Cai 		}
128778884ef4SEddie Cai 		strcat(gOpts.outPath, version);
128878884ef4SEddie Cai 		printf("fix opt:%s\n", gOpts.outPath);
128978884ef4SEddie Cai 	}
129078884ef4SEddie Cai 
129178884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
129278884ef4SEddie Cai 	printOpts(stdout);
129378884ef4SEddie Cai 	printf("---------------\n\n");
129478884ef4SEddie Cai 
129578884ef4SEddie Cai 
129678884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
129778884ef4SEddie Cai 	if (!outFile) {
129878884ef4SEddie Cai 		printf("open out file(%s) failed\n", gOpts.outPath);
129978884ef4SEddie Cai 		goto end;
130078884ef4SEddie Cai 	}
130178884ef4SEddie Cai 
130278884ef4SEddie Cai 	getBoothdr(&hdr);
130378884ef4SEddie Cai 	printf("write hdr\n");
130478884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
130578884ef4SEddie Cai 
130678884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
130778884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
130878884ef4SEddie Cai 		sizeof(rk_boot_entry);
130978884ef4SEddie Cai 
131078884ef4SEddie Cai 	printf("write code 471 entry\n");
131178884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
131278884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
131378884ef4SEddie Cai 					&dataOffset, NULL, false))
131478884ef4SEddie Cai 			goto end;
131578884ef4SEddie Cai 	}
131678884ef4SEddie Cai 	printf("write code 472 entry\n");
131778884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
131878884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
131978884ef4SEddie Cai 					&dataOffset, NULL, false))
132078884ef4SEddie Cai 			goto end;
132178884ef4SEddie Cai 	}
132278884ef4SEddie Cai 	printf("write loader entry\n");
132378884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
132478884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
132578884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
132678884ef4SEddie Cai 			goto end;
132778884ef4SEddie Cai 	}
132878884ef4SEddie Cai 
132978884ef4SEddie Cai 	printf("write code 471\n");
133078884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
133178884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
133278884ef4SEddie Cai 			goto end;
133378884ef4SEddie Cai 	}
133478884ef4SEddie Cai 	printf("write code 472\n");
133578884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
133678884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
133778884ef4SEddie Cai 			goto end;
133878884ef4SEddie Cai 	}
133978884ef4SEddie Cai 	printf("write loader\n");
134078884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
134178884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
134278884ef4SEddie Cai 			goto end;
134378884ef4SEddie Cai 	}
134478884ef4SEddie Cai 	fflush(outFile);
134578884ef4SEddie Cai 
134678884ef4SEddie Cai 	printf("write crc\n");
134778884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
134878884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
134978884ef4SEddie Cai 		goto end;
135078884ef4SEddie Cai 	printf("done\n");
135178884ef4SEddie Cai 	ret = true;
135278884ef4SEddie Cai end:
135378884ef4SEddie Cai 	if (outFile)
135478884ef4SEddie Cai 		fclose(outFile);
135578884ef4SEddie Cai 	return ret;
135678884ef4SEddie Cai }
135778884ef4SEddie Cai 
135878884ef4SEddie Cai /************merge code end************/
135978884ef4SEddie Cai /************unpack code***************/
136078884ef4SEddie Cai 
136178884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
136278884ef4SEddie Cai {
136378884ef4SEddie Cai 	int i;
136478884ef4SEddie Cai 	for (i = 0; i < len; i++) {
136578884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
136678884ef4SEddie Cai 	}
136778884ef4SEddie Cai 	str[len] = 0;
136878884ef4SEddie Cai }
136978884ef4SEddie Cai 
137078884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
137178884ef4SEddie Cai 		FILE* inFile) {
137278884ef4SEddie Cai 	bool ret = false;
137378884ef4SEddie Cai 	int size, i;
137478884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
137578884ef4SEddie Cai 	if (!outFile)
137678884ef4SEddie Cai 		goto end;
137778884ef4SEddie Cai 	printf("unpack entry(%s)\n", name);
137878884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
137978884ef4SEddie Cai 	size = entry->dataSize;
138078884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
138178884ef4SEddie Cai 		goto end;
138278884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
138378884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
138478884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
138578884ef4SEddie Cai 		if (size % SMALL_PACKET)
138678884ef4SEddie Cai 		{
138778884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
138878884ef4SEddie Cai 		}
138978884ef4SEddie Cai 	} else {
139078884ef4SEddie Cai 		P_RC4(gBuf, size);
139178884ef4SEddie Cai 	}
139278884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
139378884ef4SEddie Cai 		goto end;
139478884ef4SEddie Cai 	ret = true;
139578884ef4SEddie Cai end:
139678884ef4SEddie Cai 	if (outFile)
139778884ef4SEddie Cai 		fclose(outFile);
139878884ef4SEddie Cai 	return ret;
139978884ef4SEddie Cai }
140078884ef4SEddie Cai 
140178884ef4SEddie Cai bool unpackBoot(char* path) {
140278884ef4SEddie Cai 	bool ret = false;
140378884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
140478884ef4SEddie Cai 	int entryNum, i;
140578884ef4SEddie Cai 	char name[MAX_NAME_LEN];
140678884ef4SEddie Cai 	rk_boot_entry* entrys;
140778884ef4SEddie Cai 	if (!inFile) {
140878884ef4SEddie Cai 		fprintf(stderr, "loader(%s) not found\n", path);
140978884ef4SEddie Cai 		goto end;
141078884ef4SEddie Cai 	}
141178884ef4SEddie Cai 
141278884ef4SEddie Cai 	rk_boot_header hdr;
141378884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
141478884ef4SEddie Cai 		fprintf(stderr, "read header failed\n");
141578884ef4SEddie Cai 		goto end;
141678884ef4SEddie Cai 	}
141778884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
141878884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
141978884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
142078884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
142178884ef4SEddie Cai 		fprintf(stderr, "read data failed\n");
142278884ef4SEddie Cai 		goto end;
142378884ef4SEddie Cai 	}
142478884ef4SEddie Cai 
142578884ef4SEddie Cai 	printf("entry num:%d\n", entryNum);
142678884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
142778884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
142878884ef4SEddie Cai 
142978884ef4SEddie Cai 		printf("entry:t=%d, name=%s, off=%d, size=%d\n",
143078884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
143178884ef4SEddie Cai 				entrys[i].dataSize);
143278884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
143378884ef4SEddie Cai 			fprintf(stderr, "unpack entry(%s) failed\n", name);
143478884ef4SEddie Cai 			goto end;
143578884ef4SEddie Cai 		}
143678884ef4SEddie Cai 	}
143778884ef4SEddie Cai 	printf("done\n");
143878884ef4SEddie Cai 	ret = true;
143978884ef4SEddie Cai end:
144078884ef4SEddie Cai 	if (inFile)
144178884ef4SEddie Cai 		fclose(inFile);
144278884ef4SEddie Cai 	return ret;
144378884ef4SEddie Cai }
144478884ef4SEddie Cai 
144576af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
144676af099aSliuyi {
144776af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
144876af099aSliuyi 		return false;
144976af099aSliuyi 	CRKImage *pImage = NULL;
145076af099aSliuyi 	CRKBoot *pBoot = NULL;
145176af099aSliuyi 	bool bRet, bSuccess = false;
145276af099aSliuyi 	int iRet;
145376af099aSliuyi 
145476af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
145576af099aSliuyi 	if (!bRet){
145676af099aSliuyi 		ERROR_COLOR_ATTR;
145776af099aSliuyi 		printf("Open loader failed,exit download boot!");
145876af099aSliuyi 		NORMAL_COLOR_ATTR;
145976af099aSliuyi 		printf("\r\n");
146076af099aSliuyi 		return bSuccess;
146176af099aSliuyi 	} else {
146276af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
146376af099aSliuyi 		CRKComm *pComm = NULL;
146476af099aSliuyi 		CRKDevice *pDevice = NULL;
146576af099aSliuyi 
146676af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
146776af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
146876af099aSliuyi 		if (!bRet) {
146976af099aSliuyi 			if (pImage)
147076af099aSliuyi 				delete pImage;
147176af099aSliuyi 			ERROR_COLOR_ATTR;
147276af099aSliuyi 			printf("Creating Comm Object failed!");
147376af099aSliuyi 			NORMAL_COLOR_ATTR;
147476af099aSliuyi 			printf("\r\n");
147576af099aSliuyi 			return bSuccess;
147676af099aSliuyi 		}
147776af099aSliuyi 
147876af099aSliuyi 		pDevice = new CRKDevice(dev);
147976af099aSliuyi 		if (!pDevice) {
148076af099aSliuyi 			if (pImage)
148176af099aSliuyi 				delete pImage;
148276af099aSliuyi 			if (pComm)
148376af099aSliuyi 				delete pComm;
148476af099aSliuyi 			ERROR_COLOR_ATTR;
148576af099aSliuyi 			printf("Creating device object failed!");
148676af099aSliuyi 			NORMAL_COLOR_ATTR;
148776af099aSliuyi 			printf("\r\n");
148876af099aSliuyi 			return bSuccess;
148976af099aSliuyi 		}
149076af099aSliuyi 
149176af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
149276af099aSliuyi 		printf("Download boot...\r\n");
149376af099aSliuyi 		iRet = pDevice->DownloadBoot();
149476af099aSliuyi 
149576af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
149676af099aSliuyi 		CURSOR_DEL_LINE;
149776af099aSliuyi 		if (iRet == 0) {
149876af099aSliuyi 			pComm->Reset_Usb_Device();
149976af099aSliuyi 			CRKScan *pScan = NULL;
150076af099aSliuyi 			pScan = new CRKScan();
150176af099aSliuyi 			if (pScan) {
150276af099aSliuyi 				pScan->SetVidPid();
150376af099aSliuyi 				pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
150476af099aSliuyi 				delete pScan;
150576af099aSliuyi 			}
150676af099aSliuyi 			bSuccess = true;
150776af099aSliuyi 			printf("Download boot ok.\r\n");
150876af099aSliuyi 		}
150976af099aSliuyi 		else
151076af099aSliuyi 			printf("Download boot failed!\r\n");
151176af099aSliuyi 
151276af099aSliuyi 		if (pImage)
151376af099aSliuyi 			delete pImage;
151476af099aSliuyi 		if(pDevice)
151576af099aSliuyi 			delete pDevice;
151676af099aSliuyi 	}
151776af099aSliuyi 	return bSuccess;
151876af099aSliuyi }
1519c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1520c30d921cSKever Yang {
1521c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1522c30d921cSKever Yang 		return false;
1523c30d921cSKever Yang 	CRKImage *pImage = NULL;
1524c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1525c30d921cSKever Yang 	CRKComm *pComm = NULL;
1526c30d921cSKever Yang 	bool bRet, bSuccess = false;
1527c30d921cSKever Yang 	int iRet;
1528c30d921cSKever Yang 	char index;
1529c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1530c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1531c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1532c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1533c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1534c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1535c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1536c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1537c30d921cSKever Yang 	if (!bRet){
1538c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1539c30d921cSKever Yang 		printf("Open loader failed,exit upgrade loader!");
1540c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1541c30d921cSKever Yang 		printf("\r\n");
1542c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1543c30d921cSKever Yang 	} else {
1544c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1545c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1546c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1547c30d921cSKever Yang 		if (!bRet) {
1548c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1549c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1550c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1551c30d921cSKever Yang 			printf("\r\n");
1552c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1553c30d921cSKever Yang 		}
1554c30d921cSKever Yang 
1555c30d921cSKever Yang 		printf("Upgrade loader...\r\n");
1556c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1557c30d921cSKever Yang 		if (index == -1) {
1558c30d921cSKever Yang 			if (g_pLogObject) {
1559c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed");
1560c30d921cSKever Yang 			}
1561c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1562c30d921cSKever Yang 		}
1563c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1564c30d921cSKever Yang 		if (!bRet) {
1565c30d921cSKever Yang 			if (g_pLogObject) {
1566c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed");
1567c30d921cSKever Yang 			}
1568c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1569c30d921cSKever Yang 		}
1570c30d921cSKever Yang 
1571c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1572c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1573c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1574c30d921cSKever Yang 			if (g_pLogObject) {
1575c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed");
1576c30d921cSKever Yang 			}
1577c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1578c30d921cSKever Yang 		}
1579c30d921cSKever Yang 
1580c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1581c30d921cSKever Yang 		if (index == -1) {
1582c30d921cSKever Yang 			if (g_pLogObject) {
1583c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed");
1584c30d921cSKever Yang 			}
1585c30d921cSKever Yang 			delete []loaderCodeBuffer;
1586c30d921cSKever Yang 			return -4;
1587c30d921cSKever Yang 		}
1588c30d921cSKever Yang 
1589c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1590c30d921cSKever Yang 		if (!bRet) {
1591c30d921cSKever Yang 			if (g_pLogObject) {
1592c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed");
1593c30d921cSKever Yang 			}
1594c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1595c30d921cSKever Yang 		}
1596c30d921cSKever Yang 
1597c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1598c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1599c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1600c30d921cSKever Yang 			if (g_pLogObject) {
1601c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed");
1602c30d921cSKever Yang 			}
1603c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1604c30d921cSKever Yang 		}
1605c30d921cSKever Yang 
1606c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1607c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1608c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1609c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1610c30d921cSKever Yang 		if (!pIDBData) {
1611c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1612c30d921cSKever Yang 			printf("New memory failed!");
1613c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1614c30d921cSKever Yang 			printf("\r\n");
1615c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1616c30d921cSKever Yang 		}
1617c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1618c30d921cSKever Yang 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize);
1619c30d921cSKever Yang 		if (iRet != 0) {
1620c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1621c30d921cSKever Yang 			printf("Make idblock failed!");
1622c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1623c30d921cSKever Yang 			printf("\r\n");
1624c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1625c30d921cSKever Yang 		}
1626c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1627c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1628c30d921cSKever Yang 		CURSOR_DEL_LINE;
1629c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1630c30d921cSKever Yang 			pComm->Reset_Usb_Device();
1631c30d921cSKever Yang 			bSuccess = true;
1632c30d921cSKever Yang 			printf("Upgrade loader ok.\r\n");
1633c30d921cSKever Yang 		} else {
1634c30d921cSKever Yang 			printf("Upgrade loader failed!\r\n");
1635c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1636c30d921cSKever Yang 		}
1637c30d921cSKever Yang 	}
1638c30d921cSKever Yang Exit_UpgradeLoader:
1639c30d921cSKever Yang 	if (pImage)
1640c30d921cSKever Yang 		delete pImage;
1641c30d921cSKever Yang 	if (pComm)
1642c30d921cSKever Yang 		delete pComm;
1643c30d921cSKever Yang 	if (loaderCodeBuffer)
1644c30d921cSKever Yang 		delete []loaderCodeBuffer;
1645c30d921cSKever Yang 	if (loaderDataBuffer)
1646c30d921cSKever Yang 		delete []loaderDataBuffer;
1647c30d921cSKever Yang 	if (pIDBData)
1648c30d921cSKever Yang 		delete []pIDBData;
1649c30d921cSKever Yang 	return bSuccess;
1650c30d921cSKever Yang }
1651c30d921cSKever Yang 
165276af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
165376af099aSliuyi {
165476af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
165576af099aSliuyi 		return false;
165676af099aSliuyi 	CRKImage *pImage = NULL;
165776af099aSliuyi 	bool bRet, bSuccess = false;
165876af099aSliuyi 	int iRet;
165976af099aSliuyi 	CRKScan *pScan = NULL;
166076af099aSliuyi 	pScan = new CRKScan();
166176af099aSliuyi 	pScan->SetVidPid();
166276af099aSliuyi 
166376af099aSliuyi 	CRKComm *pComm = NULL;
166476af099aSliuyi 	CRKDevice *pDevice = NULL;
166576af099aSliuyi 
166676af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
166776af099aSliuyi 	if (!bRet) {
166876af099aSliuyi 		if (pScan)
166976af099aSliuyi 			delete pScan;
167076af099aSliuyi 		ERROR_COLOR_ATTR;
167176af099aSliuyi 		printf("Creating Comm Object failed!");
167276af099aSliuyi 		NORMAL_COLOR_ATTR;
167376af099aSliuyi 		printf("\r\n");
167476af099aSliuyi 		return bSuccess;
167576af099aSliuyi 	}
167676af099aSliuyi 
167776af099aSliuyi 	pDevice = new CRKDevice(dev);
167876af099aSliuyi 	if (!pDevice) {
167976af099aSliuyi 		if (pComm)
168076af099aSliuyi 			delete pComm;
168176af099aSliuyi 		if (pScan)
168276af099aSliuyi 			delete pScan;
168376af099aSliuyi 		ERROR_COLOR_ATTR;
168476af099aSliuyi 		printf("Creating device object failed!");
168576af099aSliuyi 		NORMAL_COLOR_ATTR;
168676af099aSliuyi 		printf("\r\n");
168776af099aSliuyi 		return bSuccess;
168876af099aSliuyi 	}
168976af099aSliuyi 
169076af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
169176af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
169276af099aSliuyi 
169376af099aSliuyi 	printf("Start to erase flash...\r\n");
169476af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
169576af099aSliuyi 	if (pDevice)
169676af099aSliuyi 		delete pDevice;
169776af099aSliuyi 
169876af099aSliuyi 	if (iRet == 0) {
169976af099aSliuyi 		if (pScan) {
170076af099aSliuyi 			pScan->SetVidPid();
170176af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
170276af099aSliuyi 			delete pScan;
170376af099aSliuyi 		}
170476af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
170576af099aSliuyi 		CURSOR_DEL_LINE;
170676af099aSliuyi 		bSuccess = true;
170776af099aSliuyi 		printf("Erase flash ok.\r\n");
170876af099aSliuyi 	}
170976af099aSliuyi 
171076af099aSliuyi 	return bSuccess;
171176af099aSliuyi }
171276af099aSliuyi 
171376af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
171476af099aSliuyi {
171576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
171676af099aSliuyi 		return false;
171776af099aSliuyi 	CRKUsbComm *pComm = NULL;
171876af099aSliuyi 	bool bRet, bSuccess = false;
171976af099aSliuyi 	int iRet;
172076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
172176af099aSliuyi 	if (bRet) {
172276af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
172376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
172476af099aSliuyi 			if (g_pLogObject)
172576af099aSliuyi 				g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet);
172676af099aSliuyi 			printf("Test Device Fail!\r\n");
172776af099aSliuyi 		} else {
172876af099aSliuyi 			bSuccess = true;
172976af099aSliuyi 			printf("Test Device OK.\r\n");
173076af099aSliuyi 		}
173176af099aSliuyi 	} else {
173276af099aSliuyi 		printf("Test Device quit,Creating comm object failed!\r\n");
173376af099aSliuyi 	}
173476af099aSliuyi 	if (pComm) {
173576af099aSliuyi 		delete pComm;
173676af099aSliuyi 		pComm = NULL;
173776af099aSliuyi 	}
173876af099aSliuyi 	return bSuccess;
173976af099aSliuyi }
174076af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
174176af099aSliuyi {
174276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
174376af099aSliuyi 		return false;
174476af099aSliuyi 	CRKUsbComm *pComm = NULL;
174576af099aSliuyi 	bool bRet, bSuccess = false;
174676af099aSliuyi 	int iRet;
174776af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
174876af099aSliuyi 	if (bRet) {
174976af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
175076af099aSliuyi 		if (iRet != ERR_SUCCESS) {
175176af099aSliuyi 			if (g_pLogObject)
175276af099aSliuyi 				g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet);
175376af099aSliuyi 			printf("Reset Device Fail!\r\n");
175476af099aSliuyi 		} else {
175576af099aSliuyi 			bSuccess = true;
175676af099aSliuyi 			printf("Reset Device OK.\r\n");
175776af099aSliuyi 		}
175876af099aSliuyi 	} else {
175976af099aSliuyi 		printf("Reset Device quit,Creating comm object failed!\r\n");
176076af099aSliuyi 	}
176176af099aSliuyi 	if (pComm) {
176276af099aSliuyi 		delete pComm;
176376af099aSliuyi 		pComm = NULL;
176476af099aSliuyi 	}
176576af099aSliuyi 	return bSuccess;
176676af099aSliuyi }
176776af099aSliuyi 
176876af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
176976af099aSliuyi {
177076af099aSliuyi 	CRKUsbComm *pComm = NULL;
177176af099aSliuyi 	bool bRet, bSuccess = false;
177276af099aSliuyi 	int iRet;
177376af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
177476af099aSliuyi 		return bSuccess;
177576af099aSliuyi 
177676af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
177776af099aSliuyi 	if (bRet) {
177876af099aSliuyi 		BYTE flashID[5];
177976af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
178076af099aSliuyi 		if (iRet != ERR_SUCCESS) {
178176af099aSliuyi 			if (g_pLogObject)
178276af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet);
178376af099aSliuyi 			printf("Read flash ID Fail!\r\n");
178476af099aSliuyi 		} else {
178576af099aSliuyi 			printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
178676af099aSliuyi 			bSuccess = true;
178776af099aSliuyi 		}
178876af099aSliuyi 	} else {
178976af099aSliuyi 		printf("Read flash ID quit,Creating comm object failed!\r\n");
179076af099aSliuyi 	}
179176af099aSliuyi 	if (pComm) {
179276af099aSliuyi 		delete pComm;
179376af099aSliuyi 		pComm = NULL;
179476af099aSliuyi 	}
179576af099aSliuyi 	return bSuccess;
179676af099aSliuyi }
179776af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
179876af099aSliuyi {
179976af099aSliuyi 	CRKUsbComm *pComm = NULL;
180076af099aSliuyi 	bool bRet, bSuccess = false;
180176af099aSliuyi 	int iRet;
180276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
180376af099aSliuyi 		return bSuccess;
180476af099aSliuyi 
180576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
180676af099aSliuyi 	if (bRet) {
180776af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
180876af099aSliuyi 		UINT uiRead;
180976af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
181076af099aSliuyi 		if (iRet != ERR_SUCCESS) {
181176af099aSliuyi 			if (g_pLogObject)
181276af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet);
181376af099aSliuyi 			printf("Read flash Info Fail!\r\n");
181476af099aSliuyi 		} else {
181576af099aSliuyi 			printf("Flash Info:\r\n");
181676af099aSliuyi 			if (info.bManufCode <= 7) {
181776af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
181876af099aSliuyi 			}
181976af099aSliuyi 			else
182076af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode);
182176af099aSliuyi 
182276af099aSliuyi 			printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024);
182376af099aSliuyi 			printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2);
182476af099aSliuyi 			printf("\tPage Size: %dKB\r\n", info.bPageSize / 2);
182576af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
182676af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
182776af099aSliuyi 			printf("\tFlash CS: ");
182876af099aSliuyi 			for(int i = 0; i < 8; i++) {
182976af099aSliuyi 				if( info.bFlashCS & (1 << i) )
183076af099aSliuyi 					printf("Flash<%d> ", i);
183176af099aSliuyi 			}
183276af099aSliuyi 			printf("\r\n");
183376af099aSliuyi 			bSuccess = true;
183476af099aSliuyi 		}
183576af099aSliuyi 	}else {
183676af099aSliuyi 		printf("Read flash Info quit,Creating comm object failed!\r\n");
183776af099aSliuyi 	}
183876af099aSliuyi 	if (pComm) {
183976af099aSliuyi 		delete pComm;
184076af099aSliuyi 		pComm = NULL;
184176af099aSliuyi 	}
184276af099aSliuyi 	return bSuccess;
184376af099aSliuyi }
184476af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
184576af099aSliuyi {
184676af099aSliuyi 	CRKUsbComm *pComm = NULL;
184776af099aSliuyi 	bool bRet, bSuccess = false;
184876af099aSliuyi 	int iRet;
184976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
185076af099aSliuyi 		return bSuccess;
185176af099aSliuyi 
185276af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
185376af099aSliuyi 	if (bRet) {
185476af099aSliuyi 		BYTE chipInfo[16];
185576af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
185676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
185776af099aSliuyi 			if (g_pLogObject)
185876af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet);
185976af099aSliuyi 			printf("Read Chip Info Fail!\r\n");
186076af099aSliuyi 		} else {
186176af099aSliuyi 			string strChipInfo;
186276af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
186376af099aSliuyi 			printf("Chip Info:%s\r\n", strChipInfo.c_str());
186476af099aSliuyi 			bSuccess = true;
186576af099aSliuyi 		}
186676af099aSliuyi 	} else {
186776af099aSliuyi 		printf("Read Chip Info quit,Creating comm object failed!\r\n");
186876af099aSliuyi 	}
186976af099aSliuyi 	if (pComm) {
187076af099aSliuyi 		delete pComm;
187176af099aSliuyi 		pComm = NULL;
187276af099aSliuyi 	}
187376af099aSliuyi 	return bSuccess;
187476af099aSliuyi }
187576af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
187676af099aSliuyi {
187776af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
187876af099aSliuyi 		return false;
187976af099aSliuyi 	CRKUsbComm *pComm = NULL;
188076af099aSliuyi 	FILE *file = NULL;
188176af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
188276af099aSliuyi 	int iRet;
188376af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
188476af099aSliuyi 	int nSectorSize = 512;
188576af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
188676af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
188776af099aSliuyi 	if (bRet) {
188876af099aSliuyi 		if(szFile) {
188976af099aSliuyi 			file = fopen(szFile, "wb+");
189076af099aSliuyi 			if( !file ) {
189176af099aSliuyi 				printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
189276af099aSliuyi 				goto Exit_ReadLBA;
189376af099aSliuyi 			}
189476af099aSliuyi 		}
189576af099aSliuyi 
189676af099aSliuyi 		while(uiLen > 0) {
189776af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
189876af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
189976af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
190076af099aSliuyi 			if(ERR_SUCCESS == iRet) {
190176af099aSliuyi 				uiLen -= iRead;
190276af099aSliuyi 				iTotalRead += iRead;
190376af099aSliuyi 
190476af099aSliuyi 				if(szFile) {
190576af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
190676af099aSliuyi 					if (bFirst){
190776af099aSliuyi 						if (iTotalRead >= 1024)
190876af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
190976af099aSliuyi 						else
191076af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
191176af099aSliuyi 						bFirst = false;
191276af099aSliuyi 					} else {
191376af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
191476af099aSliuyi 						CURSOR_DEL_LINE;
191576af099aSliuyi 						if (iTotalRead >= 1024)
191676af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
191776af099aSliuyi 						else
191876af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
191976af099aSliuyi 					}
192076af099aSliuyi 				}
192176af099aSliuyi 				else
192276af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
192376af099aSliuyi 			} else {
192476af099aSliuyi 				if (g_pLogObject)
192576af099aSliuyi 					g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet);
192676af099aSliuyi 
192776af099aSliuyi 				printf("Read LBA failed!\r\n");
192876af099aSliuyi 				goto Exit_ReadLBA;
192976af099aSliuyi 			}
193076af099aSliuyi 		}
193176af099aSliuyi 		bSuccess = true;
193276af099aSliuyi 	} else {
193376af099aSliuyi 		printf("Read LBA quit,Creating comm object failed!\r\n");
193476af099aSliuyi 	}
193576af099aSliuyi Exit_ReadLBA:
193676af099aSliuyi 	if (pComm) {
193776af099aSliuyi 		delete pComm;
193876af099aSliuyi 		pComm = NULL;
193976af099aSliuyi 	}
194076af099aSliuyi 	if (file)
194176af099aSliuyi 		fclose(file);
194276af099aSliuyi 	return bSuccess;
194376af099aSliuyi }
194476af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
194576af099aSliuyi {
194676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
194776af099aSliuyi 		return false;
194876af099aSliuyi 	CRKUsbComm *pComm = NULL;
194976af099aSliuyi 	FILE *file = NULL;
195076af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
195176af099aSliuyi 	int iRet;
195276af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
195376af099aSliuyi 	UINT iWrite = 0, iRead = 0;
195476af099aSliuyi 	UINT uiLen;
195576af099aSliuyi 	int nSectorSize = 512;
195676af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
195776af099aSliuyi 
195876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
195976af099aSliuyi 	if (bRet) {
196076af099aSliuyi 		file = fopen(szFile, "rb");
196176af099aSliuyi 		if( !file ) {
196276af099aSliuyi 			printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
196376af099aSliuyi 			goto Exit_WriteLBA;
196476af099aSliuyi 		}
196576af099aSliuyi 
196676af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
196776af099aSliuyi 		iFileSize = ftello(file);
196876af099aSliuyi 		fseeko(file, 0, SEEK_SET);
196976af099aSliuyi 		while(iTotalWrite < iFileSize) {
197076af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
197176af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
197276af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
197376af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
197476af099aSliuyi 			if(ERR_SUCCESS == iRet) {
197576af099aSliuyi 				uiBegin += uiLen;
197676af099aSliuyi 				iTotalWrite += iWrite;
197776af099aSliuyi 				if (bFirst) {
197876af099aSliuyi 					if (iTotalWrite >= 1024)
197976af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
198076af099aSliuyi 					else
198176af099aSliuyi 						printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
198276af099aSliuyi 					bFirst = false;
198376af099aSliuyi 				} else {
198476af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
198576af099aSliuyi 					CURSOR_DEL_LINE;
198676af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
198776af099aSliuyi 				}
198876af099aSliuyi 			} else {
198976af099aSliuyi 				if (g_pLogObject)
199076af099aSliuyi 					g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
199176af099aSliuyi 
199276af099aSliuyi 				printf("Write LBA failed!\r\n");
199376af099aSliuyi 				goto Exit_WriteLBA;
199476af099aSliuyi 			}
199576af099aSliuyi 		}
199676af099aSliuyi 		bSuccess = true;
199776af099aSliuyi 	} else {
199876af099aSliuyi 		printf("Write LBA quit,Creating comm object failed!\r\n");
199976af099aSliuyi 	}
200076af099aSliuyi Exit_WriteLBA:
200176af099aSliuyi 	if (pComm) {
200276af099aSliuyi 		delete pComm;
200376af099aSliuyi 		pComm = NULL;
200476af099aSliuyi 	}
200576af099aSliuyi 	if (file)
200676af099aSliuyi 		fclose(file);
200776af099aSliuyi 	return bSuccess;
200876af099aSliuyi }
200976af099aSliuyi 
201076af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
201176af099aSliuyi {
201276af099aSliuyi 	string strItem;
201376af099aSliuyi 	char szItem[100];
201476af099aSliuyi 	char *pos = NULL, *pStart;
201576af099aSliuyi 	pStart = pszItems;
201676af099aSliuyi 	pos = strchr(pStart, ',');
201776af099aSliuyi 	while(pos != NULL) {
201876af099aSliuyi 		memset(szItem, 0, 100);
201976af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
202076af099aSliuyi 		strItem = szItem;
202176af099aSliuyi 		vecItems.push_back(strItem);
202276af099aSliuyi 		pStart = pos + 1;
202376af099aSliuyi 		if (*pStart == 0)
202476af099aSliuyi 			break;
202576af099aSliuyi 		pos = strchr(pStart, ',');
202676af099aSliuyi 	}
202776af099aSliuyi 	if (strlen(pStart) > 0) {
202876af099aSliuyi 		memset(szItem, 0, 100);
202976af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
203076af099aSliuyi 		strItem = szItem;
203176af099aSliuyi 		vecItems.push_back(strItem);
203276af099aSliuyi 	}
203376af099aSliuyi }
2034c30d921cSKever Yang 
203576af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
203676af099aSliuyi {
203776af099aSliuyi 	string strCmd;
203876af099aSliuyi 	strCmd = argv[1];
203976af099aSliuyi 	ssize_t cnt;
204076af099aSliuyi 	bool bRet,bSuccess = false;
20418df2d64aSEddie Cai 	char *s;
20428df2d64aSEddie Cai 	int i, ret;
204376af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
204476af099aSliuyi 
204576af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
20468df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
20478df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
20488df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
204978884ef4SEddie Cai 
20508df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
205176af099aSliuyi 		usage();
205276af099aSliuyi 		return true;
20538df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2054c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
205576af099aSliuyi 		return true;
205678884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
205778884ef4SEddie Cai 		mergeBoot();
205878884ef4SEddie Cai 
205978884ef4SEddie Cai 		return true;
206078884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
206178884ef4SEddie Cai 		string strLoader = argv[2];
206278884ef4SEddie Cai 
206378884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
206478884ef4SEddie Cai 		return true;
206576af099aSliuyi 	}
206676af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
206776af099aSliuyi 	if (cnt < 1) {
206876af099aSliuyi 		ERROR_COLOR_ATTR;
206976af099aSliuyi 		printf("No found any rockusb device,please plug device in!");
207076af099aSliuyi 		NORMAL_COLOR_ATTR;
207176af099aSliuyi 		printf("\r\n");
207276af099aSliuyi 		return bSuccess;
207376af099aSliuyi 	} else if (cnt > 1) {
207476af099aSliuyi 		ERROR_COLOR_ATTR;
207576af099aSliuyi 		printf("Found many rockusb devices,please plug device out!");
207676af099aSliuyi 		NORMAL_COLOR_ATTR;
207776af099aSliuyi 		printf("\r\n");
207876af099aSliuyi 		return bSuccess;
207976af099aSliuyi 	}
208076af099aSliuyi 
208176af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
208276af099aSliuyi 	if (!bRet) {
208376af099aSliuyi 		ERROR_COLOR_ATTR;
208476af099aSliuyi 		printf("Getting information of rockusb device failed!");
208576af099aSliuyi 		NORMAL_COLOR_ATTR;
208676af099aSliuyi 		printf("\r\n");
208776af099aSliuyi 		return bSuccess;
208876af099aSliuyi 	}
208976af099aSliuyi 
209076af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
209176af099aSliuyi 		if ((argc != 2) && (argc != 3))
209276af099aSliuyi 			printf("Parameter of [RD] command is invalid,please check help!\r\n");
209376af099aSliuyi 		else {
209476af099aSliuyi 			if (argc == 2)
209576af099aSliuyi 				bSuccess = reset_device(dev);
209676af099aSliuyi 			else {
209776af099aSliuyi 				UINT uiSubCode;
209876af099aSliuyi 				char *pszEnd;
209976af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
210076af099aSliuyi 				if (*pszEnd)
210176af099aSliuyi 					printf("Subcode is invalid,please check!\r\n");
210276af099aSliuyi 				else {
210376af099aSliuyi 					if (uiSubCode <= 5)
210476af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
210576af099aSliuyi 					else
210676af099aSliuyi 						printf("Subcode is invalid,please check!\r\n");
210776af099aSliuyi 				}
210876af099aSliuyi 			}
210976af099aSliuyi 		}
211076af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
211176af099aSliuyi 		bSuccess = test_device(dev);
211276af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
211376af099aSliuyi 		bSuccess = read_flash_id(dev);
211476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
211576af099aSliuyi 		bSuccess = read_flash_info(dev);
211676af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
211776af099aSliuyi 		bSuccess = read_chip_info(dev);
211876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
211976af099aSliuyi 		if (argc > 2) {
212076af099aSliuyi 			string strLoader;
212176af099aSliuyi 			strLoader = argv[2];
212276af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
212376af099aSliuyi 		} else if (argc == 2) {
212476af099aSliuyi 			ret = find_config_item("loader");
212576af099aSliuyi 			if (ret == -1)
212676af099aSliuyi 				printf("No found loader item from config!\r\n");
212776af099aSliuyi 			else
212876af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
212976af099aSliuyi 		} else
213076af099aSliuyi 			printf("Parameter of [DB] command is invalid,please check help!\r\n");
2131c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
2132c30d921cSKever Yang 		if (argc > 2) {
2133c30d921cSKever Yang 			string strParameter;
2134c30d921cSKever Yang 			strParameter = argv[2];
2135c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
2136c30d921cSKever Yang 		} else
2137c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid,please check help!\r\n");
2138c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
2139c30d921cSKever Yang 		if (argc > 2) {
2140c30d921cSKever Yang 			string strLoader;
2141c30d921cSKever Yang 			strLoader = argv[2];
2142c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
2143c30d921cSKever Yang 		} else
2144c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid,please check help!\r\n");
214576af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
214676af099aSliuyi 		if (argc == 2) {
214776af099aSliuyi 			bSuccess = erase_flash(dev);
214876af099aSliuyi 		} else
214976af099aSliuyi 			printf("Parameter of [EF] command is invalid,please check help!\r\n");
215076af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
215176af099aSliuyi 		if (argc == 4) {
215276af099aSliuyi 			UINT uiBegin;
215376af099aSliuyi 			char *pszEnd;
215476af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
215576af099aSliuyi 			if (*pszEnd)
215676af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
215776af099aSliuyi 			else
215876af099aSliuyi 				bSuccess = write_lba(dev, uiBegin, argv[3]);
215976af099aSliuyi 		} else
216076af099aSliuyi 			printf("Parameter of [WL] command is invalid,please check help!\r\n");
216176af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
216276af099aSliuyi 		char *pszEnd;
216376af099aSliuyi 		UINT uiBegin, uiLen;
216476af099aSliuyi 		if (argc != 5)
216576af099aSliuyi 			printf("Parameter of [RL] command is invalid,please check help!\r\n");
216676af099aSliuyi 		else {
216776af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
216876af099aSliuyi 			if (*pszEnd)
216976af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
217076af099aSliuyi 			else {
217176af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
217276af099aSliuyi 				if (*pszEnd)
217376af099aSliuyi 					printf("Len is invalid,please check!\r\n");
217476af099aSliuyi 				else {
217576af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
217676af099aSliuyi 				}
217776af099aSliuyi 			}
217876af099aSliuyi 		}
217976af099aSliuyi 	} else {
2180c30d921cSKever Yang 		printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n");
218176af099aSliuyi 	}
218276af099aSliuyi 	return bSuccess;
218376af099aSliuyi }
218476af099aSliuyi 
218576af099aSliuyi 
218676af099aSliuyi int main(int argc, char* argv[])
218776af099aSliuyi {
218876af099aSliuyi 	CRKScan *pScan = NULL;
218976af099aSliuyi 	int ret;
219076af099aSliuyi 	char szProgramProcPath[100];
219176af099aSliuyi 	char szProgramDir[256];
219276af099aSliuyi 	string strLogDir,strConfigFile;
219376af099aSliuyi 	struct stat statBuf;
219476af099aSliuyi 
219576af099aSliuyi 	g_ConfigItemVec.clear();
219676af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
219776af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
219876af099aSliuyi 		strcpy(szProgramDir, ".");
219976af099aSliuyi 	else {
220076af099aSliuyi 		char *pSlash;
220176af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
220276af099aSliuyi 		if (pSlash)
220376af099aSliuyi 			*pSlash = '\0';
220476af099aSliuyi 	}
220576af099aSliuyi 	strLogDir = szProgramDir;
220676af099aSliuyi 	strLogDir +=  "/log/";
220776af099aSliuyi 	strConfigFile = szProgramDir;
220876af099aSliuyi 	strConfigFile += "/config.ini";
220976af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
221076af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
221176af099aSliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
221276af099aSliuyi 
221376af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
221476af099aSliuyi 		if (g_pLogObject) {
221576af099aSliuyi 			g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
221676af099aSliuyi 		}
221776af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
221876af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
221976af099aSliuyi 	}
222076af099aSliuyi 
222176af099aSliuyi 	ret = libusb_init(NULL);
222276af099aSliuyi 	if (ret < 0) {
222376af099aSliuyi 		if (g_pLogObject) {
222476af099aSliuyi 			g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
222576af099aSliuyi 			delete g_pLogObject;
222676af099aSliuyi 		}
222776af099aSliuyi 		return -1;
222876af099aSliuyi 	}
222976af099aSliuyi 
223076af099aSliuyi 	pScan = new CRKScan();
223176af099aSliuyi 	if (!pScan) {
223276af099aSliuyi 		if (g_pLogObject) {
223376af099aSliuyi 			g_pLogObject->Record("Error:failed to Create object for searching device");
223476af099aSliuyi 			delete g_pLogObject;
223576af099aSliuyi 		}
223676af099aSliuyi 		libusb_exit(NULL);
223776af099aSliuyi 		return -2;
223876af099aSliuyi 	}
223976af099aSliuyi 	pScan->SetVidPid();
224076af099aSliuyi 
224176af099aSliuyi 	if (argc == 1)
224276af099aSliuyi 		usage();
224376af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
224476af099aSliuyi 			return -0xFF;
224576af099aSliuyi 	if (pScan)
224676af099aSliuyi 		delete pScan;
224776af099aSliuyi 	if (g_pLogObject)
224876af099aSliuyi 		delete g_pLogObject;
224976af099aSliuyi 	libusb_exit(NULL);
225076af099aSliuyi 	return 0;
225176af099aSliuyi }
2252