mirror of
https://github.com/sharkcz/rkdeveloptool.git
synced 2024-11-22 14:06:47 +01:00
rkDevelopTool: initial commit
Signed-off-by: liuyi <liuyi@rock-chips.com>
This commit is contained in:
commit
76af099afc
117
DefineHeader.h
Normal file
117
DefineHeader.h
Normal file
@ -0,0 +1,117 @@
|
||||
#ifndef DEFINE_HEADER
|
||||
#define DEFINE_HEADER
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <iconv.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <libusb.h>
|
||||
|
||||
#include "Property.hpp"
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
typedef unsigned char BYTE, *PBYTE;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned short WCHAR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned int DWORD;
|
||||
|
||||
typedef enum{
|
||||
RKNONE_DEVICE = 0,
|
||||
RK27_DEVICE = 0x10,
|
||||
RKCAYMAN_DEVICE,
|
||||
RK28_DEVICE = 0x20,
|
||||
RK281X_DEVICE,
|
||||
RKPANDA_DEVICE,
|
||||
RKNANO_DEVICE = 0x30,
|
||||
RKSMART_DEVICE,
|
||||
RKCROWN_DEVICE = 0x40,
|
||||
RK29_DEVICE = 0x50,
|
||||
RK292X_DEVICE,
|
||||
RK30_DEVICE = 0x60,
|
||||
RK30B_DEVICE,
|
||||
RK31_DEVICE = 0x70,
|
||||
RK32_DEVICE = 0x80
|
||||
} ENUM_RKDEVICE_TYPE;
|
||||
typedef enum{
|
||||
RK_OS = 0,
|
||||
ANDROID_OS = 0x1
|
||||
} ENUM_OS_TYPE;
|
||||
|
||||
typedef enum{
|
||||
RKUSB_NONE = 0x0,
|
||||
RKUSB_MASKROM = 0x01,
|
||||
RKUSB_LOADER = 0x02,
|
||||
RKUSB_MSC = 0x04
|
||||
} ENUM_RKUSB_TYPE;
|
||||
typedef enum{
|
||||
ENTRY471 = 1,
|
||||
ENTRY472 = 2,
|
||||
ENTRYLOADER = 4
|
||||
} ENUM_RKBOOTENTRY;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct{
|
||||
USHORT usYear;
|
||||
BYTE ucMonth;
|
||||
BYTE ucDay;
|
||||
BYTE ucHour;
|
||||
BYTE ucMinute;
|
||||
BYTE ucSecond;
|
||||
} STRUCT_RKTIME, *PSTRUCT_RKTIME;
|
||||
|
||||
typedef struct{
|
||||
char szItemName[20];
|
||||
char szItemValue[256];
|
||||
} STRUCT_CONFIG_ITEM, *PSTRUCT_CONFIG_ITEM;
|
||||
typedef struct _STRUCT_RKDEVICE_DESC{
|
||||
USHORT usVid;
|
||||
USHORT usPid;
|
||||
USHORT usbcdUsb;
|
||||
UINT uiLocationID;
|
||||
ENUM_RKUSB_TYPE emUsbType;
|
||||
ENUM_RKDEVICE_TYPE emDeviceType;
|
||||
void *pUsbHandle;
|
||||
} STRUCT_RKDEVICE_DESC, *PSTRUCT_RKDEVICE_DESC;
|
||||
#pragma pack()
|
||||
typedef list<STRUCT_RKDEVICE_DESC> RKDEVICE_DESC_SET;
|
||||
typedef RKDEVICE_DESC_SET::iterator device_list_iter;
|
||||
typedef vector<string> STRING_VECTOR;
|
||||
typedef vector<UINT> UINT_VECTOR;
|
||||
typedef vector<STRUCT_CONFIG_ITEM> CONFIG_ITEM_VECTOR;
|
||||
typedef enum{
|
||||
TESTDEVICE_PROGRESS,
|
||||
DOWNLOADIMAGE_PROGRESS,
|
||||
CHECKIMAGE_PROGRESS,
|
||||
TAGBADBLOCK_PROGRESS,
|
||||
TESTBLOCK_PROGRESS,
|
||||
ERASEFLASH_PROGRESS,
|
||||
ERASESYSTEM_PROGRESS,
|
||||
LOWERFORMAT_PROGRESS,
|
||||
ERASEUSERDATA_PROGRESS
|
||||
} ENUM_PROGRESS_PROMPT;
|
||||
|
||||
typedef enum{
|
||||
CALL_FIRST,
|
||||
CALL_MIDDLE,
|
||||
CALL_LAST
|
||||
} ENUM_CALL_STEP;
|
||||
|
||||
typedef void (*ProgressPromptCB)(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall);
|
||||
|
||||
bool WideStringToString(wchar_t *pszSrc, char *&pszDest);
|
||||
bool StringToWideString(char *pszSrc, wchar_t *&pszDest);
|
||||
#endif
|
21
Endian.h
Normal file
21
Endian.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef ENDIAN_HEADER
|
||||
#define ENDIAN_HEADER
|
||||
|
||||
#define Endian16_Swap(value) (((((unsigned short)value) << 8) & 0xFF00)|\
|
||||
((((unsigned short)value) >> 8) & 0x00FF))
|
||||
|
||||
#define Endian32_Swap(value) (((((unsigned int)value) << 24) & 0xFF000000) |\
|
||||
((((unsigned int)value) << 8) & 0x00FF0000) |\
|
||||
((((unsigned int)value) >> 8) & 0x0000FF00) |\
|
||||
((((unsigned int)value) >> 24) & 0x000000FF))
|
||||
|
||||
#define EndianS16_LtoB(value) ((short)Endian16_Swap(value))
|
||||
#define EndianS16_BtoL(value) ((short)Endian16_Swap(value))
|
||||
#define EndianU16_LtoB(value) ((unsigned short)Endian16_Swap(value))
|
||||
#define EndianU16_BtoL(value) ((unsigned short)Endian16_Swap(value))
|
||||
#define EndianS32_LtoB(value) ((int)Endian32_Swap(value))
|
||||
#define EndianS32_BtoL(value) ((int)Endian32_Swap(value))
|
||||
#define EndianU32_LtoB(value) ((unsigned int)Endian32_Swap(value))
|
||||
#define EndianU32_BtoL(value) ((unsigned int)Endian32_Swap(value))
|
||||
|
||||
#endif
|
24
Makefile
Normal file
24
Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
# Simple Makefile for RK Flash Tool
|
||||
|
||||
CC = g++
|
||||
LD = $(CC)
|
||||
CXXFLAGS = -O2 -Wall -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -I/usr/local/include/libusb-1.0
|
||||
LDFLAGS = -L/usr/local/lib -Wl,-Bstatic -lusb-1.0 -Wl,-Bdynamic -lrt -lpthread
|
||||
|
||||
|
||||
PROGS = $(patsubst %.cpp,%.o, $(wildcard *.cpp))
|
||||
|
||||
rkDevelopTool: $(PROGS)
|
||||
$(CC) $(CXXFLAGS) $^ -o rkDevelopTool $(LDFLAGS)
|
||||
|
||||
install: $(PROGS)
|
||||
install -d -m 0755 /usr/local/bin
|
||||
install -m 0755 ./rkDevelopTool /usr/local/bin
|
||||
|
||||
clean:
|
||||
rm $(PROGS) ./rkDevelopTool
|
||||
|
||||
uninstall:
|
||||
cd /usr/local/bin && rm -f ./rkDevelopTool
|
||||
|
||||
|
94
Property.hpp
Normal file
94
Property.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
//-- Property.hpp --
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Class Library
|
||||
|
||||
Copyrights Emad Barsoum (ebarsoum@msn.com) 2003. All rights reserved.
|
||||
________________________________________________________________
|
||||
|
||||
|
||||
PROJECT : General
|
||||
MODULE : property
|
||||
FILENAME : Property.hpp
|
||||
BUILD : 1
|
||||
|
||||
History of Modifications:
|
||||
|
||||
Date(dd/mm/yyyy)Person Description
|
||||
---- ------ -----------
|
||||
25/03/2003 Emad Barsoum Initial design and coding
|
||||
|
||||
CLASS NAME: property
|
||||
VERSION: 1.0
|
||||
|
||||
DESCRIPTION:
|
||||
This class try to simulate property for C++, using template technique.
|
||||
|
||||
LICENSE:
|
||||
You are free to change or modify or redistribute the code, just keep the header.
|
||||
And you can use this class in any application you want without any warranty.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#if !defined INC_PROPERTY_HPP
|
||||
#define INC_PROPERTY_HPP
|
||||
|
||||
#define READ_ONLY 1
|
||||
#define WRITE_ONLY 2
|
||||
#define READ_WRITE 3
|
||||
|
||||
template<typename Container, typename ValueType, int nPropType>
|
||||
class property
|
||||
{
|
||||
public:
|
||||
property()
|
||||
{
|
||||
m_cObject = NULL;
|
||||
Set = NULL;
|
||||
Get = NULL;
|
||||
}
|
||||
//-- This to set a pointer to the class that contain the property --
|
||||
void setContainer(Container* cObject)
|
||||
{
|
||||
m_cObject = cObject;
|
||||
}
|
||||
//-- Set the set member function that will change the value --
|
||||
void setter(void (Container::*pSet)(ValueType value))
|
||||
{
|
||||
if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
|
||||
Set = pSet;
|
||||
else
|
||||
Set = NULL;
|
||||
}
|
||||
//-- Set the get member function that will retrieve the value --
|
||||
void getter(ValueType (Container::*pGet)())
|
||||
{
|
||||
if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
|
||||
Get = pGet;
|
||||
else
|
||||
Get = NULL;
|
||||
}
|
||||
//-- Overload the '=' sign to set the value using the set member --
|
||||
ValueType operator =(const ValueType& value)
|
||||
{
|
||||
assert(m_cObject != NULL);
|
||||
assert(Set != NULL);
|
||||
(m_cObject->*Set)(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
//-- To make possible to cast the property class to the internal type --
|
||||
operator ValueType()
|
||||
{
|
||||
assert(m_cObject != NULL);
|
||||
assert(Get != NULL);
|
||||
return (m_cObject->*Get)();
|
||||
}
|
||||
|
||||
private:
|
||||
Container* m_cObject;//-- Pointer to the module that contain the property --
|
||||
void (Container::*Set)(ValueType value);//-- Pointer to set member function --
|
||||
ValueType (Container::*Get)();//-- Pointer to get member function --
|
||||
};
|
||||
|
||||
#endif
|
314
RKBoot.cpp
Normal file
314
RKBoot.cpp
Normal file
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include "RKBoot.h"
|
||||
extern UINT CRC_32(PBYTE pData, UINT ulSize);
|
||||
bool CRKBoot::GetRc4DisableFlag()
|
||||
{
|
||||
return m_bRc4Disable;
|
||||
}
|
||||
bool CRKBoot::GetSignFlag()
|
||||
{
|
||||
return m_bSignFlag;
|
||||
}
|
||||
DWORD CRKBoot::GetVersion()
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
DWORD CRKBoot::GetMergeVersion()
|
||||
{
|
||||
return m_mergeVersion;
|
||||
}
|
||||
STRUCT_RKTIME CRKBoot::GetReleaseTime()
|
||||
{
|
||||
return m_releaseTime;
|
||||
}
|
||||
ENUM_RKDEVICE_TYPE CRKBoot::GetSupportDevice()
|
||||
{
|
||||
return m_supportDevice;
|
||||
}
|
||||
UCHAR CRKBoot::GetEntry471Count()
|
||||
{
|
||||
return m_471Count;
|
||||
}
|
||||
UCHAR CRKBoot::GetEntry472Count()
|
||||
{
|
||||
return m_472Count;
|
||||
}
|
||||
UCHAR CRKBoot::GetEntryLoaderCount()
|
||||
{
|
||||
return m_loaderCount;
|
||||
}
|
||||
bool CRKBoot::CrcCheck()
|
||||
{
|
||||
UINT*pOldCrc,ulNewCrc;
|
||||
pOldCrc = (UINT*)(m_BootData+(m_BootSize-4));
|
||||
ulNewCrc = CRC_32(m_BootData,m_BootSize-4);
|
||||
return (*pOldCrc==ulNewCrc)?true:false;
|
||||
}
|
||||
bool CRKBoot::SaveEntryFile(ENUM_RKBOOTENTRY type,UCHAR ucIndex,string fileName)
|
||||
{
|
||||
DWORD dwOffset;
|
||||
UCHAR ucCount,ucSize;
|
||||
switch ( type )
|
||||
{
|
||||
case ENTRY471:
|
||||
dwOffset = m_471Offset;
|
||||
ucCount = m_471Count;
|
||||
ucSize = m_471Size;
|
||||
break;
|
||||
case ENTRY472:
|
||||
dwOffset = m_472Offset;
|
||||
ucCount = m_472Count;
|
||||
ucSize = m_472Size;
|
||||
break;
|
||||
case ENTRYLOADER:
|
||||
dwOffset = m_loaderOffset;
|
||||
ucCount = m_loaderCount;
|
||||
ucSize = m_loaderSize;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (ucIndex >= ucCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PSTRUCT_RKBOOT_ENTRY pEntry;
|
||||
pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex));
|
||||
FILE *file=NULL;
|
||||
file = fopen(fileName.c_str(),"wb+");
|
||||
if ( !file )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fwrite(m_BootData+pEntry->dwDataOffset,1,pEntry->dwDataSize,file);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
bool CRKBoot::GetEntryProperty(ENUM_RKBOOTENTRY type,UCHAR ucIndex,DWORD &dwSize,DWORD &dwDelay,char *pName)
|
||||
{
|
||||
DWORD dwOffset;
|
||||
UCHAR ucCount,ucSize;
|
||||
switch ( type )
|
||||
{
|
||||
case ENTRY471:
|
||||
dwOffset = m_471Offset;
|
||||
ucCount = m_471Count;
|
||||
ucSize = m_471Size;
|
||||
break;
|
||||
case ENTRY472:
|
||||
dwOffset = m_472Offset;
|
||||
ucCount = m_472Count;
|
||||
ucSize = m_472Size;
|
||||
break;
|
||||
case ENTRYLOADER:
|
||||
dwOffset = m_loaderOffset;
|
||||
ucCount = m_loaderCount;
|
||||
ucSize = m_loaderSize;//Loader³¤¶ÈÉú³ÉʱÒѾ512¶ÔÆë
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (ucIndex >= ucCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PSTRUCT_RKBOOT_ENTRY pEntry;
|
||||
pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex));
|
||||
dwDelay = pEntry->dwDataDelay;
|
||||
dwSize = pEntry->dwDataSize;
|
||||
if (pName)
|
||||
{
|
||||
WCHAR_To_char(pEntry->szName,pName,20);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CRKBoot::GetEntryData(ENUM_RKBOOTENTRY type,UCHAR ucIndex,PBYTE lpData)
|
||||
{
|
||||
DWORD dwOffset;
|
||||
UCHAR ucCount,ucSize;
|
||||
switch ( type )
|
||||
{
|
||||
case ENTRY471:
|
||||
dwOffset = m_471Offset;
|
||||
ucCount = m_471Count;
|
||||
ucSize = m_471Size;
|
||||
break;
|
||||
case ENTRY472:
|
||||
dwOffset = m_472Offset;
|
||||
ucCount = m_472Count;
|
||||
ucSize = m_472Size;
|
||||
break;
|
||||
case ENTRYLOADER:
|
||||
dwOffset = m_loaderOffset;
|
||||
ucCount = m_loaderCount;
|
||||
ucSize = m_loaderSize;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (ucIndex >= ucCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PSTRUCT_RKBOOT_ENTRY pEntry;
|
||||
pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex));
|
||||
memcpy(lpData,m_BootData+pEntry->dwDataOffset,pEntry->dwDataSize);
|
||||
return true;
|
||||
}
|
||||
char CRKBoot::GetIndexByName(ENUM_RKBOOTENTRY type,char *pName)
|
||||
{
|
||||
DWORD dwOffset;
|
||||
UCHAR ucCount,ucSize;
|
||||
switch ( type )
|
||||
{
|
||||
case ENTRY471:
|
||||
dwOffset = m_471Offset;
|
||||
ucCount = m_471Count;
|
||||
ucSize = m_471Size;
|
||||
break;
|
||||
case ENTRY472:
|
||||
dwOffset = m_472Offset;
|
||||
ucCount = m_472Count;
|
||||
ucSize = m_472Size;
|
||||
break;
|
||||
case ENTRYLOADER:
|
||||
dwOffset = m_loaderOffset;
|
||||
ucCount = m_loaderCount;
|
||||
ucSize = m_loaderSize;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (UCHAR i=0;i<ucCount;i++)
|
||||
{
|
||||
PSTRUCT_RKBOOT_ENTRY pEntry;
|
||||
pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*i));
|
||||
|
||||
char szName[20];
|
||||
WCHAR_To_char(pEntry->szName,szName,20);
|
||||
|
||||
if (strcasecmp(pName,szName)==0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
CRKBoot::~CRKBoot()
|
||||
{
|
||||
if (m_BootData!=NULL)
|
||||
{
|
||||
delete []m_BootData;
|
||||
}
|
||||
}
|
||||
|
||||
CRKBoot::CRKBoot(PBYTE lpBootData,DWORD dwBootSize,bool &bCheck)
|
||||
{
|
||||
Rc4DisableFlag.setContainer(this);
|
||||
Rc4DisableFlag.getter(&CRKBoot::GetRc4DisableFlag);
|
||||
SignFlag.setContainer(this);
|
||||
SignFlag.getter(&CRKBoot::GetSignFlag);
|
||||
Version.setContainer(this);
|
||||
Version.getter(&CRKBoot::GetVersion);
|
||||
MergeVersion.setContainer(this);
|
||||
MergeVersion.getter(&CRKBoot::GetMergeVersion);
|
||||
ReleaseTime.setContainer(this);
|
||||
ReleaseTime.getter(&CRKBoot::GetReleaseTime);
|
||||
SupportDevice.setContainer(this);
|
||||
SupportDevice.getter(&CRKBoot::GetSupportDevice);
|
||||
Entry471Count.setContainer(this);
|
||||
Entry471Count.getter(&CRKBoot::GetEntry471Count);
|
||||
Entry472Count.setContainer(this);
|
||||
Entry472Count.getter(&CRKBoot::GetEntry472Count);
|
||||
EntryLoaderCount.setContainer(this);
|
||||
EntryLoaderCount.getter(&CRKBoot::GetEntryLoaderCount);
|
||||
bCheck = true;
|
||||
if (lpBootData!=NULL)
|
||||
{
|
||||
m_BootData=lpBootData;
|
||||
m_BootSize=dwBootSize;
|
||||
bCheck=CrcCheck();
|
||||
if (!bCheck)
|
||||
{
|
||||
return;
|
||||
}
|
||||
PSTRUCT_RKBOOT_HEAD pBootHead;
|
||||
pBootHead = (PSTRUCT_RKBOOT_HEAD)(m_BootData);
|
||||
if ( pBootHead->uiTag!=0x544F4F42)
|
||||
{
|
||||
bCheck=false;
|
||||
return;
|
||||
}
|
||||
if (pBootHead->ucRc4Flag)
|
||||
{
|
||||
m_bRc4Disable = true;
|
||||
}
|
||||
else
|
||||
m_bRc4Disable = false;
|
||||
if (pBootHead->ucSignFlag=='S')
|
||||
{
|
||||
m_bSignFlag = true;
|
||||
}
|
||||
else
|
||||
m_bSignFlag = false;
|
||||
m_version = pBootHead->dwVersion;
|
||||
m_mergeVersion = pBootHead->dwMergeVersion;
|
||||
m_BootHeadSize = pBootHead->usSize;
|
||||
m_releaseTime.usYear = pBootHead->stReleaseTime.usYear;
|
||||
m_releaseTime.ucMonth = pBootHead->stReleaseTime.ucMonth;
|
||||
m_releaseTime.ucDay = pBootHead->stReleaseTime.ucDay;
|
||||
m_releaseTime.ucHour = pBootHead->stReleaseTime.ucHour;
|
||||
m_releaseTime.ucMinute = pBootHead->stReleaseTime.ucMinute;
|
||||
m_releaseTime.ucSecond = pBootHead->stReleaseTime.ucSecond;
|
||||
m_supportDevice = pBootHead->emSupportChip;
|
||||
|
||||
m_471Offset = pBootHead->dw471EntryOffset;
|
||||
m_471Count = pBootHead->uc471EntryCount;
|
||||
m_471Size = pBootHead->uc471EntrySize;
|
||||
|
||||
m_472Offset = pBootHead->dw472EntryOffset;
|
||||
m_472Count = pBootHead->uc472EntryCount;
|
||||
m_472Size = pBootHead->uc472EntrySize;
|
||||
|
||||
m_loaderOffset = pBootHead->dwLoaderEntryOffset;
|
||||
m_loaderCount = pBootHead->ucLoaderEntryCount;
|
||||
m_loaderSize = pBootHead->ucLoaderEntrySize;
|
||||
|
||||
memcpy(m_crc,m_BootData+(m_BootSize-4),4);
|
||||
}
|
||||
else
|
||||
{
|
||||
bCheck = false;
|
||||
m_BootData=NULL;
|
||||
}
|
||||
}
|
||||
void CRKBoot::WCHAR_To_wchar(WCHAR *src,wchar_t *dst,int len)
|
||||
{
|
||||
int i;
|
||||
memset(dst,0,len*sizeof(wchar_t));
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
memcpy(dst,src,2);
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
void CRKBoot::WCHAR_To_char(WCHAR *src,char *dst,int len)
|
||||
{
|
||||
int i;
|
||||
memset(dst,0,len*sizeof(char));
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
memcpy(dst,src,1);
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
91
RKBoot.h
Normal file
91
RKBoot.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef RKBOOT_HEADER
|
||||
#define RKBOOT_HEADER
|
||||
#include "DefineHeader.h"
|
||||
|
||||
#define BOOT_RESERVED_SIZE 57
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT uiTag;
|
||||
USHORT usSize;
|
||||
DWORD dwVersion;
|
||||
DWORD dwMergeVersion;
|
||||
STRUCT_RKTIME stReleaseTime;
|
||||
ENUM_RKDEVICE_TYPE emSupportChip;
|
||||
UCHAR uc471EntryCount;
|
||||
DWORD dw471EntryOffset;
|
||||
UCHAR uc471EntrySize;
|
||||
UCHAR uc472EntryCount;
|
||||
DWORD dw472EntryOffset;
|
||||
UCHAR uc472EntrySize;
|
||||
UCHAR ucLoaderEntryCount;
|
||||
DWORD dwLoaderEntryOffset;
|
||||
UCHAR ucLoaderEntrySize;
|
||||
UCHAR ucSignFlag;
|
||||
UCHAR ucRc4Flag;
|
||||
UCHAR reserved[BOOT_RESERVED_SIZE];
|
||||
} STRUCT_RKBOOT_HEAD, *PSTRUCT_RKBOOT_HEAD;
|
||||
|
||||
typedef struct {
|
||||
UCHAR ucSize;
|
||||
ENUM_RKBOOTENTRY emType;
|
||||
WCHAR szName[20];
|
||||
DWORD dwDataOffset;
|
||||
DWORD dwDataSize;
|
||||
DWORD dwDataDelay;
|
||||
} STRUCT_RKBOOT_ENTRY, *PSTRUCT_RKBOOT_ENTRY;
|
||||
|
||||
|
||||
#pragma pack()
|
||||
class CRKBoot {
|
||||
public:
|
||||
bool GetRc4DisableFlag();
|
||||
property<CRKBoot, bool, READ_ONLY> Rc4DisableFlag;
|
||||
bool GetSignFlag();
|
||||
property<CRKBoot, bool, READ_ONLY> SignFlag;
|
||||
UINT GetVersion();
|
||||
property<CRKBoot, UINT, READ_ONLY> Version;
|
||||
UINT GetMergeVersion();
|
||||
property<CRKBoot, UINT, READ_ONLY> MergeVersion;
|
||||
STRUCT_RKTIME GetReleaseTime();
|
||||
property<CRKBoot, STRUCT_RKTIME, READ_ONLY> ReleaseTime;
|
||||
ENUM_RKDEVICE_TYPE GetSupportDevice();
|
||||
property<CRKBoot, ENUM_RKDEVICE_TYPE, READ_ONLY> SupportDevice;
|
||||
unsigned char GetEntry471Count();
|
||||
property<CRKBoot, unsigned char, READ_ONLY> Entry471Count;
|
||||
unsigned char GetEntry472Count();
|
||||
property<CRKBoot, unsigned char, READ_ONLY> Entry472Count;
|
||||
unsigned char GetEntryLoaderCount();
|
||||
property<CRKBoot, unsigned char, READ_ONLY> EntryLoaderCount;
|
||||
bool CrcCheck();
|
||||
bool SaveEntryFile(ENUM_RKBOOTENTRY type, UCHAR ucIndex, string fileName);
|
||||
bool GetEntryProperty(ENUM_RKBOOTENTRY type, UCHAR ucIndex, DWORD &dwSize, DWORD &dwDelay, char *pName = NULL);
|
||||
char GetIndexByName(ENUM_RKBOOTENTRY type, char *pName);
|
||||
bool GetEntryData(ENUM_RKBOOTENTRY type, UCHAR ucIndex, PBYTE lpData);
|
||||
CRKBoot(PBYTE lpBootData, DWORD dwBootSize, bool &bCheck);
|
||||
~CRKBoot();
|
||||
protected:
|
||||
private:
|
||||
bool m_bRc4Disable;
|
||||
bool m_bSignFlag;
|
||||
DWORD m_version;
|
||||
DWORD m_mergeVersion;
|
||||
STRUCT_RKTIME m_releaseTime;
|
||||
ENUM_RKDEVICE_TYPE m_supportDevice;
|
||||
DWORD m_471Offset;
|
||||
UCHAR m_471Size;
|
||||
UCHAR m_471Count;
|
||||
DWORD m_472Offset;
|
||||
UCHAR m_472Size;
|
||||
UCHAR m_472Count;
|
||||
DWORD m_loaderOffset;
|
||||
UCHAR m_loaderSize;
|
||||
UCHAR m_loaderCount;
|
||||
BYTE m_crc[4];
|
||||
PBYTE m_BootData;
|
||||
DWORD m_BootSize;
|
||||
USHORT m_BootHeadSize;
|
||||
void WCHAR_To_wchar(WCHAR *src, wchar_t *dst, int len);
|
||||
void WCHAR_To_char(WCHAR *src, char *dst, int len);
|
||||
};
|
||||
|
||||
#endif
|
710
RKComm.cpp
Normal file
710
RKComm.cpp
Normal file
@ -0,0 +1,710 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include "RKComm.h"
|
||||
#include "RKLog.h"
|
||||
#include "Endian.h"
|
||||
extern unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber);
|
||||
CRKComm::CRKComm(CRKLog *pLog)
|
||||
{
|
||||
memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC));
|
||||
m_log = pLog;
|
||||
}
|
||||
CRKComm::~CRKComm()
|
||||
{
|
||||
}
|
||||
|
||||
CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog)
|
||||
{
|
||||
bRet = InitializeUsb(devDesc);
|
||||
}
|
||||
CRKUsbComm::~CRKUsbComm()
|
||||
{
|
||||
UninitializeUsb();
|
||||
}
|
||||
|
||||
bool CRKUsbComm::InitializeUsb(STRUCT_RKDEVICE_DESC devDesc)
|
||||
{
|
||||
m_pUsbHandle = NULL;
|
||||
m_pipeBulkIn = m_pipeBulkOut = 0;
|
||||
m_interfaceNum = -1;
|
||||
if (!devDesc.pUsbHandle) {
|
||||
return false;
|
||||
}
|
||||
memcpy(&m_deviceDesc, &devDesc, sizeof(STRUCT_RKDEVICE_DESC));
|
||||
int iRet;
|
||||
iRet = libusb_open((libusb_device *)devDesc.pUsbHandle, (libusb_device_handle **)&m_pUsbHandle);
|
||||
if (iRet!=0) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:InitializeUsb-->open device failed,err=%d", iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
struct libusb_config_descriptor *pConfigDesc=NULL;
|
||||
iRet = libusb_get_active_config_descriptor((libusb_device *)devDesc.pUsbHandle, &pConfigDesc);
|
||||
if (iRet!=0) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:InitializeUsb-->get device config descriptor failed, err=%d", iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int i, j, k;
|
||||
const struct libusb_interface *pInterface;
|
||||
const struct libusb_endpoint_descriptor *pEndpointDesc;
|
||||
const struct libusb_interface_descriptor *pInterfaceDesc;
|
||||
for(i = 0; i < pConfigDesc->bNumInterfaces; i++) {
|
||||
pInterface = pConfigDesc->interface + i;
|
||||
for(j = 0; j < pInterface->num_altsetting; j++) {
|
||||
pInterfaceDesc = pInterface->altsetting+j;
|
||||
if (m_deviceDesc.emUsbType == RKUSB_MSC) {
|
||||
if( (pInterfaceDesc->bInterfaceClass != 8) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 0x50))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (pInterfaceDesc->bInterfaceClass != 0xff) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 5))
|
||||
continue;
|
||||
}
|
||||
for(k = 0; k < pInterfaceDesc->bNumEndpoints; k++) {
|
||||
pEndpointDesc = pInterfaceDesc->endpoint+k;
|
||||
if ((pEndpointDesc->bEndpointAddress & 0x80) == 0) {
|
||||
if (m_pipeBulkOut == 0)
|
||||
m_pipeBulkOut = pEndpointDesc->bEndpointAddress;
|
||||
}
|
||||
else {
|
||||
if (m_pipeBulkIn == 0)
|
||||
m_pipeBulkIn = pEndpointDesc->bEndpointAddress;
|
||||
}
|
||||
if ((m_pipeBulkIn != 0) && (m_pipeBulkOut != 0)) {//found it
|
||||
m_interfaceNum = i;
|
||||
libusb_free_config_descriptor(pConfigDesc);
|
||||
iRet = libusb_claim_interface((libusb_device_handle *)m_pUsbHandle, m_interfaceNum);
|
||||
if (iRet != 0) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:libusb_claim_interface failed,err=%d", iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
libusb_free_config_descriptor(pConfigDesc);
|
||||
return false;
|
||||
}
|
||||
void CRKUsbComm::UninitializeUsb()
|
||||
{
|
||||
if (m_pUsbHandle) {
|
||||
libusb_close((libusb_device_handle *)m_pUsbHandle);
|
||||
m_pUsbHandle = NULL;
|
||||
}
|
||||
memset(&m_deviceDesc, 0, sizeof(STRUCT_RKDEVICE_DESC));
|
||||
m_pipeBulkIn = m_pipeBulkOut = 0;
|
||||
return ;
|
||||
}
|
||||
bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc)
|
||||
{
|
||||
bool bRet;
|
||||
UninitializeUsb();
|
||||
bRet = InitializeUsb(devDesc);
|
||||
return bRet;
|
||||
}
|
||||
bool CRKUsbComm::Reset_Usb_Device()
|
||||
{
|
||||
int iRet = -1;
|
||||
if (m_pUsbHandle) {
|
||||
iRet=libusb_reset_device((libusb_device_handle *)m_pUsbHandle);
|
||||
}
|
||||
return (iRet == 0) ? true : false;
|
||||
}
|
||||
|
||||
bool CRKUsbComm::RKU_Read(BYTE* lpBuffer, DWORD dwSize)
|
||||
{
|
||||
int iRet;
|
||||
int nRead;
|
||||
iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, CMD_TIMEOUT);
|
||||
if (iRet!=0) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_Read failed,err=%d", iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (nRead != (int)dwSize) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_Read failed, size=%d, read=%d", dwSize, nRead);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRKUsbComm::RKU_Write(BYTE* lpBuffer, DWORD dwSize)
|
||||
{
|
||||
int iRet;
|
||||
int nWrite;
|
||||
iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkOut, lpBuffer, dwSize, &nWrite, CMD_TIMEOUT);
|
||||
if (iRet != 0) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_Write failed, err=%d", iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (nWrite != (int)dwSize) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_Write failed, size=%d, read=%d", dwSize, nWrite);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int CRKUsbComm::RandomInteger(int low, int high)
|
||||
{
|
||||
int k;
|
||||
double d;
|
||||
|
||||
d = (double)rand() / ((double)RAND_MAX + 1);
|
||||
k = (int)(d * (high - low + 1));
|
||||
return (low + k);
|
||||
}
|
||||
DWORD CRKUsbComm::MakeCBWTag()
|
||||
{
|
||||
DWORD tag = 0;
|
||||
int i = 0;
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
tag <<= 8;
|
||||
tag += RandomInteger(0, 0xFF);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code)
|
||||
{
|
||||
memset(pCBW,0, sizeof(CBW));
|
||||
|
||||
pCBW->dwCBWSignature = CBW_SIGN;
|
||||
pCBW->dwCBWTag = MakeCBWTag();
|
||||
pCBW->cbwcb.ucOperCode = code;
|
||||
|
||||
switch(code) {
|
||||
case TEST_UNIT_READY: /* Test Unit Ready : 0 */
|
||||
case READ_FLASH_ID: /* Read Flash ID : 1 */
|
||||
case READ_FLASH_INFO:
|
||||
case READ_CHIP_INFO:
|
||||
case READ_EFUSE:
|
||||
pCBW->ucCBWFlags= DIRECTION_IN;
|
||||
pCBW->ucCBWCBLength = 0x06;
|
||||
break;
|
||||
case DEVICE_RESET: /* Reset Device : 0xff */
|
||||
case ERASE_SYSTEMDISK:
|
||||
case SET_RESET_FLAG:
|
||||
pCBW->ucCBWFlags = DIRECTION_OUT;
|
||||
pCBW->ucCBWCBLength = 0x06;
|
||||
break;
|
||||
case TEST_BAD_BLOCK: /* Test Bad Block : 3 */
|
||||
case READ_SECTOR: /* Read Pages : 4 */
|
||||
case READ_LBA: /* Read Pages : 4 */
|
||||
case READ_SDRAM: /* Write Pages : 15 */
|
||||
case READ_SPI_FLASH:
|
||||
case READ_NEW_EFUSE:
|
||||
pCBW->ucCBWFlags = DIRECTION_IN;
|
||||
pCBW->ucCBWCBLength = 0x0a;
|
||||
break;
|
||||
case WRITE_SECTOR: /* Write Pages : 5 */
|
||||
case WRITE_LBA: /* Write Pages : 15 */
|
||||
case WRITE_SDRAM: /* Write Pages : 15 */
|
||||
case EXECUTE_SDRAM:
|
||||
case ERASE_NORMAL: /* Erase Blocks : 6 */
|
||||
case ERASE_FORCE: /* Read Spare : 11 */
|
||||
case WRITE_EFUSE:
|
||||
case WRITE_SPI_FLASH:
|
||||
case WRITE_NEW_EFUSE:
|
||||
pCBW->ucCBWFlags = DIRECTION_OUT;
|
||||
pCBW->ucCBWCBLength = 0x0a;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw)
|
||||
{
|
||||
DWORD dwReadBytes=0;
|
||||
DWORD dwTotalRead=0;
|
||||
int iTryCount;
|
||||
iTryCount = 3;
|
||||
do {
|
||||
dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) );
|
||||
|
||||
if (UFI_CHECK_SIGN(cbw,csw))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (dwReadBytes != sizeof(CSW))
|
||||
{
|
||||
iTryCount--;
|
||||
sleep(3);
|
||||
}
|
||||
dwTotalRead += dwReadBytes;
|
||||
if (dwTotalRead >= MAX_CLEAR_LEN)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}while ( iTryCount > 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize)
|
||||
{
|
||||
int iRet;
|
||||
int nRead;
|
||||
iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000);
|
||||
if (iRet != 0) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return nRead;
|
||||
}
|
||||
|
||||
int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_EraseBlock failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
USHORT usCount;
|
||||
usCount = dwCount;
|
||||
if(dwCount > MAX_ERASE_BLOCKS)
|
||||
return ERR_CROSS_BORDER;
|
||||
|
||||
InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType);
|
||||
cbw.ucCBWLUN = ucFlashCS;
|
||||
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
|
||||
cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
|
||||
|
||||
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
|
||||
{
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) )
|
||||
return ERR_CMD_NOTMATCH;
|
||||
|
||||
if(csw.ucCSWStatus == 1)
|
||||
return ERR_FOUND_BAD_BLOCK;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
|
||||
InitializeCBW(&cbw, READ_CHIP_INFO);
|
||||
|
||||
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
|
||||
{
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read(lpBuffer, 16))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) )
|
||||
return ERR_CMD_NOTMATCH;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
|
||||
InitializeCBW(&cbw, READ_FLASH_ID);
|
||||
|
||||
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
|
||||
{
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read(lpBuffer, 5))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) )
|
||||
return ERR_CMD_NOTMATCH;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_ReadFlashInfo failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
|
||||
InitializeCBW(&cbw, READ_FLASH_INFO);
|
||||
|
||||
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
|
||||
{
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
DWORD dwRead;
|
||||
dwRead = RKU_Read_EX(lpBuffer, 512);
|
||||
if ((dwRead < 11) || (dwRead > 512))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
if (puiRead)
|
||||
{
|
||||
*puiRead = dwRead;
|
||||
}
|
||||
/*
|
||||
if(!RKU_Read(hDev, lpBuffer, 11))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
*/
|
||||
if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) )
|
||||
return ERR_CMD_NOTMATCH;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_ReadLBA failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
USHORT wSectorSize;
|
||||
USHORT usSectorLen;
|
||||
wSectorSize = 512;
|
||||
usSectorLen=dwCount;
|
||||
|
||||
InitializeCBW(&cbw, READ_LBA);
|
||||
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
|
||||
cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen);
|
||||
cbw.cbwcb.ucReserved = bySubCode;
|
||||
|
||||
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
|
||||
{
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
DWORD dwTotal;
|
||||
dwTotal = usSectorLen * wSectorSize;
|
||||
|
||||
if(!RKU_Read(lpBuffer, dwTotal))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) )
|
||||
return ERR_CMD_NOTMATCH;
|
||||
|
||||
if(csw.ucCSWStatus == 1)
|
||||
return ERR_FAILED;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_ResetDevice failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
|
||||
InitializeCBW(&cbw, DEVICE_RESET);
|
||||
cbw.cbwcb.ucReserved = bySubCode;
|
||||
|
||||
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
|
||||
{
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
|
||||
{
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) ) {
|
||||
bool bRet;
|
||||
bRet = RKU_ClearBuffer(cbw, csw);
|
||||
if (!bRet) {
|
||||
return ERR_CMD_NOTMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if(csw.ucCSWStatus == 1)
|
||||
return ERR_FAILED;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_TestDeviceReady failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
|
||||
InitializeCBW(&cbw, TEST_UNIT_READY);
|
||||
|
||||
cbw.cbwcb.ucReserved = bySubCode;
|
||||
if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) ) {
|
||||
bool bRet;
|
||||
bRet = RKU_ClearBuffer(cbw ,csw);
|
||||
if (!bRet) {
|
||||
return ERR_CMD_NOTMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) {
|
||||
*dwCurrent = (csw.dwCBWDataResidue >>16);
|
||||
*dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF);
|
||||
|
||||
*dwTotal = EndianU16_BtoL(*dwTotal);
|
||||
*dwCurrent = EndianU16_BtoL(*dwCurrent);
|
||||
}
|
||||
if(csw.ucCSWStatus == 1) {
|
||||
return ERR_DEVICE_UNREADY;
|
||||
}
|
||||
|
||||
return ERR_DEVICE_READY;
|
||||
}
|
||||
int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_WriteLBA failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
USHORT wSectorSize;
|
||||
USHORT usCount;
|
||||
wSectorSize = 512;
|
||||
usCount = dwCount;
|
||||
DWORD dwTotal = usCount * wSectorSize;
|
||||
|
||||
InitializeCBW(&cbw, WRITE_LBA);
|
||||
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
|
||||
cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
|
||||
cbw.cbwcb.ucReserved = bySubCode;
|
||||
if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Write( lpBuffer, dwTotal)) {
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) )
|
||||
return ERR_CMD_NOTMATCH;
|
||||
|
||||
if(csw.ucCSWStatus == 1)
|
||||
return ERR_FAILED;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer)
|
||||
{
|
||||
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_WriteSector failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
CBW cbw;
|
||||
CSW csw;
|
||||
USHORT wSectorSize;
|
||||
USHORT usCount;
|
||||
usCount=dwCount;
|
||||
if(usCount > 32)
|
||||
return ERR_CROSS_BORDER;
|
||||
|
||||
wSectorSize = 528;
|
||||
InitializeCBW(&cbw, WRITE_SECTOR);
|
||||
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
|
||||
cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
|
||||
|
||||
if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Write( lpBuffer, usCount * wSectorSize)) {
|
||||
return ERR_DEVICE_WRITE_FAILED;
|
||||
}
|
||||
|
||||
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
|
||||
return ERR_DEVICE_READ_FAILED;
|
||||
}
|
||||
|
||||
if( !UFI_CHECK_SIGN(cbw, csw) )
|
||||
return ERR_CMD_NOTMATCH;
|
||||
|
||||
if(csw.ucCSWStatus == 1)
|
||||
return ERR_FAILED;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize)
|
||||
{
|
||||
if (m_deviceDesc.emUsbType != RKUSB_MASKROM) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_DeviceRequest failed,device not support");
|
||||
}
|
||||
return ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_DeviceRequest failed,request not support");
|
||||
}
|
||||
return ERR_REQUEST_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
bool bSendPendPacket = false;
|
||||
USHORT crcValue = 0xffff;
|
||||
BYTE *pData = NULL;
|
||||
pData = new BYTE[dwDataSize + 5];
|
||||
memset(pData, 0, dwDataSize + 5);
|
||||
memcpy(pData, lpBuffer, dwDataSize);
|
||||
|
||||
switch(dwDataSize % 4096) {
|
||||
case 4095:
|
||||
++dwDataSize;
|
||||
break;
|
||||
case 4094:
|
||||
bSendPendPacket = true;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
crcValue = CRC_CCITT(pData, dwDataSize);
|
||||
pData[dwDataSize] = (crcValue & 0xff00) >> 8;
|
||||
pData[dwDataSize+1] = crcValue & 0x00ff;
|
||||
dwDataSize += 2;
|
||||
|
||||
UINT nSendBytes = 0;
|
||||
DWORD dwTotalSended = 0;
|
||||
int iRet;
|
||||
|
||||
while(dwTotalSended < dwDataSize) {
|
||||
nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended);
|
||||
iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT);
|
||||
if (iRet != (int)nSendBytes) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet);
|
||||
}
|
||||
delete []pData;
|
||||
return ERR_REQUEST_FAIL;
|
||||
}
|
||||
dwTotalSended += nSendBytes;
|
||||
}
|
||||
|
||||
if(bSendPendPacket) {
|
||||
BYTE ucFillByte = 0;
|
||||
iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT);
|
||||
if (iRet != 0) {
|
||||
if (m_log) {
|
||||
m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet);
|
||||
}
|
||||
delete []pData;
|
||||
return ERR_REQUEST_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
delete []pData;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
170
RKComm.h
Normal file
170
RKComm.h
Normal file
@ -0,0 +1,170 @@
|
||||
#ifndef RKCOMM_HEADER
|
||||
#define RKCOMM_HEADER
|
||||
#include "DefineHeader.h"
|
||||
typedef enum {
|
||||
USB_BULK_READ = 0,
|
||||
USB_BULK_WRITE,
|
||||
USB_CONTROL,
|
||||
} USB_ACCESS_TYPE;
|
||||
typedef enum {
|
||||
TU_NONE_SUBCODE = 0,
|
||||
TU_ERASESYSTEM_SUBCODE = 0xFE,
|
||||
TU_LOWERFORMAT_SUBCODE = 0xFD,
|
||||
TU_ERASEUSERDATA_SUBCODE = 0xFB,
|
||||
TU_GETUSERSECTOR_SUBCODE = 0xF9
|
||||
} TESTUNIT_SUBCODE;
|
||||
typedef enum{
|
||||
RST_NONE_SUBCODE = 0,
|
||||
RST_RESETMSC_SUBCODE,
|
||||
RST_POWEROFF_SUBCODE,
|
||||
RST_RESETMASKROM_SUBCODE,
|
||||
RST_DISCONNECTRESET_SUBCODE
|
||||
} RESET_SUBCODE;
|
||||
typedef enum{
|
||||
RWMETHOD_IMAGE = 0,
|
||||
RWMETHOD_LBA
|
||||
} RW_SUBCODE;
|
||||
|
||||
typedef enum {
|
||||
TEST_UNIT_READY = 0,
|
||||
READ_FLASH_ID = 0x01,
|
||||
TEST_BAD_BLOCK = 0x03,
|
||||
READ_SECTOR = 0x04,
|
||||
WRITE_SECTOR = 0x05,
|
||||
ERASE_NORMAL = 0x06,
|
||||
ERASE_FORCE = 0x0B,
|
||||
READ_LBA = 0x14,
|
||||
WRITE_LBA = 0x15,
|
||||
ERASE_SYSTEMDISK = 0x16,
|
||||
READ_SDRAM = 0x17,
|
||||
WRITE_SDRAM = 0x18,
|
||||
EXECUTE_SDRAM = 0x19,
|
||||
READ_FLASH_INFO = 0x1A,
|
||||
READ_CHIP_INFO = 0x1B,
|
||||
SET_RESET_FLAG = 0x1E,
|
||||
WRITE_EFUSE = 0x1F,
|
||||
READ_EFUSE = 0x20,
|
||||
READ_SPI_FLASH = 0x21,
|
||||
WRITE_SPI_FLASH = 0x22,
|
||||
WRITE_NEW_EFUSE = 0x23,
|
||||
READ_NEW_EFUSE = 0x24,
|
||||
DEVICE_RESET = 0xFF
|
||||
} USB_OPERATION_CODE;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
BYTE ucOperCode;
|
||||
BYTE ucReserved;
|
||||
DWORD dwAddress;
|
||||
BYTE ucReserved2;
|
||||
USHORT usLength;
|
||||
BYTE ucReserved3[7];
|
||||
} CBWCB, *PCBWCB;
|
||||
|
||||
typedef struct {
|
||||
DWORD dwCBWSignature;
|
||||
DWORD dwCBWTag;
|
||||
DWORD dwCBWTransferLength;
|
||||
BYTE ucCBWFlags;
|
||||
BYTE ucCBWLUN;
|
||||
BYTE ucCBWCBLength;
|
||||
CBWCB cbwcb;
|
||||
} CBW, *PCBW;
|
||||
|
||||
typedef struct {
|
||||
DWORD dwCSWSignature;
|
||||
DWORD dwCSWTag;
|
||||
DWORD dwCBWDataResidue;
|
||||
BYTE ucCSWStatus;
|
||||
} CSW, *PCSW;
|
||||
|
||||
#pragma pack()
|
||||
#define CMD_TIMEOUT 0
|
||||
#define CBW_SIGN 0x43425355 /* "USBC" */
|
||||
#define CSW_SIGN 0x53425355 /* "USBS" */
|
||||
|
||||
#define DIRECTION_OUT 0x00
|
||||
#define DIRECTION_IN 0x80
|
||||
#define MAX_TEST_BLOCKS 512
|
||||
#define MAX_ERASE_BLOCKS 128
|
||||
#define MAX_CLEAR_LEN 16*1024
|
||||
|
||||
#ifndef ERR_SUCCESS
|
||||
#define ERR_SUCCESS 0
|
||||
#endif
|
||||
#define ERR_DEVICE_READY 0
|
||||
#define ERR_DEVICE_OPEN_FAILED -1
|
||||
#define ERR_CSW_OPEN_FAILED -2
|
||||
#define ERR_DEVICE_WRITE_FAILED -3
|
||||
#define ERR_DEVICE_READ_FAILED -4
|
||||
#define ERR_CMD_NOTMATCH -5
|
||||
#define ERR_DEVICE_UNREADY -6
|
||||
#define ERR_FOUND_BAD_BLOCK -7
|
||||
#define ERR_FAILED -8
|
||||
#define ERR_CROSS_BORDER -9
|
||||
#define ERR_DEVICE_NOT_SUPPORT -10
|
||||
#define ERR_REQUEST_NOT_SUPPORT -11
|
||||
#define ERR_REQUEST_FAIL -12
|
||||
#define ERR_BUFFER_NOT_ENOUGH -13
|
||||
#define UFI_CHECK_SIGN(cbw, csw) ((CSW_SIGN == (csw).dwCSWSignature) && ((csw).dwCSWTag == (cbw).dwCBWTag))
|
||||
|
||||
class CRKLog;
|
||||
class CRKComm
|
||||
{
|
||||
public:
|
||||
virtual int RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType) = 0;
|
||||
virtual int RKU_ReadChipInfo(BYTE *lpBuffer) = 0;
|
||||
virtual int RKU_ReadFlashID(BYTE *lpBuffer) = 0;
|
||||
virtual int RKU_ReadFlashInfo(BYTE *lpBuffer, UINT *puiRead = NULL) = 0;
|
||||
virtual int RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE) = 0;
|
||||
virtual int RKU_ResetDevice(BYTE bySubCode = RST_NONE_SUBCODE) = 0;
|
||||
virtual int RKU_TestDeviceReady(DWORD *dwTotal = NULL, DWORD *dwCurrent = NULL, BYTE bySubCode = TU_NONE_SUBCODE) = 0;
|
||||
virtual int RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE) = 0;
|
||||
virtual int RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer) = 0;
|
||||
virtual int RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize) = 0;
|
||||
virtual bool Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc) = 0;
|
||||
virtual bool Reset_Usb_Device() = 0;
|
||||
CRKComm(CRKLog *pLog);
|
||||
virtual ~CRKComm();
|
||||
protected:
|
||||
STRUCT_RKDEVICE_DESC m_deviceDesc;
|
||||
CRKLog *m_log;
|
||||
private:
|
||||
virtual bool RKU_Write(BYTE *lpBuffer, DWORD dwSize) = 0;
|
||||
virtual bool RKU_Read(BYTE *lpBuffer, DWORD dwSize) = 0;
|
||||
};
|
||||
class CRKUsbComm:public CRKComm
|
||||
{
|
||||
public:
|
||||
virtual int RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType);
|
||||
virtual int RKU_ReadChipInfo(BYTE *lpBuffer);
|
||||
virtual int RKU_ReadFlashID(BYTE *lpBuffer);
|
||||
virtual int RKU_ReadFlashInfo(BYTE *lpBuffer, UINT *puiRead = NULL);
|
||||
virtual int RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE);
|
||||
virtual int RKU_ResetDevice(BYTE bySubCode = RST_NONE_SUBCODE);
|
||||
virtual int RKU_TestDeviceReady(DWORD *dwTotal = NULL, DWORD *dwCurrent = NULL, BYTE bySubCode = TU_NONE_SUBCODE);
|
||||
virtual int RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE);
|
||||
virtual int RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer);
|
||||
virtual int RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize);
|
||||
CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet);
|
||||
virtual ~CRKUsbComm();
|
||||
virtual bool Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc);
|
||||
virtual bool Reset_Usb_Device();
|
||||
private:
|
||||
void *m_pUsbHandle;
|
||||
unsigned char m_pipeBulkIn;
|
||||
unsigned char m_pipeBulkOut;
|
||||
int m_interfaceNum;
|
||||
virtual bool RKU_Write(BYTE *lpBuffer, DWORD dwSize);
|
||||
virtual bool RKU_Read(BYTE *lpBuffer, DWORD dwSize);
|
||||
bool InitializeUsb(STRUCT_RKDEVICE_DESC devDesc);
|
||||
void UninitializeUsb();
|
||||
bool RKU_ClearBuffer(CBW &cbw, CSW &csw);
|
||||
DWORD RKU_Read_EX(BYTE *lpBuffer, DWORD dwSize);
|
||||
void InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code);
|
||||
int RandomInteger(int low, int high);
|
||||
DWORD MakeCBWTag();
|
||||
};
|
||||
|
||||
#endif
|
643
RKDevice.cpp
Normal file
643
RKDevice.cpp
Normal file
@ -0,0 +1,643 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include "RKDevice.h"
|
||||
|
||||
const char* szManufName[] =
|
||||
{
|
||||
"SAMSUNG",
|
||||
"TOSHIBA",
|
||||
"HYNIX",
|
||||
"INFINEON",
|
||||
"MICRON",
|
||||
"RENESAS",
|
||||
"ST",
|
||||
"INTEL"
|
||||
};
|
||||
|
||||
void CRKDevice::SetVendorID(USHORT value)
|
||||
{
|
||||
m_vid = value;
|
||||
}
|
||||
void CRKDevice::SetProductID(USHORT value)
|
||||
{
|
||||
m_pid = value;
|
||||
}
|
||||
void CRKDevice::SetDeviceType(ENUM_RKDEVICE_TYPE value)
|
||||
{
|
||||
m_device = value;
|
||||
}
|
||||
void CRKDevice::SetOsType(ENUM_OS_TYPE value)
|
||||
{
|
||||
m_os = value;
|
||||
}
|
||||
|
||||
void CRKDevice::SetUsbType(ENUM_RKUSB_TYPE value)
|
||||
{
|
||||
m_usb = value;
|
||||
}
|
||||
void CRKDevice::SetBcdUsb(USHORT value)
|
||||
{
|
||||
m_bcdUsb = value;
|
||||
}
|
||||
void CRKDevice::SetLayerName(char *value)
|
||||
{
|
||||
strcpy(m_layerName,value);
|
||||
}
|
||||
void CRKDevice::SetLocationID(DWORD value)
|
||||
{
|
||||
m_locationID = value;
|
||||
}
|
||||
|
||||
void CRKDevice::SetCallBackPointer(ProgressPromptCB value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
m_callBackProc = value;
|
||||
}
|
||||
}
|
||||
CRKLog* CRKDevice::GetLogObjectPointer()
|
||||
{
|
||||
return m_pLog;
|
||||
}
|
||||
|
||||
CRKComm* CRKDevice::GetCommObjectPointer()
|
||||
{
|
||||
return m_pComm;
|
||||
}
|
||||
|
||||
USHORT CRKDevice::GetVendorID()
|
||||
{
|
||||
return m_vid;
|
||||
}
|
||||
USHORT CRKDevice::GetProductID()
|
||||
{
|
||||
return m_pid;
|
||||
}
|
||||
ENUM_RKDEVICE_TYPE CRKDevice::GetDeviceType()
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
ENUM_OS_TYPE CRKDevice::GetOsType()
|
||||
{
|
||||
return m_os;
|
||||
}
|
||||
|
||||
ENUM_RKUSB_TYPE CRKDevice::GetUsbType()
|
||||
{
|
||||
return m_usb;
|
||||
}
|
||||
|
||||
USHORT CRKDevice::GetBcdUsb()
|
||||
{
|
||||
return m_bcdUsb;
|
||||
}
|
||||
DWORD CRKDevice::GetLocationID()
|
||||
{
|
||||
return m_locationID;
|
||||
}
|
||||
char* CRKDevice::GetLayerName()
|
||||
{
|
||||
return m_layerName;
|
||||
}
|
||||
|
||||
string CRKDevice::GetLayerString(DWORD dwLocationID)
|
||||
{
|
||||
char szLocation[32] = "\0";
|
||||
sprintf(szLocation, "%d-%d", dwLocationID >> 8, dwLocationID & 0xff);
|
||||
return szLocation;
|
||||
}
|
||||
|
||||
CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device)
|
||||
{
|
||||
VendorID.setContainer(this);
|
||||
VendorID.getter(&CRKDevice::GetVendorID);
|
||||
VendorID.setter(&CRKDevice::SetVendorID);
|
||||
|
||||
ProductID.setContainer(this);
|
||||
ProductID.getter(&CRKDevice::GetProductID);
|
||||
ProductID.setter(&CRKDevice::SetProductID);
|
||||
|
||||
DeviceType.setContainer(this);
|
||||
DeviceType.getter(&CRKDevice::GetDeviceType);
|
||||
DeviceType.setter(&CRKDevice::SetDeviceType);
|
||||
|
||||
UsbType.setContainer(this);
|
||||
UsbType.getter(&CRKDevice::GetUsbType);
|
||||
UsbType.setter(&CRKDevice::SetUsbType);
|
||||
|
||||
LayerName.setContainer(this);
|
||||
LayerName.getter(&CRKDevice::GetLayerName);
|
||||
LayerName.setter(&CRKDevice::SetLayerName);
|
||||
|
||||
BcdUsb.setContainer(this);
|
||||
BcdUsb.getter(&CRKDevice::GetBcdUsb);
|
||||
BcdUsb.setter(&CRKDevice::SetBcdUsb);
|
||||
|
||||
LocationID.setContainer(this);
|
||||
LocationID.getter(&CRKDevice::GetLocationID);
|
||||
LocationID.setter(&CRKDevice::SetLocationID);
|
||||
|
||||
OsType.setContainer(this);
|
||||
OsType.getter(&CRKDevice::GetOsType);
|
||||
OsType.setter(&CRKDevice::SetOsType);
|
||||
|
||||
LogObjectPointer.setContainer(this);
|
||||
LogObjectPointer.getter(&CRKDevice::GetLogObjectPointer);
|
||||
|
||||
CommObjectPointer.setContainer(this);
|
||||
CommObjectPointer.getter(&CRKDevice::GetCommObjectPointer);
|
||||
|
||||
CallBackPointer.setContainer(this);
|
||||
CallBackPointer.setter(&CRKDevice::SetCallBackPointer);
|
||||
|
||||
m_vid = device.usVid;
|
||||
m_pid = device.usPid;
|
||||
m_usb = device.emUsbType;
|
||||
m_device = device.emDeviceType;
|
||||
m_bcdUsb = device.usbcdUsb;
|
||||
m_locationID = device.uiLocationID;
|
||||
strcpy(m_layerName, GetLayerString(m_locationID).c_str());
|
||||
|
||||
memset(m_flashInfo.blockState, 0, IDBLOCK_TOP);
|
||||
m_flashInfo.usPhyBlokcPerIDB = 1;
|
||||
m_flashInfo.uiSecNumPerIDB = 0;
|
||||
m_callBackProc = NULL;
|
||||
m_chipData = NULL;
|
||||
m_pImage = NULL;
|
||||
m_pLog = NULL;
|
||||
m_pComm = NULL;
|
||||
m_pFlashInfoData = NULL;
|
||||
m_usFlashInfoDataLen = 0;
|
||||
m_usFlashInfoDataOffset = 0;
|
||||
m_bEmmc = false;
|
||||
}
|
||||
CRKDevice::~CRKDevice()
|
||||
{
|
||||
if (m_pComm) {
|
||||
delete m_pComm;
|
||||
m_pComm = NULL;
|
||||
}
|
||||
if (m_chipData) {
|
||||
delete []m_chipData;
|
||||
m_chipData = NULL;
|
||||
}
|
||||
|
||||
if (m_pFlashInfoData) {
|
||||
delete []m_pFlashInfoData;
|
||||
m_pFlashInfoData = NULL;
|
||||
}
|
||||
}
|
||||
bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog)
|
||||
{
|
||||
if (!pComm) {
|
||||
return false;
|
||||
}
|
||||
m_pImage = pImage;
|
||||
m_pComm = pComm;
|
||||
m_pLog = pLog;
|
||||
if (m_pImage) {
|
||||
m_os = m_pImage->OsType;
|
||||
} else
|
||||
m_os = RK_OS;
|
||||
return true;
|
||||
}
|
||||
int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount)
|
||||
{
|
||||
int sectorOffset,nWrittenBlcok,iRet;
|
||||
BYTE emptyData[4 * (SECTOR_SIZE+SPARE_SIZE)];
|
||||
memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE));
|
||||
nWrittenBlcok = 0;
|
||||
while (dwCount > 0) {
|
||||
sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock;
|
||||
iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData);
|
||||
if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:EraseEmmcBlock-->RKU_WriteSector failed, RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
dwCount--;
|
||||
nWrittenBlcok++;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount)
|
||||
{
|
||||
int nWritten,iRet;
|
||||
BYTE emptyData[32 * SECTOR_SIZE];
|
||||
memset(emptyData, 0xff, 32 * SECTOR_SIZE);
|
||||
|
||||
while (dwCount > 0) {
|
||||
nWritten = (dwCount < 32) ? dwCount : 32;
|
||||
iRet = m_pComm->RKU_WriteLBA(dwSectorPos, nWritten, emptyData);
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:EraseEmmcByWriteLBA-->RKU_WriteLBA failed, RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
dwCount -= nWritten;
|
||||
dwSectorPos += nWritten;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
bool CRKDevice::EraseEmmc()
|
||||
{
|
||||
UINT uiCount, uiEraseCount, uiSectorOffset;
|
||||
int iRet = ERR_SUCCESS, iLoopTimes = 0;
|
||||
uiCount = m_flashInfo.uiFlashSize;
|
||||
|
||||
DWORD dwLayerID;
|
||||
dwLayerID = m_locationID;
|
||||
ENUM_CALL_STEP emCallStep = CALL_FIRST;
|
||||
uiEraseCount = 4;
|
||||
while (uiEraseCount < uiCount) {
|
||||
uiSectorOffset = uiEraseCount * 2048;
|
||||
if (uiEraseCount>8) {
|
||||
iRet = EraseEmmcByWriteLBA(uiSectorOffset, 32);
|
||||
} else
|
||||
iRet = EraseEmmcByWriteLBA(uiSectorOffset, 2048);
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:EraseEmmc-->EraseEmmcByWriteLBA failed, RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
uiEraseCount++;
|
||||
iLoopTimes++;
|
||||
if (iLoopTimes%8 == 0) {
|
||||
if (m_callBackProc) {
|
||||
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiEraseCount, emCallStep);
|
||||
emCallStep = CALL_MIDDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_callBackProc) {
|
||||
emCallStep = CALL_LAST;
|
||||
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiCount, emCallStep);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CRKDevice::GetFlashInfo()
|
||||
{
|
||||
STRUCT_FLASHINFO_CMD info;
|
||||
BYTE flashID[5];
|
||||
int iRet;
|
||||
UINT uiRead;
|
||||
iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead);
|
||||
if( ERR_SUCCESS == iRet ) {
|
||||
if ((info.usBlockSize == 0) || (info.bPageSize == 0)) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero", m_layerName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (info.bManufCode <= 7) {
|
||||
strcpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]);
|
||||
} else {
|
||||
strcpy(m_flashInfo.szManufacturerName, "UNKNOWN");
|
||||
}
|
||||
m_flashInfo.uiFlashSize = info.uiFlashSize / 2 / 1024;
|
||||
m_flashInfo.uiPageSize = info.bPageSize / 2;
|
||||
m_flashInfo.usBlockSize = info.usBlockSize / 2;
|
||||
m_flashInfo.bECCBits = info.bECCBits;
|
||||
m_flashInfo.bAccessTime = info.bAccessTime;
|
||||
m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize;
|
||||
m_flashInfo.uiSectorPerBlock = info.usBlockSize;
|
||||
m_flashInfo.bFlashCS = info.bFlashCS;
|
||||
m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4;
|
||||
if (m_pFlashInfoData) {
|
||||
delete []m_pFlashInfoData;
|
||||
m_pFlashInfoData = NULL;
|
||||
}
|
||||
m_usFlashInfoDataLen = BYTE2SECTOR(uiRead);
|
||||
m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen];
|
||||
memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen);
|
||||
memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead);
|
||||
if (m_pLog) {
|
||||
string strFlashInfo;
|
||||
m_pLog->PrintBuffer(strFlashInfo, m_pFlashInfoData, 11);
|
||||
m_pLog->Record("<LAYER %s> INFO:FlashInfo:%s", m_layerName, strFlashInfo.c_str());
|
||||
}
|
||||
} else {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed, RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
iRet = m_pComm->RKU_ReadFlashID(flashID);
|
||||
if( ERR_SUCCESS == iRet ) {
|
||||
DWORD *pID = (DWORD *)flashID;
|
||||
if (*pID==0x434d4d45)/*emmc*/ {
|
||||
m_bEmmc = true;
|
||||
} else
|
||||
m_bEmmc = false;
|
||||
} else {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashID failed, RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CRKDevice::TestDevice()
|
||||
{
|
||||
int iResult, iTryCount;
|
||||
DWORD dwTotal, dwCurrent, dwLayerID;
|
||||
dwLayerID = m_locationID;
|
||||
ENUM_CALL_STEP emCallStep = CALL_FIRST;
|
||||
do {
|
||||
iTryCount = 3;
|
||||
while (iTryCount > 0) {
|
||||
iResult = m_pComm->RKU_TestDeviceReady(&dwTotal, &dwCurrent);
|
||||
if ((iResult == ERR_SUCCESS) || (iResult == ERR_DEVICE_UNREADY)) {
|
||||
break;
|
||||
}
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, RetCode(%d)", m_layerName, iResult);
|
||||
}
|
||||
iTryCount--;
|
||||
sleep(1);
|
||||
}
|
||||
if (iTryCount <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iResult == ERR_SUCCESS) {
|
||||
if (emCallStep == CALL_MIDDLE) {
|
||||
if (m_callBackProc) {
|
||||
dwCurrent = dwTotal;
|
||||
emCallStep = CALL_LAST;
|
||||
m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (dwCurrent>dwTotal) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed,Total=%d, Current=%d", m_layerName, dwTotal, dwCurrent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (UsbType == RKUSB_LOADER) {
|
||||
if (dwTotal == 0) {
|
||||
if (m_pLog)
|
||||
{
|
||||
m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, Total is zero", m_layerName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_callBackProc)
|
||||
{
|
||||
m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
|
||||
emCallStep = CALL_MIDDLE;
|
||||
}
|
||||
sleep(1);
|
||||
}while(iResult == ERR_DEVICE_UNREADY);
|
||||
return true;
|
||||
}
|
||||
bool CRKDevice::ResetDevice()
|
||||
{
|
||||
int iRet;
|
||||
iRet = m_pComm->RKU_ResetDevice();
|
||||
if (iRet == ERR_SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
bool bRet = false;
|
||||
if ((iRet == -2) || (iRet == -4)) {
|
||||
bRet = true;
|
||||
}
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:ResetDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
}
|
||||
|
||||
bool CRKDevice::PowerOffDevice()
|
||||
{
|
||||
int iRet;
|
||||
iRet = m_pComm->RKU_ResetDevice(RST_POWEROFF_SUBCODE);
|
||||
if (iRet == ERR_SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:PowerOffDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool CRKDevice::CheckChip()
|
||||
{
|
||||
int iRet;
|
||||
BYTE bChipInfo[CHIPINFO_LEN];
|
||||
ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE;
|
||||
memset(bChipInfo, 0, CHIPINFO_LEN);
|
||||
iRet = m_pComm->RKU_ReadChipInfo(bChipInfo);
|
||||
if (iRet == ERR_SUCCESS) {
|
||||
if (!m_chipData) {
|
||||
m_chipData = new BYTE[CHIPINFO_LEN];
|
||||
}
|
||||
memset(m_chipData, 0, CHIPINFO_LEN);
|
||||
memcpy(m_chipData, bChipInfo, CHIPINFO_LEN);
|
||||
DWORD *pValue;
|
||||
pValue = (DWORD *)(&bChipInfo[0]);
|
||||
|
||||
if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device) {
|
||||
return true;
|
||||
}
|
||||
if (*pValue == 0x524B3237) {
|
||||
curDeviceType = RK27_DEVICE;
|
||||
} else if (*pValue == 0x32373341) {
|
||||
curDeviceType = RKCAYMAN_DEVICE;
|
||||
} else if (*pValue == 0x524B3238) {
|
||||
curDeviceType = RK28_DEVICE;
|
||||
} else if (*pValue == 0x32383158) {
|
||||
curDeviceType = RK281X_DEVICE;
|
||||
} else if (*pValue == 0x32383242) {
|
||||
curDeviceType = RKPANDA_DEVICE;
|
||||
} else if (*pValue == 0x32393058) {
|
||||
curDeviceType = RK29_DEVICE;
|
||||
} else if (*pValue == 0x32393258) {
|
||||
curDeviceType = RK292X_DEVICE;
|
||||
} else if (*pValue == 0x33303041) {
|
||||
curDeviceType = RK30_DEVICE;
|
||||
} else if (*pValue == 0x33313041) {
|
||||
curDeviceType = RK30B_DEVICE;
|
||||
} else if (*pValue == 0x33313042) {
|
||||
curDeviceType = RK31_DEVICE;
|
||||
} else if (*pValue == 0x33323041) {
|
||||
curDeviceType = RK32_DEVICE;
|
||||
} else if (*pValue == 0x32363243) {
|
||||
curDeviceType = RKSMART_DEVICE;
|
||||
} else if (*pValue == 0x6E616E6F) {
|
||||
curDeviceType = RKNANO_DEVICE;
|
||||
} else if (*pValue == 0x4E4F5243) {
|
||||
curDeviceType = RKCROWN_DEVICE;
|
||||
}
|
||||
|
||||
if (curDeviceType == m_device){
|
||||
return true;
|
||||
} else {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:CheckChip-->Chip is not match, firmware(0x%x), device(0x%x)", m_layerName, m_device, *pValue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int CRKDevice::DownloadBoot()
|
||||
{
|
||||
UCHAR i;
|
||||
DWORD dwSize, dwDelay;
|
||||
PBYTE pBuffer = NULL;
|
||||
for ( i = 0; i < m_pImage->m_bootObject->Entry471Count; i++ ) {
|
||||
if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY471, i, dwSize, dwDelay) ) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Property failed,index(%d)", m_layerName, i);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
if (dwSize>0) {
|
||||
pBuffer = new BYTE[dwSize];
|
||||
if ( !m_pImage->m_bootObject->GetEntryData(ENTRY471, i, pBuffer) ) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Data failed,index(%d)", m_layerName, i);
|
||||
}
|
||||
delete []pBuffer;
|
||||
return -3;
|
||||
}
|
||||
if ( !Boot_VendorRequest(0x0471,pBuffer,dwSize) ) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest471 failed,index(%d)", m_layerName, i);
|
||||
}
|
||||
delete []pBuffer;
|
||||
return -4;
|
||||
}
|
||||
delete []pBuffer;
|
||||
pBuffer = NULL;
|
||||
if (dwDelay>0) {
|
||||
usleep(dwDelay * 1000);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0; i < m_pImage->m_bootObject->Entry472Count; i++ ) {
|
||||
if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY472, i, dwSize, dwDelay) ) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Property failed,index(%d)", m_layerName, i);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
if (dwSize > 0) {
|
||||
pBuffer = new BYTE[dwSize];
|
||||
if ( !m_pImage->m_bootObject->GetEntryData(ENTRY472, i, pBuffer) ) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Data failed,index(%d)", m_layerName, i);
|
||||
}
|
||||
delete []pBuffer;
|
||||
return -3;
|
||||
}
|
||||
if ( !Boot_VendorRequest(0x0472, pBuffer, dwSize) ) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest472 failed,index(%d)", m_layerName, i);
|
||||
}
|
||||
delete []pBuffer;
|
||||
return -4;
|
||||
}
|
||||
delete []pBuffer;
|
||||
pBuffer = NULL;
|
||||
if (dwDelay > 0) {
|
||||
usleep(dwDelay * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
sleep(1);
|
||||
return 0;
|
||||
|
||||
}
|
||||
bool CRKDevice::Boot_VendorRequest( DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize)
|
||||
{
|
||||
int iRet;
|
||||
iRet = m_pComm->RKU_DeviceRequest(requestCode, pBuffer, dwDataSize);
|
||||
return (iRet == ERR_SUCCESS) ? true : false;
|
||||
}
|
||||
int CRKDevice::EraseAllBlocks()
|
||||
{
|
||||
int i;
|
||||
UINT uiBlockCount;
|
||||
int iRet = ERR_SUCCESS, iErasePos = 0, iEraseBlockNum = 0, iEraseTimes = 0, iCSIndex = 0;
|
||||
BYTE bCSCount = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ( m_flashInfo.bFlashCS & (1 << i) ) {
|
||||
bCSCount++;
|
||||
}
|
||||
}
|
||||
DWORD dwLayerID;
|
||||
dwLayerID = LocationID;
|
||||
ENUM_CALL_STEP emCallStep = CALL_FIRST;
|
||||
if (m_bEmmc) {
|
||||
iRet = EraseEmmcBlock(0, 0, IDBLOCK_TOP);
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmcBlock failed,RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (!EraseEmmc()) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ( m_flashInfo.bFlashCS & (1 << i) ) {
|
||||
uiBlockCount = m_flashInfo.uiBlockNum;
|
||||
iErasePos = 0;
|
||||
iEraseTimes = 0;
|
||||
while (uiBlockCount > 0) {
|
||||
iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS;
|
||||
iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE);
|
||||
if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
|
||||
if (m_pLog) {
|
||||
m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
iErasePos += iEraseBlockNum;
|
||||
uiBlockCount -= iEraseBlockNum;
|
||||
iEraseTimes++;
|
||||
if (iEraseTimes % 8 == 0) {
|
||||
if (m_callBackProc) {
|
||||
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep);
|
||||
emCallStep = CALL_MIDDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
iCSIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_callBackProc) {
|
||||
emCallStep = CALL_LAST;
|
||||
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
128
RKDevice.h
Normal file
128
RKDevice.h
Normal file
@ -0,0 +1,128 @@
|
||||
#ifndef RKDEVICE_HEADER
|
||||
#define RKDEVICE_HEADER
|
||||
#include "RKImage.h"
|
||||
#include "RKComm.h"
|
||||
#include "RKLog.h"
|
||||
#include "DefineHeader.h"
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define PAGE_SIZE 2048
|
||||
#define SPARE_SIZE 16
|
||||
#define CHIPINFO_LEN 16
|
||||
#define IDBLOCK_TOP 50
|
||||
|
||||
#define CALC_UNIT(a, b) ((a > 0) ? ((a - 1) / b + 1) : (a))
|
||||
#define BYTE2SECTOR(x) (CALC_UNIT(x, SECTOR_SIZE))
|
||||
#define PAGEALIGN(x) (CALC_UNIT(x, 4))
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _STRUCT_FLASH_INFO {
|
||||
char szManufacturerName[16];
|
||||
UINT uiFlashSize;
|
||||
USHORT usBlockSize;
|
||||
UINT uiPageSize;
|
||||
UINT uiSectorPerBlock;
|
||||
BYTE blockState[IDBLOCK_TOP];
|
||||
UINT uiBlockNum;
|
||||
BYTE bECCBits;
|
||||
BYTE bAccessTime;
|
||||
BYTE bFlashCS;
|
||||
USHORT usValidSecPerBlock;
|
||||
USHORT usPhyBlokcPerIDB;
|
||||
UINT uiSecNumPerIDB;
|
||||
} STRUCT_FLASH_INFO, *PSTRUCT_FLASH_INFO;
|
||||
typedef struct _STRUCT_FLASHINFO_CMD {
|
||||
UINT uiFlashSize;
|
||||
USHORT usBlockSize;
|
||||
BYTE bPageSize;
|
||||
BYTE bECCBits;
|
||||
BYTE bAccessTime;
|
||||
BYTE bManufCode;
|
||||
BYTE bFlashCS;
|
||||
BYTE reserved[501];
|
||||
} STRUCT_FLASHINFO_CMD, *PSTRUCT_FLASHINFO_CMD;
|
||||
#pragma pack()
|
||||
|
||||
class CRKDevice
|
||||
{
|
||||
public:
|
||||
USHORT GetVendorID();
|
||||
void SetVendorID(USHORT value);
|
||||
property<CRKDevice, USHORT, READ_WRITE> VendorID;
|
||||
|
||||
USHORT GetProductID();
|
||||
void SetProductID(USHORT value);
|
||||
property<CRKDevice, USHORT, READ_WRITE> ProductID;
|
||||
|
||||
ENUM_RKDEVICE_TYPE GetDeviceType();
|
||||
void SetDeviceType(ENUM_RKDEVICE_TYPE value);
|
||||
property<CRKDevice, ENUM_RKDEVICE_TYPE, READ_WRITE> DeviceType;
|
||||
|
||||
ENUM_RKUSB_TYPE GetUsbType();
|
||||
void SetUsbType(ENUM_RKUSB_TYPE value);
|
||||
property<CRKDevice, ENUM_RKUSB_TYPE, READ_WRITE> UsbType;
|
||||
|
||||
char *GetLayerName();
|
||||
void SetLayerName(char *value);
|
||||
property<CRKDevice, char *, READ_WRITE> LayerName;
|
||||
|
||||
DWORD GetLocationID();
|
||||
void SetLocationID(DWORD value);
|
||||
property<CRKDevice, DWORD, READ_WRITE> LocationID;
|
||||
|
||||
USHORT GetBcdUsb();
|
||||
void SetBcdUsb(USHORT value);
|
||||
property<CRKDevice, USHORT, READ_WRITE> BcdUsb;
|
||||
|
||||
ENUM_OS_TYPE GetOsType();
|
||||
void SetOsType(ENUM_OS_TYPE value);
|
||||
property<CRKDevice, ENUM_OS_TYPE, READ_WRITE> OsType;
|
||||
|
||||
CRKLog *GetLogObjectPointer();
|
||||
property<CRKDevice, CRKLog *, READ_ONLY> LogObjectPointer;
|
||||
|
||||
CRKComm *GetCommObjectPointer();
|
||||
property<CRKDevice, CRKComm *, READ_ONLY> CommObjectPointer;
|
||||
|
||||
void SetCallBackPointer(ProgressPromptCB value);
|
||||
property<CRKDevice, ProgressPromptCB, WRITE_ONLY> CallBackPointer;
|
||||
|
||||
int DownloadBoot();
|
||||
bool TestDevice();
|
||||
bool ResetDevice();
|
||||
bool PowerOffDevice();
|
||||
bool CheckChip();
|
||||
bool GetFlashInfo();
|
||||
int EraseAllBlocks();
|
||||
bool SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog);
|
||||
string GetLayerString(DWORD dwLocationID);
|
||||
CRKDevice(STRUCT_RKDEVICE_DESC &device);
|
||||
~CRKDevice();
|
||||
protected:
|
||||
STRUCT_FLASH_INFO m_flashInfo;
|
||||
PBYTE m_pFlashInfoData;
|
||||
USHORT m_usFlashInfoDataOffset;
|
||||
USHORT m_usFlashInfoDataLen;
|
||||
PBYTE m_chipData;
|
||||
CRKImage *m_pImage;
|
||||
CRKComm *m_pComm;
|
||||
CRKLog *m_pLog;
|
||||
ProgressPromptCB m_callBackProc;
|
||||
bool m_bEmmc;
|
||||
int EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount);
|
||||
int EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount);
|
||||
bool EraseEmmc();
|
||||
bool Boot_VendorRequest(DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize);
|
||||
private:
|
||||
USHORT m_vid;
|
||||
USHORT m_pid;
|
||||
ENUM_RKDEVICE_TYPE m_device;
|
||||
ENUM_OS_TYPE m_os;
|
||||
ENUM_RKUSB_TYPE m_usb;
|
||||
UINT m_locationID;
|
||||
USHORT m_bcdUsb;
|
||||
protected:
|
||||
char m_layerName[32];
|
||||
};
|
||||
|
||||
#endif
|
298
RKImage.cpp
Normal file
298
RKImage.cpp
Normal file
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include "RKImage.h"
|
||||
|
||||
DWORD CRKImage::GetVersion()
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
DWORD CRKImage::GetMergeVersion()
|
||||
{
|
||||
return m_mergeVersion;
|
||||
}
|
||||
STRUCT_RKTIME CRKImage::GetReleaseTime()
|
||||
{
|
||||
return m_releaseTime;
|
||||
}
|
||||
ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice()
|
||||
{
|
||||
return m_supportDevice;
|
||||
}
|
||||
ENUM_OS_TYPE CRKImage::GetOsType()
|
||||
{
|
||||
UINT *pOsType;
|
||||
pOsType = (UINT *)&m_reserved[4];
|
||||
return (ENUM_OS_TYPE)*pOsType;
|
||||
}
|
||||
|
||||
USHORT CRKImage::GetBackupSize()
|
||||
{
|
||||
USHORT *pBackupSize;
|
||||
pBackupSize = (USHORT *)&m_reserved[12];
|
||||
return *pBackupSize;
|
||||
}
|
||||
DWORD CRKImage::GetBootOffset()
|
||||
{
|
||||
return m_bootOffset;
|
||||
}
|
||||
DWORD CRKImage::GetBootSize()
|
||||
{
|
||||
return m_bootSize;
|
||||
}
|
||||
DWORD CRKImage::GetFWOffset()
|
||||
{
|
||||
return m_fwOffset;
|
||||
}
|
||||
long long CRKImage::GetFWSize()
|
||||
{
|
||||
return m_fwSize;
|
||||
}
|
||||
bool CRKImage::SaveBootFile(string filename)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
int iRead;
|
||||
file = fopen(filename.c_str(), "wb+");
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
BYTE buffer[1024];
|
||||
DWORD dwBufferSize = 1024;
|
||||
DWORD dwBootSize = m_bootSize;
|
||||
DWORD dwReadSize;
|
||||
fseek(m_pFile, m_bootOffset, SEEK_SET);
|
||||
do {
|
||||
dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize;
|
||||
iRead = fread(buffer, 1, dwReadSize, m_pFile);
|
||||
if (iRead != (int)dwReadSize) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
fwrite(buffer, 1, dwReadSize, file);
|
||||
dwBootSize -= dwReadSize;
|
||||
} while(dwBootSize > 0);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
bool CRKImage::SaveFWFile(string filename)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
int iRead;
|
||||
file = fopen(filename.c_str(), "wb+");
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
BYTE buffer[1024];
|
||||
DWORD dwBufferSize = 1024;
|
||||
long long dwFWSize = m_fwSize;
|
||||
DWORD dwReadSize;
|
||||
fseeko(m_pFile, m_fwOffset, SEEK_SET);
|
||||
do {
|
||||
dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize;
|
||||
iRead = fread(buffer, 1, dwReadSize, m_pFile);
|
||||
if (iRead != (int)dwReadSize) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
fwrite(buffer, 1, dwReadSize, file);
|
||||
dwFWSize -= dwReadSize;
|
||||
} while (dwFWSize > 0);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer)
|
||||
{
|
||||
if ( (dwOffset < 0) || (dwSize == 0) ) {
|
||||
return false;
|
||||
}
|
||||
if ( dwOffset+dwSize > m_fileSize) {
|
||||
return false;
|
||||
}
|
||||
fseeko(m_pFile, dwOffset, SEEK_SET);
|
||||
UINT uiActualRead;
|
||||
uiActualRead = fread(lpBuffer,1, dwSize, m_pFile);
|
||||
if (dwSize != uiActualRead){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize)
|
||||
{
|
||||
lpData = m_reserved;
|
||||
usSize = IMAGE_RESERVED_SIZE;
|
||||
}
|
||||
|
||||
CRKImage::CRKImage(string filename, bool &bCheck)
|
||||
{
|
||||
Version.setContainer(this);
|
||||
Version.getter(&CRKImage::GetVersion);
|
||||
MergeVersion.setContainer(this);
|
||||
MergeVersion.getter(&CRKImage::GetMergeVersion);
|
||||
ReleaseTime.setContainer(this);
|
||||
ReleaseTime.getter(&CRKImage::GetReleaseTime);
|
||||
SupportDevice.setContainer(this);
|
||||
SupportDevice.getter(&CRKImage::GetSupportDevice);
|
||||
OsType.setContainer(this);
|
||||
OsType.getter(&CRKImage::GetOsType);
|
||||
BackupSize.setContainer(this);
|
||||
BackupSize.getter(&CRKImage::GetBackupSize);
|
||||
BootOffset.setContainer(this);
|
||||
BootOffset.getter(&CRKImage::GetBootOffset);
|
||||
BootSize.setContainer(this);
|
||||
BootSize.getter(&CRKImage::GetBootSize);
|
||||
FWOffset.setContainer(this);
|
||||
FWOffset.getter(&CRKImage::GetFWOffset);
|
||||
FWSize.setContainer(this);
|
||||
FWSize.getter(&CRKImage::GetFWSize);
|
||||
SignFlag.setContainer(this);
|
||||
SignFlag.getter(&CRKImage::GetSignFlag);
|
||||
struct stat statBuf;
|
||||
m_bootObject = NULL;
|
||||
m_pFile = NULL;
|
||||
m_bSignFlag = false;
|
||||
|
||||
m_signMd5Size = 0;
|
||||
memset(m_md5, 0, 32);
|
||||
memset(m_signMd5, 0, 256);
|
||||
|
||||
char szName[256];
|
||||
strcpy(szName, filename.c_str());
|
||||
if(stat(szName, &statBuf) < 0) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
if (S_ISDIR(statBuf.st_mode)) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
m_fileSize = statBuf.st_size;
|
||||
|
||||
bool bOnlyBootFile=false;
|
||||
transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower);
|
||||
if (filename.find(".bin") != string::npos) {
|
||||
bOnlyBootFile = true;
|
||||
}
|
||||
|
||||
m_pFile = fopen(szName, "rb");
|
||||
if (!m_pFile) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int nMd5DataSize, iRead;
|
||||
long long ulFwSize;
|
||||
STRUCT_RKIMAGE_HEAD imageHead;
|
||||
if (!bOnlyBootFile) {
|
||||
fseeko(m_pFile, 0, SEEK_SET);
|
||||
iRead = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile);
|
||||
if (iRead != sizeof(STRUCT_RKIMAGE_HEAD)) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
if ( imageHead.uiTag != 0x57464B52 ) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I')) {
|
||||
ulFwSize = *((DWORD *)(&imageHead.reserved[16]));
|
||||
ulFwSize <<= 32;
|
||||
ulFwSize += imageHead.dwFWOffset;
|
||||
ulFwSize += imageHead.dwFWSize;
|
||||
} else
|
||||
ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize;
|
||||
nMd5DataSize = GetImageSize() - ulFwSize;
|
||||
if (nMd5DataSize >= 160) {
|
||||
m_bSignFlag = true;
|
||||
m_signMd5Size = nMd5DataSize - 32;
|
||||
fseeko(m_pFile, ulFwSize, SEEK_SET);
|
||||
iRead = fread(m_md5, 1, 32, m_pFile);
|
||||
if (iRead != 32) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
iRead = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile);
|
||||
if (iRead != (nMd5DataSize - 32)) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
fseeko(m_pFile, -32, SEEK_END);
|
||||
iRead = fread(m_md5, 1, 32, m_pFile);
|
||||
if (iRead != 32) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_version = imageHead.dwVersion;
|
||||
m_mergeVersion = imageHead.dwMergeVersion;
|
||||
m_releaseTime.usYear = imageHead.stReleaseTime.usYear;
|
||||
m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth;
|
||||
m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay;
|
||||
m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour;
|
||||
m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute;
|
||||
m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond;
|
||||
m_supportDevice = imageHead.emSupportChip;
|
||||
m_bootOffset = imageHead.dwBootOffset;
|
||||
m_bootSize = imageHead.dwBootSize;
|
||||
m_fwOffset = imageHead.dwFWOffset;
|
||||
m_fwSize = ulFwSize - m_fwOffset;
|
||||
memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE);
|
||||
} else {
|
||||
m_bootOffset = 0;
|
||||
m_bootSize = m_fileSize;
|
||||
}
|
||||
|
||||
PBYTE lpBoot;
|
||||
lpBoot = new BYTE[m_bootSize];
|
||||
fseeko(m_pFile, m_bootOffset, SEEK_SET);
|
||||
iRead = fread(lpBoot, 1, m_bootSize, m_pFile);
|
||||
if (iRead != (int)m_bootSize) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
bool bRet;
|
||||
m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet);
|
||||
if (!bRet) {
|
||||
bCheck = false;
|
||||
return;
|
||||
}
|
||||
if (bOnlyBootFile) {
|
||||
m_supportDevice = m_bootObject->SupportDevice;
|
||||
UINT *pOsType;
|
||||
pOsType = (UINT *)&m_reserved[4];
|
||||
*pOsType = (UINT)RK_OS;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
}
|
||||
bCheck = true;
|
||||
}
|
||||
CRKImage::~CRKImage()
|
||||
{
|
||||
if (m_pFile) {
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
}
|
||||
if (m_bootObject) {
|
||||
delete m_bootObject;
|
||||
m_bootObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
long long CRKImage::GetImageSize()
|
||||
{
|
||||
return m_fileSize;
|
||||
}
|
||||
int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5)
|
||||
{
|
||||
lpMd5 = m_md5;
|
||||
lpSignMd5 = m_signMd5;
|
||||
return m_signMd5Size;
|
||||
}
|
||||
bool CRKImage::GetSignFlag()
|
||||
{
|
||||
return m_bSignFlag;
|
||||
}
|
77
RKImage.h
Normal file
77
RKImage.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef RKIMAGE_HEADER
|
||||
#define RKIMAGE_HEADER
|
||||
#include "DefineHeader.h"
|
||||
#include "RKBoot.h"
|
||||
#define IMAGE_RESERVED_SIZE 61
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT uiTag;
|
||||
USHORT usSize;
|
||||
DWORD dwVersion;
|
||||
DWORD dwMergeVersion;
|
||||
STRUCT_RKTIME stReleaseTime;
|
||||
ENUM_RKDEVICE_TYPE emSupportChip;
|
||||
DWORD dwBootOffset;
|
||||
DWORD dwBootSize;
|
||||
DWORD dwFWOffset;
|
||||
DWORD dwFWSize;
|
||||
BYTE reserved[IMAGE_RESERVED_SIZE];
|
||||
} STRUCT_RKIMAGE_HEAD, *PSTRUCT_RKIMAGE_HEAD;
|
||||
#pragma pack()
|
||||
class CRKImage
|
||||
{
|
||||
public:
|
||||
UINT GetVersion();
|
||||
property<CRKImage, UINT, READ_ONLY> Version;
|
||||
UINT GetMergeVersion();
|
||||
property<CRKImage, UINT, READ_ONLY> MergeVersion;
|
||||
STRUCT_RKTIME GetReleaseTime();
|
||||
property<CRKImage, STRUCT_RKTIME, READ_ONLY> ReleaseTime;
|
||||
ENUM_RKDEVICE_TYPE GetSupportDevice();
|
||||
property<CRKImage, ENUM_RKDEVICE_TYPE, READ_ONLY> SupportDevice;
|
||||
ENUM_OS_TYPE GetOsType();
|
||||
property<CRKImage, ENUM_OS_TYPE, READ_ONLY> OsType;
|
||||
|
||||
unsigned short GetBackupSize();
|
||||
property<CRKImage, unsigned short, READ_ONLY> BackupSize;
|
||||
UINT GetBootOffset();
|
||||
property<CRKImage, UINT, READ_ONLY> BootOffset;
|
||||
UINT GetBootSize();
|
||||
property<CRKImage, UINT, READ_ONLY> BootSize;
|
||||
UINT GetFWOffset();
|
||||
property<CRKImage, UINT, READ_ONLY> FWOffset;
|
||||
long long GetFWSize();
|
||||
property<CRKImage, long long, READ_ONLY> FWSize;
|
||||
bool GetSignFlag();
|
||||
property<CRKImage, bool, READ_ONLY> SignFlag;
|
||||
|
||||
CRKBoot *m_bootObject;
|
||||
bool SaveBootFile(string filename);
|
||||
bool SaveFWFile(string filename);
|
||||
bool GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer);
|
||||
void GetReservedData(PBYTE &lpData, USHORT &usSize);
|
||||
int GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5);
|
||||
long long GetImageSize();
|
||||
CRKImage(string filename, bool &bCheck);
|
||||
~CRKImage();
|
||||
protected:
|
||||
|
||||
private:
|
||||
DWORD m_version;
|
||||
DWORD m_mergeVersion;
|
||||
STRUCT_RKTIME m_releaseTime;
|
||||
ENUM_RKDEVICE_TYPE m_supportDevice;
|
||||
DWORD m_bootOffset;
|
||||
DWORD m_bootSize;
|
||||
DWORD m_fwOffset;
|
||||
long long m_fwSize;
|
||||
|
||||
BYTE m_md5[32];
|
||||
BYTE m_signMd5[256];
|
||||
BYTE m_reserved[IMAGE_RESERVED_SIZE];
|
||||
bool m_bSignFlag;
|
||||
int m_signMd5Size;
|
||||
FILE *m_pFile;
|
||||
long long m_fileSize;
|
||||
};
|
||||
#endif
|
121
RKLog.cpp
Normal file
121
RKLog.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include "RKLog.h"
|
||||
int file_stat(string strPath)
|
||||
{
|
||||
struct stat statBuf;
|
||||
int ret;
|
||||
ret = stat(strPath.c_str(), &statBuf);
|
||||
if (ret != 0) {
|
||||
return STAT_NOT_EXIST;
|
||||
}
|
||||
if (S_ISDIR(statBuf.st_mode))
|
||||
return STAT_DIR;
|
||||
return STAT_FILE;
|
||||
}
|
||||
string CRKLog::GetLogSavePath()
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
bool CRKLog::GetEnableLog()
|
||||
{
|
||||
return m_enable;
|
||||
}
|
||||
void CRKLog::SetEnableLog(bool bEnable)
|
||||
{
|
||||
m_enable = bEnable;
|
||||
}
|
||||
|
||||
CRKLog::CRKLog(string logFilePath, string logFileName, bool enable)
|
||||
{
|
||||
LogSavePath.setContainer(this);
|
||||
LogSavePath.getter(&CRKLog::GetLogSavePath);
|
||||
|
||||
EnableLog.setContainer(this);
|
||||
EnableLog.getter(&CRKLog::GetEnableLog);
|
||||
EnableLog.setter(&CRKLog::SetEnableLog);
|
||||
|
||||
if (!opendir(logFilePath.c_str())) {
|
||||
m_path = "";
|
||||
} else {
|
||||
if (logFilePath[logFilePath.size() - 1] != '/') {
|
||||
logFilePath += '/';
|
||||
}
|
||||
m_path = logFilePath;
|
||||
}
|
||||
if (logFileName.size() <= 0) {
|
||||
m_name = "Log";
|
||||
} else
|
||||
m_name = logFileName;
|
||||
m_enable = enable;
|
||||
|
||||
}
|
||||
CRKLog::~CRKLog()
|
||||
{
|
||||
}
|
||||
void CRKLog::Record(const char *lpFmt,...)
|
||||
{
|
||||
/************************* Êä³öµ½ÈÕÖ¾ ***********************/
|
||||
char szBuf[1024] = "";
|
||||
GET_FMT_STRING(lpFmt, szBuf);
|
||||
if ((m_enable) && (m_path.size() > 0))
|
||||
{
|
||||
Write( szBuf);
|
||||
}
|
||||
}
|
||||
bool CRKLog::Write(string text)
|
||||
{
|
||||
time_t now;
|
||||
struct tm timeNow;
|
||||
char szDateTime[100];
|
||||
string strName;
|
||||
FILE *file=NULL;
|
||||
time(&now);
|
||||
localtime_r(&now, &timeNow);
|
||||
sprintf(szDateTime, "%04d-%02d-%02d.txt", timeNow.tm_year + 1900, timeNow.tm_mon + 1, timeNow.tm_mday);
|
||||
strName = m_path + m_name+szDateTime;
|
||||
|
||||
try {
|
||||
file = fopen(strName.c_str(), "ab+");
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
sprintf(szDateTime, "%02d:%02d:%02d \t", timeNow.tm_hour, timeNow.tm_min, timeNow.tm_sec);
|
||||
text = szDateTime + text + "\r\n";
|
||||
fwrite(text.c_str(), 1, text.size() * sizeof(char), file);
|
||||
fclose(file);
|
||||
} catch (...) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CRKLog::SaveBuffer(string fileName, PBYTE lpBuffer, DWORD dwSize)
|
||||
{
|
||||
FILE *file;
|
||||
file = fopen(fileName.c_str(), "wb+");
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
fwrite(lpBuffer, 1, dwSize, file);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
void CRKLog::PrintBuffer(string &strOutput, PBYTE lpBuffer, DWORD dwSize, UINT uiLineCount)
|
||||
{
|
||||
UINT i,count;
|
||||
char strHex[32];
|
||||
strOutput = "";
|
||||
for (i = 0, count = 0; i < dwSize; i++, count++) {
|
||||
sprintf(strHex, "%X", lpBuffer[i]);
|
||||
strOutput = strOutput + " " + strHex;
|
||||
if (count >= uiLineCount) {
|
||||
strOutput += "\r\n";
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
41
RKLog.h
Normal file
41
RKLog.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef RKLOG_HEADER
|
||||
#define RKLOG_HEADER
|
||||
#include "DefineHeader.h"
|
||||
|
||||
#define GET_FMT_STRING(fmt, buf) \
|
||||
{ \
|
||||
va_list args; \
|
||||
va_start(args, fmt); \
|
||||
vsnprintf(buf, sizeof(buf)-1, fmt, args); \
|
||||
va_end(args); \
|
||||
buf[sizeof(buf)-1] = 0x00; \
|
||||
};
|
||||
|
||||
class CRKLog
|
||||
{
|
||||
public:
|
||||
string GetLogSavePath();
|
||||
bool GetEnableLog();
|
||||
void SetEnableLog(bool bEnable);
|
||||
property<CRKLog, string, READ_ONLY> LogSavePath;
|
||||
property<CRKLog, bool, READ_WRITE> EnableLog;
|
||||
CRKLog(string logFilePath, string logFileName, bool enable = true);
|
||||
~CRKLog();
|
||||
bool SaveBuffer(string fileName, PBYTE lpBuffer, DWORD dwSize);
|
||||
void PrintBuffer(string &strOutput, PBYTE lpBuffer, DWORD dwSize, UINT uiLineCount = 16);
|
||||
void Record(const char *lpFmt, ...);
|
||||
|
||||
protected:
|
||||
private:
|
||||
string m_path;
|
||||
string m_name;
|
||||
bool m_enable;
|
||||
bool Write(string text);
|
||||
};
|
||||
typedef enum {
|
||||
STAT_NOT_EXIST = 0,
|
||||
STAT_FILE,
|
||||
STAT_DIR
|
||||
} ENUM_FILE_STAT;
|
||||
int file_stat(string strPath);
|
||||
#endif
|
614
RKScan.cpp
Normal file
614
RKScan.cpp
Normal file
@ -0,0 +1,614 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include "RKScan.h"
|
||||
#define BUSID(id) ((id & 0x0000FF00) >> 8)
|
||||
int CRKScan::GetDEVICE_COUNTS()
|
||||
{
|
||||
return m_list.size();
|
||||
}
|
||||
|
||||
UINT CRKScan::GetMSC_TIMEOUT()
|
||||
{
|
||||
return m_waitMscSecond;
|
||||
}
|
||||
|
||||
UINT CRKScan::GetRKUSB_TIMEOUT()
|
||||
{
|
||||
return m_waitRKusbSecond;
|
||||
}
|
||||
|
||||
void CRKScan::SetMSC_TIMEOUT(UINT value)
|
||||
{
|
||||
m_waitMscSecond = value;
|
||||
}
|
||||
|
||||
void CRKScan::SetRKUSB_TIMEOUT(UINT value)
|
||||
{
|
||||
m_waitRKusbSecond = value;
|
||||
}
|
||||
|
||||
CRKScan::CRKScan(UINT uiMscTimeout, UINT uiRKusbTimeout)
|
||||
{
|
||||
DEVICE_COUNTS.setContainer(this);
|
||||
DEVICE_COUNTS.getter(&CRKScan::GetDEVICE_COUNTS);
|
||||
|
||||
MSC_TIMEOUT.setContainer(this);
|
||||
MSC_TIMEOUT.getter(&CRKScan::GetMSC_TIMEOUT);
|
||||
MSC_TIMEOUT.setter(&CRKScan::SetMSC_TIMEOUT);
|
||||
|
||||
RKUSB_TIMEOUT.setContainer(this);
|
||||
RKUSB_TIMEOUT.getter(&CRKScan::GetRKUSB_TIMEOUT);
|
||||
RKUSB_TIMEOUT.setter(&CRKScan::SetRKUSB_TIMEOUT);
|
||||
|
||||
m_waitMscSecond = uiMscTimeout;
|
||||
m_waitRKusbSecond = uiRKusbTimeout;
|
||||
m_log = NULL;
|
||||
m_list.clear();
|
||||
m_deviceConfigSet.clear();
|
||||
m_deviceMscConfigSet.clear();
|
||||
}
|
||||
bool CRKScan::FindRockusbVidPid(ENUM_RKDEVICE_TYPE type, USHORT &usVid, USHORT &usPid)
|
||||
{
|
||||
UINT i;
|
||||
bool bRet = false;
|
||||
for (i = 0; i < m_deviceConfigSet.size(); i++) {
|
||||
if (m_deviceConfigSet[i].emDeviceType == type) {
|
||||
usVid = m_deviceConfigSet[i].usVid;
|
||||
usPid = m_deviceConfigSet[i].usPid;
|
||||
bRet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
void CRKScan::AddRockusbVidPid(USHORT newVid, USHORT newPid, USHORT oldVid, USHORT oldPid)
|
||||
{
|
||||
if ((newVid == 0) || (newPid == 0) || (oldVid == 0) || (oldPid == 0)) {
|
||||
return;
|
||||
}
|
||||
STRUCT_DEVICE_CONFIG config;
|
||||
unsigned int i;
|
||||
for (i = 0; i < m_deviceConfigSet.size(); i++) {
|
||||
if ((m_deviceConfigSet[i].usVid == oldVid) && (m_deviceConfigSet[i].usPid == oldPid)) {
|
||||
config.usVid = newVid;
|
||||
config.usPid = newPid;
|
||||
config.emDeviceType = m_deviceConfigSet[i].emDeviceType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < m_deviceConfigSet.size())
|
||||
m_deviceConfigSet.push_back(config);
|
||||
}
|
||||
|
||||
void CRKScan::SetVidPid(USHORT mscVid, USHORT mscPid)
|
||||
{
|
||||
STRUCT_DEVICE_CONFIG config;
|
||||
m_deviceConfigSet.clear();
|
||||
|
||||
config.emDeviceType = RK27_DEVICE;
|
||||
config.usPid = 0x3201;
|
||||
config.usVid = 0x071B;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK28_DEVICE;
|
||||
config.usPid = 0x3228;
|
||||
config.usVid = 0x071B;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKNANO_DEVICE;
|
||||
config.usPid = 0x3226;
|
||||
config.usVid = 0x071B;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKCROWN_DEVICE;
|
||||
config.usPid = 0x261A;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK281X_DEVICE;
|
||||
config.usPid = 0x281A;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKCAYMAN_DEVICE;
|
||||
config.usPid = 0x273A;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK29_DEVICE;
|
||||
config.usPid = 0x290A;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKPANDA_DEVICE;
|
||||
config.usPid = 0x282B;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKSMART_DEVICE;
|
||||
config.usPid = 0x262C;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK292X_DEVICE;
|
||||
config.usPid = 0x292A;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK30_DEVICE;
|
||||
config.usPid = 0x300A;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK30B_DEVICE;
|
||||
config.usPid = 0x300B;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK31_DEVICE;
|
||||
config.usPid = 0x310B;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RK32_DEVICE;
|
||||
config.usPid = 0x320A;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceConfigSet.push_back(config);
|
||||
|
||||
m_deviceMscConfigSet.clear();
|
||||
|
||||
config.emDeviceType = RKNONE_DEVICE;
|
||||
config.usPid = 0x3203;
|
||||
config.usVid = 0x071B;
|
||||
m_deviceMscConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKNONE_DEVICE;
|
||||
config.usPid = 0x3205;
|
||||
config.usVid = 0x071B;
|
||||
m_deviceMscConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKNONE_DEVICE;
|
||||
config.usPid = 0x2910;
|
||||
config.usVid = 0x0BB4;
|
||||
m_deviceMscConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKNONE_DEVICE;
|
||||
config.usPid = 0x0000;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceMscConfigSet.push_back(config);
|
||||
|
||||
config.emDeviceType = RKNONE_DEVICE;
|
||||
config.usPid = 0x0010;
|
||||
config.usVid = 0x2207;
|
||||
m_deviceMscConfigSet.push_back(config);
|
||||
|
||||
if ((mscVid != 0) || (mscPid != 0)) {
|
||||
if (FindConfigSetPos(m_deviceMscConfigSet, mscVid, mscPid) == -1) {
|
||||
config.emDeviceType = RKNONE_DEVICE;
|
||||
config.usPid = mscPid;
|
||||
config.usVid = mscVid;
|
||||
m_deviceMscConfigSet.push_back(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
int CRKScan::FindWaitSetPos(const RKDEVICE_CONFIG_SET &waitDeviceSet, USHORT vid, USHORT pid)
|
||||
{
|
||||
int pos=-1;
|
||||
UINT i;
|
||||
for ( i = 0; i < waitDeviceSet.size(); i++ ) {
|
||||
if ( (vid == waitDeviceSet[i].usVid) && (pid == waitDeviceSet[i].usPid) ) {
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
int CRKScan::FindConfigSetPos(RKDEVICE_CONFIG_SET &devConfigSet, USHORT vid, USHORT pid)
|
||||
{
|
||||
int pos = -1;
|
||||
UINT i;
|
||||
for ( i = 0; i < devConfigSet.size(); i++ ) {
|
||||
if ( (vid == devConfigSet[i].usVid) && (pid == devConfigSet[i].usPid) ) {
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
void CRKScan::EnumerateUsbDevice(RKDEVICE_DESC_SET &list, UINT &uiTotalMatchDevices)
|
||||
{
|
||||
STRUCT_RKDEVICE_DESC desc;
|
||||
struct libusb_device_descriptor descriptor;
|
||||
int ret,i,cnt;
|
||||
|
||||
uiTotalMatchDevices = 0;
|
||||
libusb_device **pDevs = NULL;
|
||||
libusb_device *dev;
|
||||
ret = libusb_get_device_list(NULL, &pDevs);
|
||||
if (ret < 0) {
|
||||
if (m_log)
|
||||
m_log->Record("Error:EnumerateUsbDevice-->get_device_list failed,err=%d!", ret);
|
||||
return;
|
||||
}
|
||||
cnt = ret;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
dev = pDevs[i];
|
||||
if (dev) {
|
||||
ret = libusb_get_device_descriptor (dev, &descriptor);
|
||||
if (ret < 0) {
|
||||
libusb_free_device_list(pDevs, 1);
|
||||
if (m_log)
|
||||
m_log->Record("Error:EnumerateUsbDevice-->get_device_descriptor failed,err=%d!", ret);
|
||||
return;
|
||||
}
|
||||
desc.emDeviceType = RKNONE_DEVICE;
|
||||
desc.emUsbType = RKUSB_NONE;
|
||||
desc.pUsbHandle = (void *)dev;
|
||||
desc.usbcdUsb = descriptor.bcdUSB;
|
||||
desc.usVid = descriptor.idVendor;
|
||||
desc.usPid = descriptor.idProduct;
|
||||
desc.uiLocationID = libusb_get_bus_number(dev);
|
||||
desc.uiLocationID <<= 8;
|
||||
desc.uiLocationID += libusb_get_port_number(dev);
|
||||
libusb_ref_device(dev);
|
||||
uiTotalMatchDevices++;
|
||||
list.push_back(desc);
|
||||
}
|
||||
|
||||
}
|
||||
libusb_free_device_list(pDevs, 1);
|
||||
|
||||
}
|
||||
|
||||
void CRKScan::FreeDeviceList(RKDEVICE_DESC_SET &list)
|
||||
{
|
||||
device_list_iter iter;
|
||||
for (iter = list.begin(); iter != list.end(); iter++) {
|
||||
if ((*iter).pUsbHandle) {
|
||||
libusb_unref_device((libusb_device *)((*iter).pUsbHandle));
|
||||
(*iter).pUsbHandle = NULL;
|
||||
}
|
||||
}
|
||||
list.clear();
|
||||
}
|
||||
bool CRKScan::IsRockusbDevice(ENUM_RKDEVICE_TYPE &type, USHORT vid, USHORT pid)
|
||||
{
|
||||
int iPos;
|
||||
iPos = FindConfigSetPos(m_deviceConfigSet, vid, pid);
|
||||
if (iPos != -1) {
|
||||
type = m_deviceConfigSet[iPos].emDeviceType;
|
||||
return true;
|
||||
}
|
||||
if (vid == 0x2207) {
|
||||
if ((pid >> 8) > 0) {
|
||||
type = RKNONE_DEVICE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int CRKScan::Search(UINT type)
|
||||
{
|
||||
device_list_iter iter,new_iter;
|
||||
ENUM_RKDEVICE_TYPE devType;
|
||||
UINT uiTotalDevice;
|
||||
int iPos;
|
||||
|
||||
FreeDeviceList(m_list);
|
||||
EnumerateUsbDevice( m_list, uiTotalDevice );
|
||||
|
||||
for ( iter = m_list.begin(); iter != m_list.end(); ) {
|
||||
if( (iPos = FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid)) != -1 ) {
|
||||
(*iter).emDeviceType = RKNONE_DEVICE;
|
||||
iter++;
|
||||
continue;
|
||||
} else if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid) ) {
|
||||
(*iter).emDeviceType = devType;
|
||||
iter++;
|
||||
continue;
|
||||
} else {
|
||||
if ((*iter).pUsbHandle) {
|
||||
libusb_unref_device((libusb_device *)((*iter).pUsbHandle));
|
||||
(*iter).pUsbHandle = NULL;
|
||||
}
|
||||
iter = m_list.erase(iter);
|
||||
uiTotalDevice--;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_list.size() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (type & RKUSB_MASKROM) == 0 ) {
|
||||
for ( iter = m_list.begin(); iter != m_list.end(); ) {
|
||||
if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 0) ) {
|
||||
if ((*iter).pUsbHandle) {
|
||||
libusb_unref_device((libusb_device *)((*iter).pUsbHandle));
|
||||
(*iter).pUsbHandle = NULL;
|
||||
}
|
||||
iter = m_list.erase(iter);
|
||||
uiTotalDevice--;
|
||||
} else {
|
||||
iter++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_list.size() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (type & RKUSB_LOADER) == 0 ) {
|
||||
for ( iter = m_list.begin(); iter != m_list.end(); ) {
|
||||
if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 1) ) {
|
||||
if ((*iter).pUsbHandle) {
|
||||
libusb_unref_device((libusb_device *)((*iter).pUsbHandle));
|
||||
(*iter).pUsbHandle = NULL;
|
||||
}
|
||||
iter = m_list.erase(iter);
|
||||
uiTotalDevice--;
|
||||
} else {
|
||||
iter++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_list.size() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (type & RKUSB_MSC) == 0 ) {
|
||||
for ( iter = m_list.begin(); iter != m_list.end(); ) {
|
||||
if(FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) {
|
||||
if ((*iter).pUsbHandle) {
|
||||
libusb_unref_device((libusb_device *)((*iter).pUsbHandle));
|
||||
(*iter).pUsbHandle = NULL;
|
||||
}
|
||||
iter = m_list.erase(iter);
|
||||
uiTotalDevice--;
|
||||
} else {
|
||||
iter++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_list.size() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) {
|
||||
if (FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) {
|
||||
(*iter).emUsbType = RKUSB_MSC;
|
||||
} else {
|
||||
USHORT usTemp;
|
||||
usTemp = (*iter).usbcdUsb;
|
||||
usTemp= usTemp & 0x1;
|
||||
if ( usTemp == 0 )
|
||||
(*iter).emUsbType = RKUSB_MASKROM;
|
||||
else
|
||||
(*iter).emUsbType = RKUSB_LOADER;
|
||||
}
|
||||
}
|
||||
return m_list.size();
|
||||
}
|
||||
bool CRKScan::MutexWait(UINT_VECTOR &vecExistedDevice, STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid)
|
||||
{
|
||||
device_list_iter iter;
|
||||
int uiWaitSecond;
|
||||
int iFoundCount = 0;
|
||||
UINT iRet,i;
|
||||
bool bFound = false;
|
||||
if (usbType == RKUSB_MSC)
|
||||
uiWaitSecond = m_waitMscSecond;
|
||||
else
|
||||
uiWaitSecond = m_waitRKusbSecond;
|
||||
time_t tmInit, tmNow;
|
||||
time(&tmInit);
|
||||
device.uiLocationID = 0;
|
||||
while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) {
|
||||
iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC);
|
||||
if ( iRet == vecExistedDevice.size() + 1 ) {
|
||||
for (i = 0; i < vecExistedDevice.size(); i++) {
|
||||
for (iter = m_list.begin(); iter != m_list.end(); ) {
|
||||
if ((*iter).uiLocationID == vecExistedDevice[i]) {
|
||||
iter = m_list.erase(iter);
|
||||
} else
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
if (m_list.size() != 1) {
|
||||
device.uiLocationID = 0;
|
||||
iFoundCount = 0;
|
||||
} else {
|
||||
iter = m_list.begin();
|
||||
if (device.uiLocationID == 0) {
|
||||
iFoundCount++;
|
||||
device.uiLocationID = (*iter).uiLocationID;
|
||||
} else {
|
||||
if (device.uiLocationID == (*iter).uiLocationID) {
|
||||
iFoundCount++;
|
||||
} else {
|
||||
device.uiLocationID = 0;
|
||||
iFoundCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
device.uiLocationID = 0;
|
||||
iFoundCount = 0;
|
||||
}
|
||||
if (iFoundCount >= 10) {
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound) {
|
||||
return false;
|
||||
}
|
||||
bFound = Wait(device, usbType, usVid, usPid);
|
||||
return bFound;
|
||||
}
|
||||
|
||||
bool CRKScan::MutexWaitPrepare(UINT_VECTOR &vecExistedDevice, DWORD uiOfflineDevice)
|
||||
{
|
||||
int iRet, iRet2;
|
||||
device_list_iter iter;
|
||||
time_t timeInit, timeNow;
|
||||
time(&timeInit);
|
||||
iRet = iRet2 =0;
|
||||
while ((time(&timeNow) - timeInit) <= 3) {
|
||||
iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC);
|
||||
usleep(20000);
|
||||
iRet2 = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC);
|
||||
if (iRet2 == iRet) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((iRet <= 0) || (iRet2 != iRet)) {
|
||||
return false;
|
||||
}
|
||||
vecExistedDevice.clear();
|
||||
bool bFound = false;
|
||||
for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) {
|
||||
if ((*iter).uiLocationID != uiOfflineDevice) {
|
||||
vecExistedDevice.push_back((*iter).uiLocationID);
|
||||
} else
|
||||
bFound = true;
|
||||
}
|
||||
if (!bFound) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool CRKScan::Wait(STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid)
|
||||
{
|
||||
RKDEVICE_DESC_SET deviceList;
|
||||
ENUM_RKUSB_TYPE curDeviceType;
|
||||
ENUM_RKDEVICE_TYPE devType;
|
||||
device_list_iter iter;
|
||||
UINT totalDevice;
|
||||
int uiWaitSecond;
|
||||
int iFoundCount = 0;
|
||||
bool bRet = false;
|
||||
if (usbType == RKUSB_MSC)
|
||||
uiWaitSecond = m_waitMscSecond;
|
||||
else
|
||||
uiWaitSecond = m_waitRKusbSecond;
|
||||
time_t tmInit, tmNow;
|
||||
time(&tmInit);
|
||||
while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) {
|
||||
FreeDeviceList(deviceList);
|
||||
EnumerateUsbDevice(deviceList, totalDevice);
|
||||
for ( iter = deviceList.begin(); iter != deviceList.end(); iter++ ) {
|
||||
if ((BUSID((*iter).uiLocationID) != BUSID(device.uiLocationID)) ||
|
||||
((BUSID((*iter).uiLocationID) == BUSID(device.uiLocationID)) && ((*iter).uiLocationID >= device.uiLocationID))) {
|
||||
if ((usVid != 0) || (usPid != 0)) {
|
||||
if ( ((*iter).usVid != usVid) || ((*iter).usPid != usPid) )
|
||||
continue;
|
||||
}
|
||||
if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) {
|
||||
if ( ((*iter).usbcdUsb & 0x0001) == 0 )
|
||||
curDeviceType = RKUSB_MASKROM;
|
||||
else
|
||||
curDeviceType = RKUSB_LOADER;
|
||||
} else if ( FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1 ) {
|
||||
curDeviceType = RKUSB_MSC;
|
||||
} else
|
||||
curDeviceType = RKUSB_NONE;
|
||||
|
||||
if ( curDeviceType == usbType ) {
|
||||
iFoundCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( iter == deviceList.end() ) {
|
||||
iFoundCount = 0;
|
||||
}
|
||||
if ( iFoundCount >= 8 ) {
|
||||
device.usVid = (*iter).usVid;
|
||||
device.usPid = (*iter).usPid;
|
||||
device.uiLocationID = (*iter).uiLocationID;
|
||||
device.pUsbHandle= (*iter).pUsbHandle;
|
||||
device.emUsbType = usbType;
|
||||
device.usbcdUsb = (*iter).usbcdUsb;
|
||||
libusb_ref_device((libusb_device *)device.pUsbHandle);
|
||||
|
||||
if (usbType == RKUSB_MSC) {
|
||||
device.emDeviceType = RKNONE_DEVICE;
|
||||
} else {
|
||||
if (IsRockusbDevice(devType, device.usVid, device.usPid))
|
||||
device.emDeviceType = devType;
|
||||
}
|
||||
bRet = true;
|
||||
break;
|
||||
}
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
FreeDeviceList(deviceList);
|
||||
return bRet;
|
||||
}
|
||||
int CRKScan::GetPos(UINT locationID)
|
||||
{
|
||||
device_list_iter iter;
|
||||
int pos = 0;
|
||||
bool bFound = false;
|
||||
for (iter = m_list.begin(); iter != m_list.end(); iter++) {
|
||||
if (locationID == (*iter).uiLocationID) {
|
||||
bFound=true;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return (bFound ? pos : -1);
|
||||
}
|
||||
bool CRKScan::GetDevice(STRUCT_RKDEVICE_DESC &device, int pos)
|
||||
{
|
||||
if ( (pos < 0) || (pos >= (int)m_list.size()) ) {
|
||||
return false;
|
||||
}
|
||||
device_list_iter iter;
|
||||
for (iter = m_list.begin(); iter != m_list.end(); iter++) {
|
||||
if (pos == 0) {
|
||||
break;
|
||||
}
|
||||
pos--;
|
||||
}
|
||||
device.usVid = (*iter).usVid;
|
||||
device.usPid = (*iter).usPid;
|
||||
device.emDeviceType = (*iter).emDeviceType;
|
||||
device.emUsbType = (*iter).emUsbType;
|
||||
device.uiLocationID = (*iter).uiLocationID;
|
||||
device.pUsbHandle= (*iter).pUsbHandle;
|
||||
device.usbcdUsb = (*iter).usbcdUsb;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRKScan::SetLogObject(CRKLog *pLog)
|
||||
{
|
||||
if (pLog) {
|
||||
if (m_log) {
|
||||
delete m_log;
|
||||
}
|
||||
m_log = pLog;
|
||||
} else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
CRKScan::~CRKScan()
|
||||
{
|
||||
FreeDeviceList(m_list);
|
||||
if (m_log) {
|
||||
delete m_log;
|
||||
m_log = NULL;
|
||||
}
|
||||
}
|
52
RKScan.h
Normal file
52
RKScan.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef RKSCAN_HEADER
|
||||
#define RKSCAN_HEADER
|
||||
#include "DefineHeader.h"
|
||||
#include "RKLog.h"
|
||||
|
||||
typedef struct {
|
||||
USHORT usVid;
|
||||
USHORT usPid;
|
||||
ENUM_RKDEVICE_TYPE emDeviceType;
|
||||
} STRUCT_DEVICE_CONFIG, *PSTRUCT_DEVICE_CONFIG;
|
||||
|
||||
typedef vector<STRUCT_DEVICE_CONFIG> RKDEVICE_CONFIG_SET;
|
||||
class CRKScan
|
||||
{
|
||||
public:
|
||||
UINT GetMSC_TIMEOUT();
|
||||
void SetMSC_TIMEOUT(UINT value);
|
||||
property<CRKScan, UINT, READ_WRITE> MSC_TIMEOUT;
|
||||
|
||||
UINT GetRKUSB_TIMEOUT();
|
||||
void SetRKUSB_TIMEOUT(UINT value);
|
||||
property<CRKScan, UINT, READ_WRITE> RKUSB_TIMEOUT;
|
||||
|
||||
int GetDEVICE_COUNTS();
|
||||
property<CRKScan, int, READ_ONLY> DEVICE_COUNTS;
|
||||
|
||||
CRKScan(UINT uiMscTimeout = 30, UINT uiRKusbTimeout = 20);
|
||||
void SetVidPid(USHORT mscVid = 0, USHORT mscPid = 0);
|
||||
void AddRockusbVidPid(USHORT newVid, USHORT newPid, USHORT oldVid, USHORT oldPid);
|
||||
bool FindRockusbVidPid(ENUM_RKDEVICE_TYPE type, USHORT &usVid, USHORT &usPid);
|
||||
int Search(UINT type);
|
||||
bool Wait(STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid = 0, USHORT usPid = 0);
|
||||
bool MutexWaitPrepare(UINT_VECTOR &vecExistedDevice, DWORD uiOfflineDevice);
|
||||
bool MutexWait(UINT_VECTOR &vecExistedDevice, STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid = 0, USHORT usPid = 0);
|
||||
int GetPos(UINT locationID);
|
||||
bool GetDevice(STRUCT_RKDEVICE_DESC &device, int pos);
|
||||
bool SetLogObject(CRKLog *pLog);
|
||||
~CRKScan();
|
||||
private:
|
||||
UINT m_waitRKusbSecond;
|
||||
UINT m_waitMscSecond;
|
||||
CRKLog *m_log;
|
||||
RKDEVICE_DESC_SET m_list;
|
||||
RKDEVICE_CONFIG_SET m_deviceConfigSet;
|
||||
RKDEVICE_CONFIG_SET m_deviceMscConfigSet;
|
||||
int FindConfigSetPos(RKDEVICE_CONFIG_SET &devConfigSet, USHORT vid, USHORT pid);
|
||||
int FindWaitSetPos(const RKDEVICE_CONFIG_SET &waitDeviceSet, USHORT vid, USHORT pid);
|
||||
void EnumerateUsbDevice(RKDEVICE_DESC_SET &list, UINT &uiTotalMatchDevices);
|
||||
void FreeDeviceList(RKDEVICE_DESC_SET &list);
|
||||
bool IsRockusbDevice(ENUM_RKDEVICE_TYPE &type, USHORT vid, USHORT pid);
|
||||
};
|
||||
#endif
|
17
Readme.txt
Normal file
17
Readme.txt
Normal file
@ -0,0 +1,17 @@
|
||||
rkDevelopTool gives you a simple way to read/write rockusb device.let's start.
|
||||
|
||||
compile and install
|
||||
1 download libusb source from https://github.com/libusb/libusb.git
|
||||
2 go into root of libusb
|
||||
3 ./autogen.sh (libudev must be installed by apt-get install libudev1 or run cmd "./configure --disable-udev")
|
||||
4 make && make install
|
||||
5 go into root of rkDevelopTool
|
||||
6 make && make install
|
||||
|
||||
rkDeveloptool usage,input "rkDevelopTool -h" to see
|
||||
|
||||
example:
|
||||
1.download kernel.img
|
||||
./rkDevelopTool db RKXXLoader.bin //download usbcode to device
|
||||
./rkDevelopTool wl 0x8000 kernel.img //0x8000 is base of kernel partition,unit is sector.
|
||||
./rkDevelopTool rd //reset device
|
0
config.ini
Normal file
0
config.ini
Normal file
362
crc.cpp
Normal file
362
crc.cpp
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include "DefineHeader.h"
|
||||
UINT gTable_Crc32[256] =
|
||||
{//crfc32 factor 0x04C10DB7
|
||||
0x00000000, 0x04c10db7, 0x09821b6e, 0x0d4316d9,
|
||||
0x130436dc, 0x17c53b6b, 0x1a862db2, 0x1e472005,
|
||||
0x26086db8, 0x22c9600f, 0x2f8a76d6, 0x2b4b7b61,
|
||||
0x350c5b64, 0x31cd56d3, 0x3c8e400a, 0x384f4dbd,
|
||||
0x4c10db70, 0x48d1d6c7, 0x4592c01e, 0x4153cda9,
|
||||
0x5f14edac, 0x5bd5e01b, 0x5696f6c2, 0x5257fb75,
|
||||
0x6a18b6c8, 0x6ed9bb7f, 0x639aada6, 0x675ba011,
|
||||
0x791c8014, 0x7ddd8da3, 0x709e9b7a, 0x745f96cd,
|
||||
0x9821b6e0, 0x9ce0bb57, 0x91a3ad8e, 0x9562a039,
|
||||
0x8b25803c, 0x8fe48d8b, 0x82a79b52, 0x866696e5,
|
||||
0xbe29db58, 0xbae8d6ef, 0xb7abc036, 0xb36acd81,
|
||||
0xad2ded84, 0xa9ece033, 0xa4aff6ea, 0xa06efb5d,
|
||||
0xd4316d90, 0xd0f06027, 0xddb376fe, 0xd9727b49,
|
||||
0xc7355b4c, 0xc3f456fb, 0xceb74022, 0xca764d95,
|
||||
0xf2390028, 0xf6f80d9f, 0xfbbb1b46, 0xff7a16f1,
|
||||
0xe13d36f4, 0xe5fc3b43, 0xe8bf2d9a, 0xec7e202d,
|
||||
0x34826077, 0x30436dc0, 0x3d007b19, 0x39c176ae,
|
||||
0x278656ab, 0x23475b1c, 0x2e044dc5, 0x2ac54072,
|
||||
0x128a0dcf, 0x164b0078, 0x1b0816a1, 0x1fc91b16,
|
||||
0x018e3b13, 0x054f36a4, 0x080c207d, 0x0ccd2dca,
|
||||
0x7892bb07, 0x7c53b6b0, 0x7110a069, 0x75d1adde,
|
||||
0x6b968ddb, 0x6f57806c, 0x621496b5, 0x66d59b02,
|
||||
0x5e9ad6bf, 0x5a5bdb08, 0x5718cdd1, 0x53d9c066,
|
||||
0x4d9ee063, 0x495fedd4, 0x441cfb0d, 0x40ddf6ba,
|
||||
0xaca3d697, 0xa862db20, 0xa521cdf9, 0xa1e0c04e,
|
||||
0xbfa7e04b, 0xbb66edfc, 0xb625fb25, 0xb2e4f692,
|
||||
0x8aabbb2f, 0x8e6ab698, 0x8329a041, 0x87e8adf6,
|
||||
0x99af8df3, 0x9d6e8044, 0x902d969d, 0x94ec9b2a,
|
||||
0xe0b30de7, 0xe4720050, 0xe9311689, 0xedf01b3e,
|
||||
0xf3b73b3b, 0xf776368c, 0xfa352055, 0xfef42de2,
|
||||
0xc6bb605f, 0xc27a6de8, 0xcf397b31, 0xcbf87686,
|
||||
0xd5bf5683, 0xd17e5b34, 0xdc3d4ded, 0xd8fc405a,
|
||||
0x6904c0ee, 0x6dc5cd59, 0x6086db80, 0x6447d637,
|
||||
0x7a00f632, 0x7ec1fb85, 0x7382ed5c, 0x7743e0eb,
|
||||
0x4f0cad56, 0x4bcda0e1, 0x468eb638, 0x424fbb8f,
|
||||
0x5c089b8a, 0x58c9963d, 0x558a80e4, 0x514b8d53,
|
||||
0x25141b9e, 0x21d51629, 0x2c9600f0, 0x28570d47,
|
||||
0x36102d42, 0x32d120f5, 0x3f92362c, 0x3b533b9b,
|
||||
0x031c7626, 0x07dd7b91, 0x0a9e6d48, 0x0e5f60ff,
|
||||
0x101840fa, 0x14d94d4d, 0x199a5b94, 0x1d5b5623,
|
||||
0xf125760e, 0xf5e47bb9, 0xf8a76d60, 0xfc6660d7,
|
||||
0xe22140d2, 0xe6e04d65, 0xeba35bbc, 0xef62560b,
|
||||
0xd72d1bb6, 0xd3ec1601, 0xdeaf00d8, 0xda6e0d6f,
|
||||
0xc4292d6a, 0xc0e820dd, 0xcdab3604, 0xc96a3bb3,
|
||||
0xbd35ad7e, 0xb9f4a0c9, 0xb4b7b610, 0xb076bba7,
|
||||
0xae319ba2, 0xaaf09615, 0xa7b380cc, 0xa3728d7b,
|
||||
0x9b3dc0c6, 0x9ffccd71, 0x92bfdba8, 0x967ed61f,
|
||||
0x8839f61a, 0x8cf8fbad, 0x81bbed74, 0x857ae0c3,
|
||||
0x5d86a099, 0x5947ad2e, 0x5404bbf7, 0x50c5b640,
|
||||
0x4e829645, 0x4a439bf2, 0x47008d2b, 0x43c1809c,
|
||||
0x7b8ecd21, 0x7f4fc096, 0x720cd64f, 0x76cddbf8,
|
||||
0x688afbfd, 0x6c4bf64a, 0x6108e093, 0x65c9ed24,
|
||||
0x11967be9, 0x1557765e, 0x18146087, 0x1cd56d30,
|
||||
0x02924d35, 0x06534082, 0x0b10565b, 0x0fd15bec,
|
||||
0x379e1651, 0x335f1be6, 0x3e1c0d3f, 0x3add0088,
|
||||
0x249a208d, 0x205b2d3a, 0x2d183be3, 0x29d93654,
|
||||
0xc5a71679, 0xc1661bce, 0xcc250d17, 0xc8e400a0,
|
||||
0xd6a320a5, 0xd2622d12, 0xdf213bcb, 0xdbe0367c,
|
||||
0xe3af7bc1, 0xe76e7676, 0xea2d60af, 0xeeec6d18,
|
||||
0xf0ab4d1d, 0xf46a40aa, 0xf9295673, 0xfde85bc4,
|
||||
0x89b7cd09, 0x8d76c0be, 0x8035d667, 0x84f4dbd0,
|
||||
0x9ab3fbd5, 0x9e72f662, 0x9331e0bb, 0x97f0ed0c,
|
||||
0xafbfa0b1, 0xab7ead06, 0xa63dbbdf, 0xa2fcb668,
|
||||
0xbcbb966d, 0xb87a9bda, 0xb5398d03, 0xb1f880b4,
|
||||
};
|
||||
#define rr_max 104 /* Number of parity checks, rr = deg[g(x)] */
|
||||
#define parallel 8 //bit count
|
||||
#define mm 13//limit count
|
||||
#define nn 8191//code size
|
||||
#define kk 4120//info length
|
||||
#define tt 8//correct count
|
||||
|
||||
#define tt2 2*tt
|
||||
UINT s[tt2+1]; // Syndrome values
|
||||
|
||||
UINT rr;//redundant length // BCH code parameters
|
||||
|
||||
|
||||
UINT p[mm + 1];
|
||||
UINT alpha_to[nn+1], index_of[nn+1] ; // Galois field
|
||||
UINT gg[rr_max+1] ; // Generator polynomial
|
||||
|
||||
UINT ggx1=0;
|
||||
UINT ggx2=0;
|
||||
UINT ggx3=0;
|
||||
UINT ggx4=0;
|
||||
// get crc32 value
|
||||
UINT CRC_32(unsigned char* pData, UINT ulSize)
|
||||
{
|
||||
UINT i;
|
||||
UINT nAccum = 0;
|
||||
|
||||
for ( i=0; i<ulSize; i++)
|
||||
nAccum = (nAccum<<8)^gTable_Crc32[(nAccum>>24)^(*pData++)];
|
||||
return nAccum;
|
||||
}
|
||||
#define CRC16_CCITT 0x1021 //CRC operator
|
||||
void CRCBuildTable16(unsigned short aPoly , unsigned short *crcTable)
|
||||
{
|
||||
unsigned short i, j;
|
||||
unsigned short nData;
|
||||
unsigned short nAccum;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
nData = (unsigned short)(i << 8);
|
||||
nAccum = 0;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if ((nData ^ nAccum) & 0x8000)
|
||||
nAccum = (nAccum << 1) ^ aPoly;
|
||||
else
|
||||
nAccum <<= 1;
|
||||
nData <<= 1;
|
||||
}
|
||||
crcTable[i] = nAccum;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short CRC_16(unsigned char* aData, UINT aSize)
|
||||
{
|
||||
UINT i;
|
||||
unsigned short nAccum = 0;
|
||||
unsigned short crcTable[256];
|
||||
|
||||
CRCBuildTable16(CRC16_CCITT , crcTable);
|
||||
for (i = 0; i < aSize; i++)
|
||||
nAccum = (nAccum << 8) ^ crcTable[(nAccum >> 8) ^ *aData++];
|
||||
|
||||
return nAccum;
|
||||
}
|
||||
|
||||
void P_RC4(unsigned char* buf, unsigned short len)
|
||||
{
|
||||
unsigned char S[256],K[256],temp;
|
||||
unsigned short i,j,t,x;
|
||||
unsigned char key[16]={124,78,3,4,85,5,9,7,45,44,123,56,23,13,23,17};
|
||||
|
||||
j = 0;
|
||||
for(i=0; i<256; i++){
|
||||
S[i] = (unsigned char)i;
|
||||
j&=0x0f;
|
||||
K[i] = key[j];
|
||||
j++;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for(i=0; i<256; i++){
|
||||
j = (j + S[i] + K[i]) % 256;
|
||||
temp = S[i];
|
||||
S[i] = S[j];
|
||||
S[j] = temp;
|
||||
}
|
||||
|
||||
i = j = 0;
|
||||
for(x=0; x<len; x++){
|
||||
i = (i+1) % 256;
|
||||
j = (j + S[i]) % 256;
|
||||
temp = S[i];
|
||||
S[i] = S[j];
|
||||
S[j] = temp;
|
||||
t = (S[i] + (S[j] % 256)) % 256;
|
||||
buf[x] = buf[x] ^ S[t];
|
||||
}
|
||||
}
|
||||
|
||||
void bch_encode(unsigned char* encode_in, unsigned char* encode_out)
|
||||
{
|
||||
UINT i,j;
|
||||
bool feed_back;
|
||||
UINT bch1=0;
|
||||
UINT bch2=0;
|
||||
UINT bch3=0;
|
||||
UINT bch4=0;
|
||||
|
||||
for (i=0;i<515;i++)
|
||||
{
|
||||
for (j=0;j<8;j++)
|
||||
{
|
||||
feed_back = (bch1&1) ^ ((encode_in[i]>>j) & 1);
|
||||
bch1=((bch1>>1)|((bch2&1)*0x80000000))^(ggx1*feed_back);
|
||||
bch2=((bch2>>1)|((bch3&1)*0x80000000))^(ggx2*feed_back);
|
||||
bch3=((bch3>>1)|((bch4&1)*0x80000000))^(ggx3*feed_back);
|
||||
bch4=(((bch4>>1)^(ggx4*feed_back))) | (feed_back*0x80);
|
||||
}
|
||||
}
|
||||
|
||||
//********Handle FF***********************
|
||||
bch1 = ~(bch1 ^ 0xad6273b1);
|
||||
bch2 = ~(bch2 ^ 0x348393d2);
|
||||
bch3 = ~(bch3 ^ 0xe6ebed3c);
|
||||
bch4 = ~(bch4 ^ 0xc8);
|
||||
//*********************************************
|
||||
|
||||
for (i=0;i<515;i++)
|
||||
encode_out[i] = encode_in[i];
|
||||
encode_out[515] = bch1&0x000000ff;
|
||||
encode_out[516] = (bch1&0x0000ff00)>>8;
|
||||
encode_out[517] = (bch1&0x00ff0000)>>16;
|
||||
encode_out[518] = (bch1&0xff000000)>>24;
|
||||
encode_out[519] = bch2&0x000000ff;
|
||||
encode_out[520] = (bch2&0x0000ff00)>>8;
|
||||
encode_out[521] = (bch2&0x00ff0000)>>16;
|
||||
encode_out[522] = (bch2&0xff000000)>>24;
|
||||
encode_out[523] = bch3&0x000000ff;
|
||||
encode_out[524] = (bch3&0x0000ff00)>>8;
|
||||
encode_out[525] = (bch3&0x00ff0000)>>16;
|
||||
encode_out[526] = (bch3&0xff000000)>>24;
|
||||
encode_out[527] = bch4&0x000000ff;
|
||||
}
|
||||
|
||||
#define poly16_CCITT 0x1021 /* crc-ccitt mask */
|
||||
|
||||
unsigned short CRC_Calculate(unsigned short crc, unsigned char ch)
|
||||
{
|
||||
UINT i;
|
||||
for(i=0x80; i!=0; i>>=1)
|
||||
{
|
||||
if((crc & 0x8000) != 0)
|
||||
{
|
||||
crc <<= 1;
|
||||
crc ^= poly16_CCITT;
|
||||
}
|
||||
else
|
||||
crc <<= 1;
|
||||
if((ch & i)!=0)
|
||||
crc ^= poly16_CCITT;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber)
|
||||
{
|
||||
unsigned short crc = 0xffff;
|
||||
while(CalculateNumber--)
|
||||
{
|
||||
crc = CRC_Calculate(crc, *p);
|
||||
p++;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
void gen_poly()
|
||||
{
|
||||
UINT gen_roots[nn + 1], gen_roots_true[nn + 1] ; // Roots of generator polynomial
|
||||
UINT i, j, Temp ;
|
||||
|
||||
// Initialization of gen_roots
|
||||
for (i = 0; i <= nn; i++)
|
||||
{ gen_roots_true[i] = 0;
|
||||
gen_roots[i] = 0;
|
||||
}
|
||||
|
||||
// Cyclotomic cosets of gen_roots
|
||||
for (i = 1; i <= 2*tt ; i++)
|
||||
{
|
||||
for (j = 0; j < mm; j++)
|
||||
{
|
||||
Temp = ((1<<j)*i)%nn;
|
||||
gen_roots_true[Temp] = 1;
|
||||
}
|
||||
}
|
||||
rr = 0; // Count thenumber of parity check bits
|
||||
for (i = 0; i < nn; i++)
|
||||
{
|
||||
if (gen_roots_true[i] == 1)
|
||||
{
|
||||
rr++;
|
||||
gen_roots[rr] = i;
|
||||
}
|
||||
}
|
||||
// Compute generator polynomial based on its roots
|
||||
gg[0] = 2 ; // g(x) = (X + alpha) initially
|
||||
gg[1] = 1 ;
|
||||
for (i = 2; i <= rr; i++)
|
||||
{
|
||||
gg[i] = 1 ;
|
||||
for (j = i - 1; j > 0; j--)
|
||||
if (gg[j] != 0)
|
||||
gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
|
||||
else
|
||||
gg[j] = gg[j-1] ;
|
||||
gg[0] = alpha_to[(index_of[gg[0]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
|
||||
}
|
||||
|
||||
ggx1 = gg[103] | (gg[102]<<1) | (gg[101]<<2) | (gg[100]<<3) | (gg[99]<<4) |(gg[98]<<5)| (gg[97]<<6)|(gg[96]<<7)
|
||||
| (gg[95]<<8) | (gg[94]<<9) | (gg[93]<<10) | (gg[92]<<11) |(gg[91]<<12)| (gg[90]<<13)|(gg[89]<<14) |(gg[88]<<15)
|
||||
| (gg[87]<<16) | (gg[86]<<17) | (gg[85]<<18) | (gg[84]<<19) | (gg[83]<<20) |(gg[82]<<21)| (gg[81]<<22)|(gg[80]<<23)
|
||||
| (gg[79]<<24) | (gg[78]<<25) | (gg[77]<<26) | (gg[76]<<27) |(gg[75]<<28)| (gg[74]<<29)|(gg[73]<<30) |(gg[72]<<31);
|
||||
ggx2 = gg[71] | (gg[70]<<1) | (gg[69]<<2) | (gg[68]<<3) | (gg[67]<<4) |(gg[66]<<5)| (gg[65]<<6)|(gg[64]<<7)
|
||||
| (gg[63]<<8) | (gg[62]<<9) | (gg[61]<<10) | (gg[60]<<11) |(gg[59]<<12)| (gg[58]<<13)|(gg[57]<<14) |(gg[56]<<15)
|
||||
| (gg[55]<<16) | (gg[54]<<17) | (gg[53]<<18) | (gg[52]<<19) | (gg[51]<<20) |(gg[50]<<21)| (gg[49]<<22)|(gg[48]<<23)
|
||||
| (gg[47]<<24) | (gg[46]<<25) | (gg[45]<<26) | (gg[44]<<27) |(gg[43]<<28)| (gg[42]<<29)|(gg[41]<<30) |(gg[40]<<31);
|
||||
ggx3 = gg[39] | (gg[38]<<1) | (gg[37]<<2) | (gg[36]<<3) | (gg[35]<<4) |(gg[34]<<5)| (gg[33]<<6)|(gg[32]<<7)
|
||||
| (gg[31]<<8) | (gg[30]<<9) | (gg[29]<<10) | (gg[28]<<11) |(gg[27]<<12)| (gg[26]<<13)|(gg[25]<<14) |(gg[24]<<15)
|
||||
| (gg[23]<<16) | (gg[22]<<17) | (gg[21]<<18) | (gg[20]<<19) | (gg[19]<<20) |(gg[18]<<21)| (gg[17]<<22)|(gg[16]<<23)
|
||||
| (gg[15]<<24) | (gg[14]<<25) | (gg[13]<<26) | (gg[12]<<27) |(gg[11]<<28)| (gg[10]<<29)|(gg[9]<<30) |(gg[8]<<31);
|
||||
ggx4 = gg[7] | (gg[6]<<1) | (gg[5]<<2) | (gg[4]<<3) | (gg[3]<<4) |(gg[2]<<5)| (gg[1]<<6);
|
||||
|
||||
}
|
||||
|
||||
void generate_gf()
|
||||
{
|
||||
UINT i;
|
||||
UINT mask ; // Register states
|
||||
|
||||
// Primitive polynomials
|
||||
for (i = 1; i < mm; i++)
|
||||
p[i] = 0;
|
||||
p[0] = p[mm] = 1;
|
||||
if (mm == 2) p[1] = 1;
|
||||
else if (mm == 3) p[1] = 1;
|
||||
else if (mm == 4) p[1] = 1;
|
||||
else if (mm == 5) p[2] = 1;
|
||||
else if (mm == 6) p[1] = 1;
|
||||
else if (mm == 7) p[1] = 1;
|
||||
else if (mm == 8) p[4] = p[5] = p[6] = 1;
|
||||
else if (mm == 9) p[4] = 1;
|
||||
else if (mm == 10) p[3] = 1;
|
||||
else if (mm == 11) p[2] = 1;
|
||||
else if (mm == 12) p[3] = p[4] = p[7] = 1;
|
||||
else if (mm == 13) p[1] = p[2] = p[3] = p[5] = p[7] = p[8] = p[10] = 1; // 25AF
|
||||
else if (mm == 14) p[2] = p[4] = p[6] = p[7] = p[8] = 1; // 41D5
|
||||
else if (mm == 15) p[1] = 1;
|
||||
else if (mm == 16) p[2] = p[3] = p[5] = 1;
|
||||
else if (mm == 17) p[3] = 1;
|
||||
else if (mm == 18) p[7] = 1;
|
||||
else if (mm == 19) p[1] = p[5] = p[6] = 1;
|
||||
else if (mm == 20) p[3] = 1;
|
||||
// Galois field implementation with shift registers
|
||||
// Ref: L&C, Chapter 6.7, pp. 217
|
||||
mask = 1 ;
|
||||
alpha_to[mm] = 0 ;
|
||||
for (i = 0; i < mm; i++)
|
||||
{
|
||||
alpha_to[i] = mask ;
|
||||
index_of[alpha_to[i]] = i ;
|
||||
if (p[i] != 0)
|
||||
alpha_to[mm] ^= mask ;
|
||||
mask <<= 1 ;
|
||||
}
|
||||
|
||||
index_of[alpha_to[mm]] = mm ;
|
||||
mask >>= 1 ;
|
||||
for (i = mm + 1; i < nn; i++)
|
||||
{
|
||||
if (alpha_to[i-1] >= mask)
|
||||
alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1] ^ mask) << 1) ;
|
||||
else
|
||||
alpha_to[i] = alpha_to[i-1] << 1 ;
|
||||
|
||||
index_of[alpha_to[i]] = i ;
|
||||
}
|
||||
index_of[0] = -1 ;
|
||||
}
|
339
license.txt
Normal file
339
license.txt
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
940
main.cpp
Normal file
940
main.cpp
Normal file
@ -0,0 +1,940 @@
|
||||
/*
|
||||
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Seth Liu 2017.03.01
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include "DefineHeader.h"
|
||||
#include "RKLog.h"
|
||||
#include "RKScan.h"
|
||||
#include "RKComm.h"
|
||||
#include "RKDevice.h"
|
||||
#include "RKImage.h"
|
||||
extern const char *szManufName[];
|
||||
CRKLog *g_pLogObject=NULL;
|
||||
CONFIG_ITEM_VECTOR g_ConfigItemVec;
|
||||
#define DEFAULT_RW_LBA 128
|
||||
#define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
|
||||
#define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
|
||||
#define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
|
||||
#define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
|
||||
#define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B);
|
||||
#define NORMAL_COLOR_ATTR printf("%c[37;40m", 0x1B);
|
||||
void usage()
|
||||
{
|
||||
printf("\r\n---------------------Tool Usage ---------------------\r\n");
|
||||
printf("Help: -H\r\n");
|
||||
printf("Version: -V\r\n");
|
||||
printf("DownloadBoot: DB <Loader>\r\n");
|
||||
printf("ReadLBA: RL <BeginSec> <SectorLen> <File>\r\n");
|
||||
printf("WriteLBA: WL <BeginSec> <File>\r\n");
|
||||
printf("EraseFlash: EF \r\n");
|
||||
printf("TestDevice: TD\r\n");
|
||||
printf("ResetDevice: RD [subcode]\r\n");
|
||||
printf("ReadFlashID: RID\r\n");
|
||||
printf("ReadFlashInfo: RFI\r\n");
|
||||
printf("ReadChipInfo: RCI\r\n");
|
||||
printf("-------------------------------------------------------\r\n\r\n");
|
||||
}
|
||||
void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
|
||||
{
|
||||
string strInfoText="";
|
||||
char szText[256];
|
||||
switch (promptID) {
|
||||
case TESTDEVICE_PROGRESS:
|
||||
sprintf(szText, "Test Device Total(%lld),Current(%lld)", totalValue, currentValue);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case LOWERFORMAT_PROGRESS:
|
||||
sprintf(szText, "Lowerformat Device Total(%lld),Current(%lld)", totalValue, currentValue);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case DOWNLOADIMAGE_PROGRESS:
|
||||
sprintf(szText, "Download Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case CHECKIMAGE_PROGRESS:
|
||||
sprintf(szText, "Check Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case TAGBADBLOCK_PROGRESS:
|
||||
sprintf(szText, "Tag Bad Block Total(%lld),Current(%lld)", totalValue, currentValue);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case TESTBLOCK_PROGRESS:
|
||||
sprintf(szText, "Test Block Total(%lld),Current(%lld)", totalValue, currentValue);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case ERASEFLASH_PROGRESS:
|
||||
sprintf(szText, "Erase Flash Total(%lld),Current(%lld)", totalValue, currentValue);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case ERASESYSTEM_PROGRESS:
|
||||
sprintf(szText, "Erase System partition Total(%lld),Current(%lld)", totalValue, currentValue);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
case ERASEUSERDATA_PROGRESS:
|
||||
sprintf(szText, "<LocationID=%x> Erase Userdata partition Total(%lld),Current(%lld)",deviceLayer,totalValue, currentValue);
|
||||
strInfoText = szText;
|
||||
break;
|
||||
}
|
||||
if (strInfoText.size() > 0){
|
||||
CURSOR_MOVEUP_LINE(1);
|
||||
CURSOR_DEL_LINE;
|
||||
printf("%s\r\n", strInfoText.c_str());
|
||||
}
|
||||
if (emCall == CALL_LAST)
|
||||
deviceLayer = 0;
|
||||
}
|
||||
|
||||
char *strupr(char *szSrc)
|
||||
{
|
||||
char *p = szSrc;
|
||||
while(*p){
|
||||
if ((*p >= 'a') && (*p <= 'z'))
|
||||
*p = *p - 'a' + 'A';
|
||||
p++;
|
||||
}
|
||||
return szSrc;
|
||||
}
|
||||
void PrintData(PBYTE pData, int nSize)
|
||||
{
|
||||
char szPrint[17] = "\0";
|
||||
int i;
|
||||
for( i = 0; i < nSize; i++){
|
||||
if(i % 16 == 0){
|
||||
if(i / 16 > 0)
|
||||
printf(" %s\r\n", szPrint);
|
||||
printf("%08d ", i / 16);
|
||||
}
|
||||
printf("%02X ", pData[i]);
|
||||
szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
|
||||
}
|
||||
if(i / 16 > 0)
|
||||
printf(" %s\r\n", szPrint);
|
||||
}
|
||||
|
||||
bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
|
||||
{
|
||||
if (!pszSrc)
|
||||
return false;
|
||||
int nSrcLen = strlen(pszSrc);
|
||||
int nDestLen = nSrcLen * 2;
|
||||
|
||||
pszDest = NULL;
|
||||
pszDest = new wchar_t[nDestLen];
|
||||
if (!pszDest)
|
||||
return false;
|
||||
nDestLen = nDestLen * sizeof(wchar_t);
|
||||
memset(pszDest, 0, nDestLen);
|
||||
int iRet;
|
||||
iconv_t cd;
|
||||
cd = iconv_open("UTF-32", "UTF-8");
|
||||
if((iconv_t)-1 == cd) {
|
||||
delete []pszDest;
|
||||
pszDest = NULL;
|
||||
return false;
|
||||
}
|
||||
char *pIn, *pOut;
|
||||
pIn = (char *)pszSrc;
|
||||
pOut = (char *)pszDest;
|
||||
|
||||
iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
|
||||
|
||||
if(iRet == -1) {
|
||||
delete []pszDest;
|
||||
pszDest = NULL;
|
||||
iconv_close(cd);
|
||||
return false;
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
|
||||
{
|
||||
if (!pszSrc)
|
||||
return false;
|
||||
int nSrcLen = wcslen(pszSrc);
|
||||
int nDestLen = nSrcLen * 2;
|
||||
nSrcLen = nSrcLen * sizeof(wchar_t);
|
||||
pszDest = NULL;
|
||||
pszDest = new char[nDestLen];
|
||||
if (!pszDest)
|
||||
return false;
|
||||
memset(pszDest, 0, nDestLen);
|
||||
int iRet;
|
||||
iconv_t cd;
|
||||
cd = iconv_open("UTF-8", "UTF-32");
|
||||
|
||||
if((iconv_t)-1 == cd) {
|
||||
delete []pszDest;
|
||||
pszDest = NULL;
|
||||
return false;
|
||||
}
|
||||
char *pIn, *pOut;
|
||||
pIn = (char *)pszSrc;
|
||||
pOut = (char *)pszDest;
|
||||
iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
|
||||
|
||||
if(iRet == -1) {
|
||||
delete []pszDest;
|
||||
pszDest = NULL;
|
||||
iconv_close(cd);
|
||||
return false;
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
|
||||
return true;
|
||||
}
|
||||
int find_config_item(const char *pszName)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; i < g_ConfigItemVec.size(); i++){
|
||||
if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
|
||||
{
|
||||
|
||||
stringstream configStream(pConfig);
|
||||
string strLine, strItemName, strItemValue;
|
||||
string::size_type line_size,pos;
|
||||
STRUCT_CONFIG_ITEM item;
|
||||
vecItem.clear();
|
||||
while (!configStream.eof()){
|
||||
getline(configStream, strLine);
|
||||
line_size = strLine.size();
|
||||
if (line_size == 0)
|
||||
continue;
|
||||
if (strLine[line_size-1] == '\r'){
|
||||
strLine = strLine.substr(0, line_size-1);
|
||||
}
|
||||
pos = strLine.find("=");
|
||||
if (pos == string::npos){
|
||||
continue;
|
||||
}
|
||||
strItemName = strLine.substr(0, pos);
|
||||
strItemValue = strLine.substr(pos + 1);
|
||||
strItemName.erase(0, strItemName.find_first_not_of(" "));
|
||||
strItemName.erase(strItemName.find_last_not_of(" ") + 1);
|
||||
strItemValue.erase(0, strItemValue.find_first_not_of(" "));
|
||||
strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
|
||||
if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
|
||||
strcpy(item.szItemName, strItemName.c_str());
|
||||
strcpy(item.szItemValue, strItemValue.c_str());
|
||||
vecItem.push_back(item);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
file = fopen(pConfigFile, "rb");
|
||||
if( !file ){
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("parse_config_file failed,err=%d,can't open file: %s\r\n", errno, pConfigFile);
|
||||
return false;
|
||||
}
|
||||
int iFileSize;
|
||||
fseek(file, 0, SEEK_END);
|
||||
iFileSize = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
char *pConfigBuf = NULL;
|
||||
pConfigBuf = new char[iFileSize + 1];
|
||||
if (!pConfigBuf){
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
memset(pConfigBuf, 0, iFileSize + 1);
|
||||
int iRead;
|
||||
iRead = fread(pConfigBuf, 1, iFileSize, file);
|
||||
if (iRead != iFileSize){
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("parse_config_file failed,err=%d, read=%d, total=%d\r\n", errno, iRead, iFileSize);
|
||||
fclose(file);
|
||||
delete []pConfigBuf;
|
||||
return false;
|
||||
}
|
||||
fclose(file);
|
||||
bool bRet;
|
||||
bRet = parse_config(pConfigBuf, vecItem);
|
||||
delete []pConfigBuf;
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
|
||||
{
|
||||
if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("The Device did not support this operation!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
|
||||
{
|
||||
if (!check_device_type(dev, RKUSB_MASKROM))
|
||||
return false;
|
||||
CRKImage *pImage = NULL;
|
||||
CRKBoot *pBoot = NULL;
|
||||
bool bRet, bSuccess = false;
|
||||
int iRet;
|
||||
|
||||
pImage = new CRKImage(szLoader, bRet);
|
||||
if (!bRet){
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("Open loader failed,exit download boot!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
} else {
|
||||
pBoot = (CRKBoot *)pImage->m_bootObject;
|
||||
CRKComm *pComm = NULL;
|
||||
CRKDevice *pDevice = NULL;
|
||||
|
||||
dev.emDeviceType = pBoot->SupportDevice;
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (!bRet) {
|
||||
if (pImage)
|
||||
delete pImage;
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("Creating Comm Object failed!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
pDevice = new CRKDevice(dev);
|
||||
if (!pDevice) {
|
||||
if (pImage)
|
||||
delete pImage;
|
||||
if (pComm)
|
||||
delete pComm;
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("Creating device object failed!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
pDevice->SetObject(pImage, pComm, g_pLogObject);
|
||||
printf("Download boot...\r\n");
|
||||
iRet = pDevice->DownloadBoot();
|
||||
|
||||
CURSOR_MOVEUP_LINE(1);
|
||||
CURSOR_DEL_LINE;
|
||||
if (iRet == 0) {
|
||||
pComm->Reset_Usb_Device();
|
||||
CRKScan *pScan = NULL;
|
||||
pScan = new CRKScan();
|
||||
if (pScan) {
|
||||
pScan->SetVidPid();
|
||||
pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
|
||||
delete pScan;
|
||||
}
|
||||
bSuccess = true;
|
||||
printf("Download boot ok.\r\n");
|
||||
}
|
||||
else
|
||||
printf("Download boot failed!\r\n");
|
||||
|
||||
if (pImage)
|
||||
delete pImage;
|
||||
if(pDevice)
|
||||
delete pDevice;
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
|
||||
{
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return false;
|
||||
CRKImage *pImage = NULL;
|
||||
bool bRet, bSuccess = false;
|
||||
int iRet;
|
||||
CRKScan *pScan = NULL;
|
||||
pScan = new CRKScan();
|
||||
pScan->SetVidPid();
|
||||
|
||||
CRKComm *pComm = NULL;
|
||||
CRKDevice *pDevice = NULL;
|
||||
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (!bRet) {
|
||||
if (pScan)
|
||||
delete pScan;
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("Creating Comm Object failed!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
pDevice = new CRKDevice(dev);
|
||||
if (!pDevice) {
|
||||
if (pComm)
|
||||
delete pComm;
|
||||
if (pScan)
|
||||
delete pScan;
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("Creating device object failed!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
pDevice->SetObject(pImage, pComm, g_pLogObject);
|
||||
pDevice->CallBackPointer = ProgressInfoProc;
|
||||
|
||||
printf("Start to erase flash...\r\n");
|
||||
iRet = pDevice->EraseAllBlocks();
|
||||
if (pDevice)
|
||||
delete pDevice;
|
||||
|
||||
if (iRet == 0) {
|
||||
if (pScan) {
|
||||
pScan->SetVidPid();
|
||||
pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
|
||||
delete pScan;
|
||||
}
|
||||
CURSOR_MOVEUP_LINE(1);
|
||||
CURSOR_DEL_LINE;
|
||||
bSuccess = true;
|
||||
printf("Erase flash ok.\r\n");
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool test_device(STRUCT_RKDEVICE_DESC &dev)
|
||||
{
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return false;
|
||||
CRKUsbComm *pComm = NULL;
|
||||
bool bRet, bSuccess = false;
|
||||
int iRet;
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (bRet) {
|
||||
iRet = pComm->RKU_TestDeviceReady();
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet);
|
||||
printf("Test Device Fail!\r\n");
|
||||
} else {
|
||||
bSuccess = true;
|
||||
printf("Test Device OK.\r\n");
|
||||
}
|
||||
} else {
|
||||
printf("Test Device quit,Creating comm object failed!\r\n");
|
||||
}
|
||||
if (pComm) {
|
||||
delete pComm;
|
||||
pComm = NULL;
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
|
||||
{
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return false;
|
||||
CRKUsbComm *pComm = NULL;
|
||||
bool bRet, bSuccess = false;
|
||||
int iRet;
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (bRet) {
|
||||
iRet = pComm->RKU_ResetDevice(subCode);
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet);
|
||||
printf("Reset Device Fail!\r\n");
|
||||
} else {
|
||||
bSuccess = true;
|
||||
printf("Reset Device OK.\r\n");
|
||||
}
|
||||
} else {
|
||||
printf("Reset Device quit,Creating comm object failed!\r\n");
|
||||
}
|
||||
if (pComm) {
|
||||
delete pComm;
|
||||
pComm = NULL;
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
|
||||
{
|
||||
CRKUsbComm *pComm = NULL;
|
||||
bool bRet, bSuccess = false;
|
||||
int iRet;
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return bSuccess;
|
||||
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (bRet) {
|
||||
BYTE flashID[5];
|
||||
iRet = pComm->RKU_ReadFlashID(flashID);
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet);
|
||||
printf("Read flash ID Fail!\r\n");
|
||||
} else {
|
||||
printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
|
||||
bSuccess = true;
|
||||
}
|
||||
} else {
|
||||
printf("Read flash ID quit,Creating comm object failed!\r\n");
|
||||
}
|
||||
if (pComm) {
|
||||
delete pComm;
|
||||
pComm = NULL;
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
|
||||
{
|
||||
CRKUsbComm *pComm = NULL;
|
||||
bool bRet, bSuccess = false;
|
||||
int iRet;
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return bSuccess;
|
||||
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (bRet) {
|
||||
STRUCT_FLASHINFO_CMD info;
|
||||
UINT uiRead;
|
||||
iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet);
|
||||
printf("Read flash Info Fail!\r\n");
|
||||
} else {
|
||||
printf("Flash Info:\r\n");
|
||||
if (info.bManufCode <= 7) {
|
||||
printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
|
||||
}
|
||||
else
|
||||
printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode);
|
||||
|
||||
printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024);
|
||||
printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2);
|
||||
printf("\tPage Size: %dKB\r\n", info.bPageSize / 2);
|
||||
printf("\tECC Bits: %d\r\n", info.bECCBits);
|
||||
printf("\tAccess Time: %d\r\n", info.bAccessTime);
|
||||
printf("\tFlash CS: ");
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if( info.bFlashCS & (1 << i) )
|
||||
printf("Flash<%d> ", i);
|
||||
}
|
||||
printf("\r\n");
|
||||
bSuccess = true;
|
||||
}
|
||||
}else {
|
||||
printf("Read flash Info quit,Creating comm object failed!\r\n");
|
||||
}
|
||||
if (pComm) {
|
||||
delete pComm;
|
||||
pComm = NULL;
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
|
||||
{
|
||||
CRKUsbComm *pComm = NULL;
|
||||
bool bRet, bSuccess = false;
|
||||
int iRet;
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return bSuccess;
|
||||
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (bRet) {
|
||||
BYTE chipInfo[16];
|
||||
iRet = pComm->RKU_ReadChipInfo(chipInfo);
|
||||
if (iRet != ERR_SUCCESS) {
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet);
|
||||
printf("Read Chip Info Fail!\r\n");
|
||||
} else {
|
||||
string strChipInfo;
|
||||
g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
|
||||
printf("Chip Info:%s\r\n", strChipInfo.c_str());
|
||||
bSuccess = true;
|
||||
}
|
||||
} else {
|
||||
printf("Read Chip Info quit,Creating comm object failed!\r\n");
|
||||
}
|
||||
if (pComm) {
|
||||
delete pComm;
|
||||
pComm = NULL;
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
|
||||
{
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return false;
|
||||
CRKUsbComm *pComm = NULL;
|
||||
FILE *file = NULL;
|
||||
bool bRet, bFirst = true, bSuccess = false;
|
||||
int iRet;
|
||||
UINT iTotalRead = 0,iRead = 0;
|
||||
int nSectorSize = 512;
|
||||
BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (bRet) {
|
||||
if(szFile) {
|
||||
file = fopen(szFile, "wb+");
|
||||
if( !file ) {
|
||||
printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
|
||||
goto Exit_ReadLBA;
|
||||
}
|
||||
}
|
||||
|
||||
while(uiLen > 0) {
|
||||
memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
|
||||
iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
|
||||
iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
|
||||
if(ERR_SUCCESS == iRet) {
|
||||
uiLen -= iRead;
|
||||
iTotalRead += iRead;
|
||||
|
||||
if(szFile) {
|
||||
fwrite(pBuf, 1, iRead * nSectorSize, file);
|
||||
if (bFirst){
|
||||
if (iTotalRead >= 1024)
|
||||
printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
|
||||
else
|
||||
printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
|
||||
bFirst = false;
|
||||
} else {
|
||||
CURSOR_MOVEUP_LINE(1);
|
||||
CURSOR_DEL_LINE;
|
||||
if (iTotalRead >= 1024)
|
||||
printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
|
||||
else
|
||||
printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
|
||||
}
|
||||
}
|
||||
else
|
||||
PrintData(pBuf, nSectorSize * iRead);
|
||||
} else {
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet);
|
||||
|
||||
printf("Read LBA failed!\r\n");
|
||||
goto Exit_ReadLBA;
|
||||
}
|
||||
}
|
||||
bSuccess = true;
|
||||
} else {
|
||||
printf("Read LBA quit,Creating comm object failed!\r\n");
|
||||
}
|
||||
Exit_ReadLBA:
|
||||
if (pComm) {
|
||||
delete pComm;
|
||||
pComm = NULL;
|
||||
}
|
||||
if (file)
|
||||
fclose(file);
|
||||
return bSuccess;
|
||||
}
|
||||
bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
|
||||
{
|
||||
if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
|
||||
return false;
|
||||
CRKUsbComm *pComm = NULL;
|
||||
FILE *file = NULL;
|
||||
bool bRet, bFirst = true, bSuccess = false;
|
||||
int iRet;
|
||||
long long iTotalWrite = 0, iFileSize = 0;
|
||||
UINT iWrite = 0, iRead = 0;
|
||||
UINT uiLen;
|
||||
int nSectorSize = 512;
|
||||
BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
|
||||
|
||||
pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
|
||||
if (bRet) {
|
||||
file = fopen(szFile, "rb");
|
||||
if( !file ) {
|
||||
printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
|
||||
goto Exit_WriteLBA;
|
||||
}
|
||||
|
||||
iRet = fseeko(file, 0, SEEK_END);
|
||||
iFileSize = ftello(file);
|
||||
fseeko(file, 0, SEEK_SET);
|
||||
while(iTotalWrite < iFileSize) {
|
||||
memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
|
||||
iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
|
||||
if ((int)iRead != nSectorSize * DEFAULT_RW_LBA) {
|
||||
printf("Write LBA failed,err=%d,read=%d,total=%d!\r\n", errno, iRead, nSectorSize * DEFAULT_RW_LBA);
|
||||
goto Exit_WriteLBA;
|
||||
}
|
||||
uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
|
||||
iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
|
||||
if(ERR_SUCCESS == iRet) {
|
||||
uiBegin += uiLen;
|
||||
iTotalWrite += iWrite;
|
||||
if (bFirst) {
|
||||
if (iTotalWrite >= 1024)
|
||||
printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
|
||||
else
|
||||
printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
|
||||
bFirst = false;
|
||||
} else {
|
||||
CURSOR_MOVEUP_LINE(1);
|
||||
CURSOR_DEL_LINE;
|
||||
printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
|
||||
}
|
||||
} else {
|
||||
if (g_pLogObject)
|
||||
g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
|
||||
|
||||
printf("Write LBA failed!\r\n");
|
||||
goto Exit_WriteLBA;
|
||||
}
|
||||
}
|
||||
bSuccess = true;
|
||||
} else {
|
||||
printf("Write LBA quit,Creating comm object failed!\r\n");
|
||||
}
|
||||
Exit_WriteLBA:
|
||||
if (pComm) {
|
||||
delete pComm;
|
||||
pComm = NULL;
|
||||
}
|
||||
if (file)
|
||||
fclose(file);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void split_item(STRING_VECTOR &vecItems, char *pszItems)
|
||||
{
|
||||
string strItem;
|
||||
char szItem[100];
|
||||
char *pos = NULL, *pStart;
|
||||
pStart = pszItems;
|
||||
pos = strchr(pStart, ',');
|
||||
while(pos != NULL) {
|
||||
memset(szItem, 0, 100);
|
||||
strncpy(szItem, pStart, pos - pStart);
|
||||
strItem = szItem;
|
||||
vecItems.push_back(strItem);
|
||||
pStart = pos + 1;
|
||||
if (*pStart == 0)
|
||||
break;
|
||||
pos = strchr(pStart, ',');
|
||||
}
|
||||
if (strlen(pStart) > 0) {
|
||||
memset(szItem, 0, 100);
|
||||
strncpy(szItem, pStart, strlen(pStart));
|
||||
strItem = szItem;
|
||||
vecItems.push_back(strItem);
|
||||
}
|
||||
}
|
||||
bool handle_command(int argc, char* argv[], CRKScan *pScan)
|
||||
{
|
||||
string strCmd;
|
||||
strCmd = argv[1];
|
||||
ssize_t cnt;
|
||||
bool bRet,bSuccess = false;
|
||||
int ret;
|
||||
STRUCT_RKDEVICE_DESC dev;
|
||||
|
||||
transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
|
||||
if(strcmp(strCmd.c_str(), "-H") == 0) {
|
||||
usage();
|
||||
return true;
|
||||
} else if(strcmp(strCmd.c_str(), "-V") == 0) {
|
||||
printf("rkDevelopTool ver 1.0\r\n");
|
||||
return true;
|
||||
}
|
||||
cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
|
||||
if (cnt < 1) {
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("No found any rockusb device,please plug device in!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
} else if (cnt > 1) {
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("Found many rockusb devices,please plug device out!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bRet = pScan->GetDevice(dev, 0);
|
||||
if (!bRet) {
|
||||
ERROR_COLOR_ATTR;
|
||||
printf("Getting information of rockusb device failed!");
|
||||
NORMAL_COLOR_ATTR;
|
||||
printf("\r\n");
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
if(strcmp(strCmd.c_str(), "RD") == 0) {
|
||||
if ((argc != 2) && (argc != 3))
|
||||
printf("Parameter of [RD] command is invalid,please check help!\r\n");
|
||||
else {
|
||||
if (argc == 2)
|
||||
bSuccess = reset_device(dev);
|
||||
else {
|
||||
UINT uiSubCode;
|
||||
char *pszEnd;
|
||||
uiSubCode = strtoul(argv[2], &pszEnd, 0);
|
||||
if (*pszEnd)
|
||||
printf("Subcode is invalid,please check!\r\n");
|
||||
else {
|
||||
if (uiSubCode <= 5)
|
||||
bSuccess = reset_device(dev, uiSubCode);
|
||||
else
|
||||
printf("Subcode is invalid,please check!\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(strcmp(strCmd.c_str(), "TD") == 0) {
|
||||
bSuccess = test_device(dev);
|
||||
} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
|
||||
bSuccess = read_flash_id(dev);
|
||||
} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
|
||||
bSuccess = read_flash_info(dev);
|
||||
} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
|
||||
bSuccess = read_chip_info(dev);
|
||||
} else if(strcmp(strCmd.c_str(), "DB") == 0) {
|
||||
if (argc > 2) {
|
||||
string strLoader;
|
||||
strLoader = argv[2];
|
||||
bSuccess = download_boot(dev, (char *)strLoader.c_str());
|
||||
} else if (argc == 2) {
|
||||
ret = find_config_item("loader");
|
||||
if (ret == -1)
|
||||
printf("No found loader item from config!\r\n");
|
||||
else
|
||||
bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
|
||||
} else
|
||||
printf("Parameter of [DB] command is invalid,please check help!\r\n");
|
||||
} else if(strcmp(strCmd.c_str(), "EF") == 0) {
|
||||
if (argc == 2) {
|
||||
bSuccess = erase_flash(dev);
|
||||
} else
|
||||
printf("Parameter of [EF] command is invalid,please check help!\r\n");
|
||||
} else if(strcmp(strCmd.c_str(), "WL") == 0) {
|
||||
if (argc == 4) {
|
||||
UINT uiBegin;
|
||||
char *pszEnd;
|
||||
uiBegin = strtoul(argv[2], &pszEnd, 0);
|
||||
if (*pszEnd)
|
||||
printf("Begin is invalid,please check!\r\n");
|
||||
else
|
||||
bSuccess = write_lba(dev, uiBegin, argv[3]);
|
||||
} else
|
||||
printf("Parameter of [WL] command is invalid,please check help!\r\n");
|
||||
} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
|
||||
char *pszEnd;
|
||||
UINT uiBegin, uiLen;
|
||||
if (argc != 5)
|
||||
printf("Parameter of [RL] command is invalid,please check help!\r\n");
|
||||
else {
|
||||
uiBegin = strtoul(argv[2], &pszEnd, 0);
|
||||
if (*pszEnd)
|
||||
printf("Begin is invalid,please check!\r\n");
|
||||
else {
|
||||
uiLen = strtoul(argv[3], &pszEnd, 0);
|
||||
if (*pszEnd)
|
||||
printf("Len is invalid,please check!\r\n");
|
||||
else {
|
||||
bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("command is invalid,please press upgrade_tool -h to check usage!\r\n");
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
CRKScan *pScan = NULL;
|
||||
int ret;
|
||||
char szProgramProcPath[100];
|
||||
char szProgramDir[256];
|
||||
string strLogDir,strConfigFile;
|
||||
struct stat statBuf;
|
||||
|
||||
g_ConfigItemVec.clear();
|
||||
sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
|
||||
if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
|
||||
strcpy(szProgramDir, ".");
|
||||
else {
|
||||
char *pSlash;
|
||||
pSlash = strrchr(szProgramDir, '/');
|
||||
if (pSlash)
|
||||
*pSlash = '\0';
|
||||
}
|
||||
strLogDir = szProgramDir;
|
||||
strLogDir += "/log/";
|
||||
strConfigFile = szProgramDir;
|
||||
strConfigFile += "/config.ini";
|
||||
if (opendir(strLogDir.c_str()) == NULL)
|
||||
mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
|
||||
g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
|
||||
|
||||
if(stat(strConfigFile.c_str(), &statBuf) < 0) {
|
||||
if (g_pLogObject) {
|
||||
g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
|
||||
}
|
||||
} else if (S_ISREG(statBuf.st_mode)) {
|
||||
parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
|
||||
}
|
||||
|
||||
ret = libusb_init(NULL);
|
||||
if (ret < 0) {
|
||||
if (g_pLogObject) {
|
||||
g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
|
||||
delete g_pLogObject;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
pScan = new CRKScan();
|
||||
if (!pScan) {
|
||||
if (g_pLogObject) {
|
||||
g_pLogObject->Record("Error:failed to Create object for searching device");
|
||||
delete g_pLogObject;
|
||||
}
|
||||
libusb_exit(NULL);
|
||||
return -2;
|
||||
}
|
||||
pScan->SetVidPid();
|
||||
|
||||
if (argc == 1)
|
||||
usage();
|
||||
else if (!handle_command(argc, argv, pScan))
|
||||
return -0xFF;
|
||||
if (pScan)
|
||||
delete pScan;
|
||||
if (g_pLogObject)
|
||||
delete g_pLogObject;
|
||||
libusb_exit(NULL);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user