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