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