xref: /rkdeveloptool/main.cpp (revision 76af099afcbcafd97801028de2ba3421d3c12865)
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 			if ((int)iRead != nSectorSize * DEFAULT_RW_LBA) {
686 				printf("Write LBA failed,err=%d,read=%d,total=%d!\r\n", errno, iRead, nSectorSize * DEFAULT_RW_LBA);
687 				goto Exit_WriteLBA;
688 			}
689 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
690 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
691 			if(ERR_SUCCESS == iRet) {
692 				uiBegin += uiLen;
693 				iTotalWrite += iWrite;
694 				if (bFirst) {
695 					if (iTotalWrite >= 1024)
696 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
697 					else
698 						printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
699 					bFirst = false;
700 				} else {
701 					CURSOR_MOVEUP_LINE(1);
702 					CURSOR_DEL_LINE;
703 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
704 				}
705 			} else {
706 				if (g_pLogObject)
707 					g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
708 
709 				printf("Write LBA failed!\r\n");
710 				goto Exit_WriteLBA;
711 			}
712 		}
713 		bSuccess = true;
714 	} else {
715 		printf("Write LBA quit,Creating comm object failed!\r\n");
716 	}
717 Exit_WriteLBA:
718 	if (pComm) {
719 		delete pComm;
720 		pComm = NULL;
721 	}
722 	if (file)
723 		fclose(file);
724 	return bSuccess;
725 }
726 
727 void split_item(STRING_VECTOR &vecItems, char *pszItems)
728 {
729 	string strItem;
730 	char szItem[100];
731 	char *pos = NULL, *pStart;
732 	pStart = pszItems;
733 	pos = strchr(pStart, ',');
734 	while(pos != NULL) {
735 		memset(szItem, 0, 100);
736 		strncpy(szItem, pStart, pos - pStart);
737 		strItem = szItem;
738 		vecItems.push_back(strItem);
739 		pStart = pos + 1;
740 		if (*pStart == 0)
741 			break;
742 		pos = strchr(pStart, ',');
743 	}
744 	if (strlen(pStart) > 0) {
745 		memset(szItem, 0, 100);
746 		strncpy(szItem, pStart, strlen(pStart));
747 		strItem = szItem;
748 		vecItems.push_back(strItem);
749 	}
750 }
751 bool handle_command(int argc, char* argv[], CRKScan *pScan)
752 {
753 	string strCmd;
754 	strCmd = argv[1];
755 	ssize_t cnt;
756 	bool bRet,bSuccess = false;
757 	int ret;
758 	STRUCT_RKDEVICE_DESC dev;
759 
760 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
761 	if(strcmp(strCmd.c_str(), "-H") == 0) {
762 		usage();
763 		return true;
764 	} else if(strcmp(strCmd.c_str(), "-V") == 0) {
765 		printf("rkDevelopTool ver 1.0\r\n");
766 		return true;
767 	}
768 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
769 	if (cnt < 1) {
770 		ERROR_COLOR_ATTR;
771 		printf("No found any rockusb device,please plug device in!");
772 		NORMAL_COLOR_ATTR;
773 		printf("\r\n");
774 		return bSuccess;
775 	} else if (cnt > 1) {
776 		ERROR_COLOR_ATTR;
777 		printf("Found many rockusb devices,please plug device out!");
778 		NORMAL_COLOR_ATTR;
779 		printf("\r\n");
780 		return bSuccess;
781 	}
782 
783 	bRet = pScan->GetDevice(dev, 0);
784 	if (!bRet) {
785 		ERROR_COLOR_ATTR;
786 		printf("Getting information of rockusb device failed!");
787 		NORMAL_COLOR_ATTR;
788 		printf("\r\n");
789 		return bSuccess;
790 	}
791 
792 	if(strcmp(strCmd.c_str(), "RD") == 0) {
793 		if ((argc != 2) && (argc != 3))
794 			printf("Parameter of [RD] command is invalid,please check help!\r\n");
795 		else {
796 			if (argc == 2)
797 				bSuccess = reset_device(dev);
798 			else {
799 				UINT uiSubCode;
800 				char *pszEnd;
801 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
802 				if (*pszEnd)
803 					printf("Subcode is invalid,please check!\r\n");
804 				else {
805 					if (uiSubCode <= 5)
806 						bSuccess = reset_device(dev, uiSubCode);
807 					else
808 						printf("Subcode is invalid,please check!\r\n");
809 				}
810 			}
811 		}
812 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
813 		bSuccess = test_device(dev);
814 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
815 		bSuccess = read_flash_id(dev);
816 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
817 		bSuccess = read_flash_info(dev);
818 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
819 		bSuccess = read_chip_info(dev);
820 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
821 		if (argc > 2) {
822 			string strLoader;
823 			strLoader = argv[2];
824 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
825 		} else if (argc == 2) {
826 			ret = find_config_item("loader");
827 			if (ret == -1)
828 				printf("No found loader item from config!\r\n");
829 			else
830 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
831 		} else
832 			printf("Parameter of [DB] command is invalid,please check help!\r\n");
833 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
834 		if (argc == 2) {
835 			bSuccess = erase_flash(dev);
836 		} else
837 			printf("Parameter of [EF] command is invalid,please check help!\r\n");
838 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
839 		if (argc == 4) {
840 			UINT uiBegin;
841 			char *pszEnd;
842 			uiBegin = strtoul(argv[2], &pszEnd, 0);
843 			if (*pszEnd)
844 				printf("Begin is invalid,please check!\r\n");
845 			else
846 				bSuccess = write_lba(dev, uiBegin, argv[3]);
847 		} else
848 			printf("Parameter of [WL] command is invalid,please check help!\r\n");
849 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
850 		char *pszEnd;
851 		UINT uiBegin, uiLen;
852 		if (argc != 5)
853 			printf("Parameter of [RL] command is invalid,please check help!\r\n");
854 		else {
855 			uiBegin = strtoul(argv[2], &pszEnd, 0);
856 			if (*pszEnd)
857 				printf("Begin is invalid,please check!\r\n");
858 			else {
859 				uiLen = strtoul(argv[3], &pszEnd, 0);
860 				if (*pszEnd)
861 					printf("Len is invalid,please check!\r\n");
862 				else {
863 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
864 				}
865 			}
866 		}
867 	} else {
868 		printf("command is invalid,please press upgrade_tool -h to check usage!\r\n");
869 	}
870 	return bSuccess;
871 }
872 
873 
874 
875 int main(int argc, char* argv[])
876 {
877 	CRKScan *pScan = NULL;
878 	int ret;
879 	char szProgramProcPath[100];
880 	char szProgramDir[256];
881 	string strLogDir,strConfigFile;
882 	struct stat statBuf;
883 
884 	g_ConfigItemVec.clear();
885 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
886 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
887 		strcpy(szProgramDir, ".");
888 	else {
889 		char *pSlash;
890 		pSlash = strrchr(szProgramDir, '/');
891 		if (pSlash)
892 			*pSlash = '\0';
893 	}
894 	strLogDir = szProgramDir;
895 	strLogDir +=  "/log/";
896 	strConfigFile = szProgramDir;
897 	strConfigFile += "/config.ini";
898 	if (opendir(strLogDir.c_str()) == NULL)
899 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
900 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
901 
902 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
903 		if (g_pLogObject) {
904 			g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
905 		}
906 	} else if (S_ISREG(statBuf.st_mode)) {
907 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
908 	}
909 
910 	ret = libusb_init(NULL);
911 	if (ret < 0) {
912 		if (g_pLogObject) {
913 			g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
914 			delete g_pLogObject;
915 		}
916 		return -1;
917 	}
918 
919 	pScan = new CRKScan();
920 	if (!pScan) {
921 		if (g_pLogObject) {
922 			g_pLogObject->Record("Error:failed to Create object for searching device");
923 			delete g_pLogObject;
924 		}
925 		libusb_exit(NULL);
926 		return -2;
927 	}
928 	pScan->SetVidPid();
929 
930 	if (argc == 1)
931 		usage();
932 	else if (!handle_command(argc, argv, pScan))
933 			return -0xFF;
934 	if (pScan)
935 		delete pScan;
936 	if (g_pLogObject)
937 		delete g_pLogObject;
938 	libusb_exit(NULL);
939 	return 0;
940 }
941