xref: /rkdeveloptool/main.cpp (revision 5b7562f2de7374e1e6d47cfc37120a2d9cd243f1)
1 /*
2  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
3  * Seth Liu 2017.03.01
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include   <unistd.h>
9 #include   <dirent.h>
10 #include "DefineHeader.h"
11 #include "RKLog.h"
12 #include "RKScan.h"
13 #include "RKComm.h"
14 #include "RKDevice.h"
15 #include "RKImage.h"
16 extern const char *szManufName[];
17 CRKLog *g_pLogObject=NULL;
18 CONFIG_ITEM_VECTOR g_ConfigItemVec;
19 #define DEFAULT_RW_LBA 128
20 #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
21 #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
22 #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
23 #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
24 #define ERROR_COLOR_ATTR  printf("%c[30;41m", 0x1B);
25 #define NORMAL_COLOR_ATTR  printf("%c[37;40m", 0x1B);
26 void usage()
27 {
28 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
29 	printf("Help:             -H\r\n");
30 	printf("Version:          -V\r\n");
31 	printf("DownloadBoot:	DB <Loader>\r\n");
32 	printf("ReadLBA:		RL  <BeginSec> <SectorLen> <File>\r\n");
33 	printf("WriteLBA:		WL  <BeginSec> <File>\r\n");
34 	printf("EraseFlash:		EF \r\n");
35 	printf("TestDevice:		TD\r\n");
36 	printf("ResetDevice:	RD [subcode]\r\n");
37 	printf("ReadFlashID:	RID\r\n");
38 	printf("ReadFlashInfo:	RFI\r\n");
39 	printf("ReadChipInfo:	RCI\r\n");
40 	printf("-------------------------------------------------------\r\n\r\n");
41 }
42 void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
43 {
44 	string strInfoText="";
45 	char szText[256];
46 	switch (promptID) {
47 	case TESTDEVICE_PROGRESS:
48 		sprintf(szText, "Test Device Total(%lld),Current(%lld)", totalValue, currentValue);
49 		strInfoText = szText;
50 		break;
51 	case LOWERFORMAT_PROGRESS:
52 		sprintf(szText, "Lowerformat Device Total(%lld),Current(%lld)", totalValue, currentValue);
53 		strInfoText = szText;
54 		break;
55 	case DOWNLOADIMAGE_PROGRESS:
56 		sprintf(szText, "Download Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
57 		strInfoText = szText;
58 		break;
59 	case CHECKIMAGE_PROGRESS:
60 		sprintf(szText, "Check Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
61 		strInfoText = szText;
62 		break;
63 	case TAGBADBLOCK_PROGRESS:
64 		sprintf(szText, "Tag Bad Block Total(%lld),Current(%lld)", totalValue, currentValue);
65 		strInfoText = szText;
66 		break;
67 	case TESTBLOCK_PROGRESS:
68 		sprintf(szText, "Test Block Total(%lld),Current(%lld)", totalValue, currentValue);
69 		strInfoText = szText;
70 		break;
71 	case ERASEFLASH_PROGRESS:
72 		sprintf(szText, "Erase Flash Total(%lld),Current(%lld)", totalValue, currentValue);
73 		strInfoText = szText;
74 		break;
75 	case ERASESYSTEM_PROGRESS:
76 		sprintf(szText, "Erase System partition Total(%lld),Current(%lld)", totalValue, currentValue);
77 		strInfoText = szText;
78 		break;
79 	case ERASEUSERDATA_PROGRESS:
80 		sprintf(szText, "<LocationID=%x> Erase Userdata partition Total(%lld),Current(%lld)",deviceLayer,totalValue, currentValue);
81 		strInfoText = szText;
82 		break;
83 	}
84 	if (strInfoText.size() > 0){
85 		CURSOR_MOVEUP_LINE(1);
86 		CURSOR_DEL_LINE;
87 		printf("%s\r\n", strInfoText.c_str());
88 	}
89 	if (emCall == CALL_LAST)
90 		deviceLayer = 0;
91 }
92 
93 char *strupr(char *szSrc)
94 {
95 	char *p = szSrc;
96 	while(*p){
97 		if ((*p >= 'a') && (*p <= 'z'))
98 			*p = *p - 'a' + 'A';
99 		p++;
100 	}
101 	return szSrc;
102 }
103 void PrintData(PBYTE pData, int nSize)
104 {
105 	char szPrint[17] = "\0";
106 	int i;
107 	for( i = 0; i < nSize; i++){
108 		if(i % 16 == 0){
109 			if(i / 16 > 0)
110 				printf("     %s\r\n", szPrint);
111 			printf("%08d ", i / 16);
112 		}
113 		printf("%02X ", pData[i]);
114 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
115 	}
116 	if(i / 16 > 0)
117 		printf("     %s\r\n", szPrint);
118 }
119 
120 bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
121 {
122 	if (!pszSrc)
123 		return false;
124 	int nSrcLen = strlen(pszSrc);
125 	int nDestLen = nSrcLen * 2;
126 
127 	pszDest = NULL;
128 	pszDest = new wchar_t[nDestLen];
129 	if (!pszDest)
130 		return false;
131 	nDestLen = nDestLen * sizeof(wchar_t);
132 	memset(pszDest, 0, nDestLen);
133 	int iRet;
134 	iconv_t cd;
135 	cd = iconv_open("UTF-32", "UTF-8");
136 	if((iconv_t)-1 == cd) {
137 		delete []pszDest;
138 		pszDest = NULL;
139 	      return false;
140 	 }
141 	char *pIn, *pOut;
142 	pIn = (char *)pszSrc;
143 	pOut = (char *)pszDest;
144 
145 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
146 
147 	if(iRet == -1) {
148 		delete []pszDest;
149 		pszDest = NULL;
150 		iconv_close(cd);
151 		return false;
152 	 }
153 
154 	 iconv_close(cd);
155 
156 	 return true;
157 }
158 bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
159 {
160 	if (!pszSrc)
161 		return false;
162 	int nSrcLen = wcslen(pszSrc);
163 	int nDestLen = nSrcLen * 2;
164 	nSrcLen = nSrcLen * sizeof(wchar_t);
165 	pszDest = NULL;
166 	pszDest = new char[nDestLen];
167 	if (!pszDest)
168 		return false;
169 	memset(pszDest, 0, nDestLen);
170 	int iRet;
171 	iconv_t cd;
172 	cd = iconv_open("UTF-8", "UTF-32");
173 
174 	if((iconv_t)-1 == cd) {
175 		delete []pszDest;
176 		pszDest = NULL;
177 	      return false;
178 	 }
179 	char *pIn, *pOut;
180 	pIn = (char *)pszSrc;
181 	pOut = (char *)pszDest;
182 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
183 
184 	if(iRet == -1) {
185 		delete []pszDest;
186 		pszDest = NULL;
187 		iconv_close(cd);
188 		return false;
189 	 }
190 
191 	 iconv_close(cd);
192 
193 	 return true;
194 }
195 int find_config_item(const char *pszName)
196 {
197 	unsigned int i;
198 	for(i = 0; i < g_ConfigItemVec.size(); i++){
199 		if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){
200 			return i;
201 		}
202 	}
203 	return -1;
204 }
205 
206 bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
207 {
208 
209 	stringstream configStream(pConfig);
210 	string strLine, strItemName, strItemValue;
211 	string::size_type line_size,pos;
212 	STRUCT_CONFIG_ITEM item;
213 	vecItem.clear();
214 	while (!configStream.eof()){
215 		getline(configStream, strLine);
216 		line_size = strLine.size();
217 		if (line_size == 0)
218 			continue;
219 		if (strLine[line_size-1] == '\r'){
220 			strLine = strLine.substr(0, line_size-1);
221 		}
222 		pos = strLine.find("=");
223 		if (pos == string::npos){
224 			continue;
225 		}
226 		strItemName = strLine.substr(0, pos);
227 		strItemValue = strLine.substr(pos + 1);
228 		strItemName.erase(0, strItemName.find_first_not_of(" "));
229 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
230 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
231 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
232 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
233 			strcpy(item.szItemName, strItemName.c_str());
234 			strcpy(item.szItemValue, strItemValue.c_str());
235 			vecItem.push_back(item);
236 		}
237 	}
238 	return true;
239 
240 }
241 bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
242 {
243 	FILE *file = NULL;
244 	file = fopen(pConfigFile, "rb");
245 	if( !file ){
246 		if (g_pLogObject)
247 			g_pLogObject->Record("parse_config_file failed,err=%d,can't open file: %s\r\n", errno, pConfigFile);
248 		return false;
249 	}
250 	int iFileSize;
251 	fseek(file, 0, SEEK_END);
252 	iFileSize = ftell(file);
253 	fseek(file, 0, SEEK_SET);
254 	char *pConfigBuf = NULL;
255 	pConfigBuf = new char[iFileSize + 1];
256 	if (!pConfigBuf){
257 		fclose(file);
258 		return false;
259 	}
260 	memset(pConfigBuf, 0, iFileSize + 1);
261 	int iRead;
262 	iRead = fread(pConfigBuf, 1, iFileSize, file);
263 	if (iRead != iFileSize){
264 		if (g_pLogObject)
265 			g_pLogObject->Record("parse_config_file failed,err=%d, read=%d, total=%d\r\n", errno, iRead, iFileSize);
266 		fclose(file);
267 		delete []pConfigBuf;
268 		return false;
269 	}
270 	fclose(file);
271 	bool bRet;
272 	bRet = parse_config(pConfigBuf, vecItem);
273 	delete []pConfigBuf;
274 	return bRet;
275 }
276 
277 bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
278 {
279 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
280 		return true;
281 	else
282 	{
283 		ERROR_COLOR_ATTR;
284 		printf("The  Device did not support this operation!");
285 		NORMAL_COLOR_ATTR;
286 		printf("\r\n");
287 		return false;
288 	}
289 }
290 
291 bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
292 {
293 	if (!check_device_type(dev, RKUSB_MASKROM))
294 		return false;
295 	CRKImage *pImage = NULL;
296 	CRKBoot *pBoot = NULL;
297 	bool bRet, bSuccess = false;
298 	int iRet;
299 
300 	pImage = new CRKImage(szLoader, bRet);
301 	if (!bRet){
302 		ERROR_COLOR_ATTR;
303 		printf("Open loader failed,exit download boot!");
304 		NORMAL_COLOR_ATTR;
305 		printf("\r\n");
306 		return bSuccess;
307 	} else {
308 		pBoot = (CRKBoot *)pImage->m_bootObject;
309 		CRKComm *pComm = NULL;
310 		CRKDevice *pDevice = NULL;
311 
312 		dev.emDeviceType = pBoot->SupportDevice;
313 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
314 		if (!bRet) {
315 			if (pImage)
316 				delete pImage;
317 			ERROR_COLOR_ATTR;
318 			printf("Creating Comm Object failed!");
319 			NORMAL_COLOR_ATTR;
320 			printf("\r\n");
321 			return bSuccess;
322 		}
323 
324 		pDevice = new CRKDevice(dev);
325 		if (!pDevice) {
326 			if (pImage)
327 				delete pImage;
328 			if (pComm)
329 				delete pComm;
330 			ERROR_COLOR_ATTR;
331 			printf("Creating device object failed!");
332 			NORMAL_COLOR_ATTR;
333 			printf("\r\n");
334 			return bSuccess;
335 		}
336 
337 		pDevice->SetObject(pImage, pComm, g_pLogObject);
338 		printf("Download boot...\r\n");
339 		iRet = pDevice->DownloadBoot();
340 
341 		CURSOR_MOVEUP_LINE(1);
342 		CURSOR_DEL_LINE;
343 		if (iRet == 0) {
344 			pComm->Reset_Usb_Device();
345 			CRKScan *pScan = NULL;
346 			pScan = new CRKScan();
347 			if (pScan) {
348 				pScan->SetVidPid();
349 				pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
350 				delete pScan;
351 			}
352 			bSuccess = true;
353 			printf("Download boot ok.\r\n");
354 		}
355 		else
356 			printf("Download boot failed!\r\n");
357 
358 		if (pImage)
359 			delete pImage;
360 		if(pDevice)
361 			delete pDevice;
362 	}
363 	return bSuccess;
364 }
365 bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
366 {
367 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
368 		return false;
369 	CRKImage *pImage = NULL;
370 	bool bRet, bSuccess = false;
371 	int iRet;
372 	CRKScan *pScan = NULL;
373 	pScan = new CRKScan();
374 	pScan->SetVidPid();
375 
376 	CRKComm *pComm = NULL;
377 	CRKDevice *pDevice = NULL;
378 
379 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
380 	if (!bRet) {
381 		if (pScan)
382 			delete pScan;
383 		ERROR_COLOR_ATTR;
384 		printf("Creating Comm Object failed!");
385 		NORMAL_COLOR_ATTR;
386 		printf("\r\n");
387 		return bSuccess;
388 	}
389 
390 	pDevice = new CRKDevice(dev);
391 	if (!pDevice) {
392 		if (pComm)
393 			delete pComm;
394 		if (pScan)
395 			delete pScan;
396 		ERROR_COLOR_ATTR;
397 		printf("Creating device object failed!");
398 		NORMAL_COLOR_ATTR;
399 		printf("\r\n");
400 		return bSuccess;
401 	}
402 
403 	pDevice->SetObject(pImage, pComm, g_pLogObject);
404 	pDevice->CallBackPointer = ProgressInfoProc;
405 
406 	printf("Start to erase flash...\r\n");
407 	iRet = pDevice->EraseAllBlocks();
408 	if (pDevice)
409 		delete pDevice;
410 
411 	if (iRet == 0) {
412 		if (pScan) {
413 			pScan->SetVidPid();
414 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
415 			delete pScan;
416 		}
417 		CURSOR_MOVEUP_LINE(1);
418 		CURSOR_DEL_LINE;
419 		bSuccess = true;
420 		printf("Erase flash ok.\r\n");
421 	}
422 
423 	return bSuccess;
424 }
425 
426 bool test_device(STRUCT_RKDEVICE_DESC &dev)
427 {
428 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
429 		return false;
430 	CRKUsbComm *pComm = NULL;
431 	bool bRet, bSuccess = false;
432 	int iRet;
433 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
434 	if (bRet) {
435 		iRet = pComm->RKU_TestDeviceReady();
436 		if (iRet != ERR_SUCCESS) {
437 			if (g_pLogObject)
438 				g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet);
439 			printf("Test Device Fail!\r\n");
440 		} else {
441 			bSuccess = true;
442 			printf("Test Device OK.\r\n");
443 		}
444 	} else {
445 		printf("Test Device quit,Creating comm object failed!\r\n");
446 	}
447 	if (pComm) {
448 		delete pComm;
449 		pComm = NULL;
450 	}
451 	return bSuccess;
452 }
453 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
454 {
455 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
456 		return false;
457 	CRKUsbComm *pComm = NULL;
458 	bool bRet, bSuccess = false;
459 	int iRet;
460 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
461 	if (bRet) {
462 		iRet = pComm->RKU_ResetDevice(subCode);
463 		if (iRet != ERR_SUCCESS) {
464 			if (g_pLogObject)
465 				g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet);
466 			printf("Reset Device Fail!\r\n");
467 		} else {
468 			bSuccess = true;
469 			printf("Reset Device OK.\r\n");
470 		}
471 	} else {
472 		printf("Reset Device quit,Creating comm object failed!\r\n");
473 	}
474 	if (pComm) {
475 		delete pComm;
476 		pComm = NULL;
477 	}
478 	return bSuccess;
479 }
480 
481 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
482 {
483 	CRKUsbComm *pComm = NULL;
484 	bool bRet, bSuccess = false;
485 	int iRet;
486 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
487 		return bSuccess;
488 
489 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
490 	if (bRet) {
491 		BYTE flashID[5];
492 		iRet = pComm->RKU_ReadFlashID(flashID);
493 		if (iRet != ERR_SUCCESS) {
494 			if (g_pLogObject)
495 				g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet);
496 			printf("Read flash ID Fail!\r\n");
497 		} else {
498 			printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
499 			bSuccess = true;
500 		}
501 	} else {
502 		printf("Read flash ID quit,Creating comm object failed!\r\n");
503 	}
504 	if (pComm) {
505 		delete pComm;
506 		pComm = NULL;
507 	}
508 	return bSuccess;
509 }
510 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
511 {
512 	CRKUsbComm *pComm = NULL;
513 	bool bRet, bSuccess = false;
514 	int iRet;
515 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
516 		return bSuccess;
517 
518 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
519 	if (bRet) {
520 		STRUCT_FLASHINFO_CMD info;
521 		UINT uiRead;
522 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
523 		if (iRet != ERR_SUCCESS) {
524 			if (g_pLogObject)
525 				g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet);
526 			printf("Read flash Info Fail!\r\n");
527 		} else {
528 			printf("Flash Info:\r\n");
529 			if (info.bManufCode <= 7) {
530 				printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
531 			}
532 			else
533 				printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode);
534 
535 			printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024);
536 			printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2);
537 			printf("\tPage Size: %dKB\r\n", info.bPageSize / 2);
538 			printf("\tECC Bits: %d\r\n", info.bECCBits);
539 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
540 			printf("\tFlash CS: ");
541 			for(int i = 0; i < 8; i++) {
542 				if( info.bFlashCS & (1 << i) )
543 					printf("Flash<%d> ", i);
544 			}
545 			printf("\r\n");
546 			bSuccess = true;
547 		}
548 	}else {
549 		printf("Read flash Info quit,Creating comm object failed!\r\n");
550 	}
551 	if (pComm) {
552 		delete pComm;
553 		pComm = NULL;
554 	}
555 	return bSuccess;
556 }
557 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
558 {
559 	CRKUsbComm *pComm = NULL;
560 	bool bRet, bSuccess = false;
561 	int iRet;
562 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
563 		return bSuccess;
564 
565 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
566 	if (bRet) {
567 		BYTE chipInfo[16];
568 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
569 		if (iRet != ERR_SUCCESS) {
570 			if (g_pLogObject)
571 				g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet);
572 			printf("Read Chip Info Fail!\r\n");
573 		} else {
574 			string strChipInfo;
575 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
576 			printf("Chip Info:%s\r\n", strChipInfo.c_str());
577 			bSuccess = true;
578 		}
579 	} else {
580 		printf("Read Chip Info quit,Creating comm object failed!\r\n");
581 	}
582 	if (pComm) {
583 		delete pComm;
584 		pComm = NULL;
585 	}
586 	return bSuccess;
587 }
588 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
589 {
590 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
591 		return false;
592 	CRKUsbComm *pComm = NULL;
593 	FILE *file = NULL;
594 	bool bRet, bFirst = true, bSuccess = false;
595 	int iRet;
596 	UINT iTotalRead = 0,iRead = 0;
597 	int nSectorSize = 512;
598 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
599 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
600 	if (bRet) {
601 		if(szFile) {
602 			file = fopen(szFile, "wb+");
603 			if( !file ) {
604 				printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
605 				goto Exit_ReadLBA;
606 			}
607 		}
608 
609 		while(uiLen > 0) {
610 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
611 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
612 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
613 			if(ERR_SUCCESS == iRet) {
614 				uiLen -= iRead;
615 				iTotalRead += iRead;
616 
617 				if(szFile) {
618 					fwrite(pBuf, 1, iRead * nSectorSize, file);
619 					if (bFirst){
620 						if (iTotalRead >= 1024)
621 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
622 						else
623 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
624 						bFirst = false;
625 					} else {
626 						CURSOR_MOVEUP_LINE(1);
627 						CURSOR_DEL_LINE;
628 						if (iTotalRead >= 1024)
629 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
630 						else
631 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
632 					}
633 				}
634 				else
635 					PrintData(pBuf, nSectorSize * iRead);
636 			} else {
637 				if (g_pLogObject)
638 					g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet);
639 
640 				printf("Read LBA failed!\r\n");
641 				goto Exit_ReadLBA;
642 			}
643 		}
644 		bSuccess = true;
645 	} else {
646 		printf("Read LBA quit,Creating comm object failed!\r\n");
647 	}
648 Exit_ReadLBA:
649 	if (pComm) {
650 		delete pComm;
651 		pComm = NULL;
652 	}
653 	if (file)
654 		fclose(file);
655 	return bSuccess;
656 }
657 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
658 {
659 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
660 		return false;
661 	CRKUsbComm *pComm = NULL;
662 	FILE *file = NULL;
663 	bool bRet, bFirst = true, bSuccess = false;
664 	int iRet;
665 	long long iTotalWrite = 0, iFileSize = 0;
666 	UINT iWrite = 0, iRead = 0;
667 	UINT uiLen;
668 	int nSectorSize = 512;
669 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
670 
671 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
672 	if (bRet) {
673 		file = fopen(szFile, "rb");
674 		if( !file ) {
675 			printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
676 			goto Exit_WriteLBA;
677 		}
678 
679 		iRet = fseeko(file, 0, SEEK_END);
680 		iFileSize = ftello(file);
681 		fseeko(file, 0, SEEK_SET);
682 		while(iTotalWrite < iFileSize) {
683 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
684 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
685 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
686 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
687 			if(ERR_SUCCESS == iRet) {
688 				uiBegin += uiLen;
689 				iTotalWrite += iWrite;
690 				if (bFirst) {
691 					if (iTotalWrite >= 1024)
692 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
693 					else
694 						printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
695 					bFirst = false;
696 				} else {
697 					CURSOR_MOVEUP_LINE(1);
698 					CURSOR_DEL_LINE;
699 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
700 				}
701 			} else {
702 				if (g_pLogObject)
703 					g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
704 
705 				printf("Write LBA failed!\r\n");
706 				goto Exit_WriteLBA;
707 			}
708 		}
709 		bSuccess = true;
710 	} else {
711 		printf("Write LBA quit,Creating comm object failed!\r\n");
712 	}
713 Exit_WriteLBA:
714 	if (pComm) {
715 		delete pComm;
716 		pComm = NULL;
717 	}
718 	if (file)
719 		fclose(file);
720 	return bSuccess;
721 }
722 
723 void split_item(STRING_VECTOR &vecItems, char *pszItems)
724 {
725 	string strItem;
726 	char szItem[100];
727 	char *pos = NULL, *pStart;
728 	pStart = pszItems;
729 	pos = strchr(pStart, ',');
730 	while(pos != NULL) {
731 		memset(szItem, 0, 100);
732 		strncpy(szItem, pStart, pos - pStart);
733 		strItem = szItem;
734 		vecItems.push_back(strItem);
735 		pStart = pos + 1;
736 		if (*pStart == 0)
737 			break;
738 		pos = strchr(pStart, ',');
739 	}
740 	if (strlen(pStart) > 0) {
741 		memset(szItem, 0, 100);
742 		strncpy(szItem, pStart, strlen(pStart));
743 		strItem = szItem;
744 		vecItems.push_back(strItem);
745 	}
746 }
747 bool handle_command(int argc, char* argv[], CRKScan *pScan)
748 {
749 	string strCmd;
750 	strCmd = argv[1];
751 	ssize_t cnt;
752 	bool bRet,bSuccess = false;
753 	int ret;
754 	STRUCT_RKDEVICE_DESC dev;
755 
756 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
757 	if(strcmp(strCmd.c_str(), "-H") == 0) {
758 		usage();
759 		return true;
760 	} else if(strcmp(strCmd.c_str(), "-V") == 0) {
761 		printf("rkDevelopTool ver 1.0\r\n");
762 		return true;
763 	}
764 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
765 	if (cnt < 1) {
766 		ERROR_COLOR_ATTR;
767 		printf("No found any rockusb device,please plug device in!");
768 		NORMAL_COLOR_ATTR;
769 		printf("\r\n");
770 		return bSuccess;
771 	} else if (cnt > 1) {
772 		ERROR_COLOR_ATTR;
773 		printf("Found many rockusb devices,please plug device out!");
774 		NORMAL_COLOR_ATTR;
775 		printf("\r\n");
776 		return bSuccess;
777 	}
778 
779 	bRet = pScan->GetDevice(dev, 0);
780 	if (!bRet) {
781 		ERROR_COLOR_ATTR;
782 		printf("Getting information of rockusb device failed!");
783 		NORMAL_COLOR_ATTR;
784 		printf("\r\n");
785 		return bSuccess;
786 	}
787 
788 	if(strcmp(strCmd.c_str(), "RD") == 0) {
789 		if ((argc != 2) && (argc != 3))
790 			printf("Parameter of [RD] command is invalid,please check help!\r\n");
791 		else {
792 			if (argc == 2)
793 				bSuccess = reset_device(dev);
794 			else {
795 				UINT uiSubCode;
796 				char *pszEnd;
797 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
798 				if (*pszEnd)
799 					printf("Subcode is invalid,please check!\r\n");
800 				else {
801 					if (uiSubCode <= 5)
802 						bSuccess = reset_device(dev, uiSubCode);
803 					else
804 						printf("Subcode is invalid,please check!\r\n");
805 				}
806 			}
807 		}
808 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
809 		bSuccess = test_device(dev);
810 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
811 		bSuccess = read_flash_id(dev);
812 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
813 		bSuccess = read_flash_info(dev);
814 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
815 		bSuccess = read_chip_info(dev);
816 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
817 		if (argc > 2) {
818 			string strLoader;
819 			strLoader = argv[2];
820 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
821 		} else if (argc == 2) {
822 			ret = find_config_item("loader");
823 			if (ret == -1)
824 				printf("No found loader item from config!\r\n");
825 			else
826 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
827 		} else
828 			printf("Parameter of [DB] command is invalid,please check help!\r\n");
829 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
830 		if (argc == 2) {
831 			bSuccess = erase_flash(dev);
832 		} else
833 			printf("Parameter of [EF] command is invalid,please check help!\r\n");
834 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
835 		if (argc == 4) {
836 			UINT uiBegin;
837 			char *pszEnd;
838 			uiBegin = strtoul(argv[2], &pszEnd, 0);
839 			if (*pszEnd)
840 				printf("Begin is invalid,please check!\r\n");
841 			else
842 				bSuccess = write_lba(dev, uiBegin, argv[3]);
843 		} else
844 			printf("Parameter of [WL] command is invalid,please check help!\r\n");
845 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
846 		char *pszEnd;
847 		UINT uiBegin, uiLen;
848 		if (argc != 5)
849 			printf("Parameter of [RL] command is invalid,please check help!\r\n");
850 		else {
851 			uiBegin = strtoul(argv[2], &pszEnd, 0);
852 			if (*pszEnd)
853 				printf("Begin is invalid,please check!\r\n");
854 			else {
855 				uiLen = strtoul(argv[3], &pszEnd, 0);
856 				if (*pszEnd)
857 					printf("Len is invalid,please check!\r\n");
858 				else {
859 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
860 				}
861 			}
862 		}
863 	} else {
864 		printf("command is invalid,please press upgrade_tool -h to check usage!\r\n");
865 	}
866 	return bSuccess;
867 }
868 
869 
870 
871 int main(int argc, char* argv[])
872 {
873 	CRKScan *pScan = NULL;
874 	int ret;
875 	char szProgramProcPath[100];
876 	char szProgramDir[256];
877 	string strLogDir,strConfigFile;
878 	struct stat statBuf;
879 
880 	g_ConfigItemVec.clear();
881 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
882 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
883 		strcpy(szProgramDir, ".");
884 	else {
885 		char *pSlash;
886 		pSlash = strrchr(szProgramDir, '/');
887 		if (pSlash)
888 			*pSlash = '\0';
889 	}
890 	strLogDir = szProgramDir;
891 	strLogDir +=  "/log/";
892 	strConfigFile = szProgramDir;
893 	strConfigFile += "/config.ini";
894 	if (opendir(strLogDir.c_str()) == NULL)
895 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
896 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
897 
898 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
899 		if (g_pLogObject) {
900 			g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
901 		}
902 	} else if (S_ISREG(statBuf.st_mode)) {
903 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
904 	}
905 
906 	ret = libusb_init(NULL);
907 	if (ret < 0) {
908 		if (g_pLogObject) {
909 			g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
910 			delete g_pLogObject;
911 		}
912 		return -1;
913 	}
914 
915 	pScan = new CRKScan();
916 	if (!pScan) {
917 		if (g_pLogObject) {
918 			g_pLogObject->Record("Error:failed to Create object for searching device");
919 			delete g_pLogObject;
920 		}
921 		libusb_exit(NULL);
922 		return -2;
923 	}
924 	pScan->SetVidPid();
925 
926 	if (argc == 1)
927 		usage();
928 	else if (!handle_command(argc, argv, pScan))
929 			return -0xFF;
930 	if (pScan)
931 		delete pScan;
932 	if (g_pLogObject)
933 		delete g_pLogObject;
934 	libusb_exit(NULL);
935 	return 0;
936 }
937