269 lines
7.1 KiB
C++
269 lines
7.1 KiB
C++
|
|
#include "rm_settings_cfg_emt_kr.h"
|
|
#include <QFile>
|
|
#include <QDebug>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <Windows.h>
|
|
#if (USE_DEVICE_SETTINGS && RM_MODEL_EMT_KR)
|
|
|
|
unsigned char CFG::data[SETTINGS_CFG_SIZE] = {0,};
|
|
unsigned char CFG::stored[SETTINGS_CFG_SIZE] = {0,};
|
|
EMTINFO CFG::info = {0,};
|
|
QJsonArray CFG::items;
|
|
QString CFG::cfgPath = "";
|
|
|
|
QStringList CFG::model_names = QStringList() << "NM5000" << "NP5000" << "MIRROR5" << "PRO5" << "360X";
|
|
uint32_t CFG::model_codes[5] = { NM5000, NP5000, MIRROR5, PRO5, A360X};
|
|
|
|
bool CFG::_loadJSon()
|
|
{
|
|
// CLEAR
|
|
while(CFG::items.count()) {
|
|
CFG::items.pop_back();
|
|
}
|
|
|
|
//QString jsonPath = ":/raw/cfg_5102.json";
|
|
QString jsonPath = "";
|
|
switch(info.model) {
|
|
case NM5000:
|
|
jsonPath = ":/raw/cfg_nm5000.json";
|
|
break;
|
|
case NP5000:
|
|
jsonPath = ":/raw/cfg_np5000.json";
|
|
break;
|
|
case MIRROR5:
|
|
jsonPath = ":/raw/cfg_mirror5.json";
|
|
break;
|
|
case PRO5:
|
|
jsonPath = ":/raw/cfg_pro5.json";
|
|
break;
|
|
case A360X:
|
|
jsonPath = ":/raw/cfg_360x.json";
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
QFile file(jsonPath);
|
|
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
QByteArray data = file.readAll();
|
|
file.close();
|
|
CFG::items = QJsonDocument::fromJson(data).array();
|
|
}
|
|
return true;
|
|
}
|
|
void CFG::_getItems(QJsonArray& in, QJsonArray& ret)
|
|
{
|
|
for(int i=0;i<in.size();i++) {
|
|
QJsonObject obj = in.at(i).toObject();
|
|
if(obj.contains("group") && obj.contains("items")) {
|
|
_getItems(obj.value("items").toArray(),ret);
|
|
}
|
|
else {
|
|
ret.append(obj);
|
|
}
|
|
}
|
|
}
|
|
void CFG::serializeItems(QJsonArray& citems) {
|
|
_getItems(CFG::items,citems);
|
|
return;
|
|
}
|
|
void CFG::setDefault()
|
|
{
|
|
QJsonArray citems;
|
|
serializeItems(citems);
|
|
for(int i=0;i<citems.size();i++) {
|
|
QJsonObject obj = citems.at(i).toObject();
|
|
|
|
//qInfo() << obj << __FUNCTION__;
|
|
|
|
if(obj.contains("default") && obj.contains("offset")) {
|
|
QString type = obj.value("type").toString();
|
|
if(type == "int") {
|
|
int offset = obj.value("offset").toInt();
|
|
CFG::data[offset] = obj.value("default").toInt();
|
|
//qInfo() << obj << __FUNCTION__;
|
|
}
|
|
}
|
|
}
|
|
//qInfo() << items << __FUNCTION__;
|
|
|
|
}
|
|
void CFG::backup()
|
|
{
|
|
memcpy(CFG::stored,CFG::data,SETTINGS_CFG_SIZE);
|
|
}
|
|
void CFG::restore()
|
|
{
|
|
memcpy(CFG::data,CFG::stored,SETTINGS_CFG_SIZE);
|
|
}
|
|
bool CFG::isEdited()
|
|
{
|
|
return (0 != memcmp(CFG::stored,CFG::data,SETTINGS_CFG_SIZE-sizeof(_EMTINFO)));
|
|
}
|
|
CFG_ERROR_CODE CFG::load(QString path)
|
|
{
|
|
CFG_ERROR_CODE r = CFG_UNKNOWN_ERROR;
|
|
if(!QFile::exists(path)) {
|
|
return CFG_IO_ERROR;
|
|
}
|
|
|
|
FILE* f = fopen(path.toLocal8Bit(),"r+b");
|
|
if(f == NULL) {
|
|
return CFG_IO_ERROR;
|
|
}
|
|
|
|
unsigned char d[SETTINGS_CFG_SIZE] = {0,};
|
|
size_t read = fread(d,1,SETTINGS_CFG_SIZE,f);
|
|
fclose(f);
|
|
if(read > 0)
|
|
{
|
|
cfgPath = path;
|
|
memcpy(CFG::data,d,read);
|
|
|
|
// 나머지 영역 초기화???
|
|
if(read == SETTINGS_CFG_SIZE) {
|
|
memcpy(&CFG::info,&d[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)],sizeof(_EMTINFO));
|
|
//setDefault();
|
|
r = verifyInfo();
|
|
if(r != CFG_SUCCESS) {
|
|
return r;
|
|
}
|
|
|
|
_loadJSon();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
setDefault();
|
|
}
|
|
|
|
|
|
CFG::backup(); // 현재 데이터 보존
|
|
// CHECKSUM 확인
|
|
if(!appUserSettingCheck()) {
|
|
return CFG_CHECKSUM_ERROR;
|
|
}
|
|
return r;
|
|
}
|
|
CFG_ERROR_CODE CFG::verifyInfo()
|
|
{
|
|
if(info.magic != 0xA5A5CC33) {
|
|
return CFG_WRONG_FILE;
|
|
}
|
|
// Magnus : 5101
|
|
// Trinity : 5102
|
|
// Mirror5 : 5103
|
|
// Pro5 : 5104
|
|
// 360X : 5105
|
|
// qInfo() << info.file1 << info.file2 << __FUNCTION__; // ?? 값이 정확하지 않음
|
|
// qInfo() << "MODEL CODE:" << info.model << "FILE SIZE:" << info.file1 << info.file2 << __FUNCTION__;
|
|
if(info.model < 5101 || info.model > 5105)
|
|
{
|
|
return CFG_WRONG_FILE;
|
|
}
|
|
return CFG_SUCCESS;
|
|
}
|
|
QString CFG::modelName()
|
|
{
|
|
for(int i=0;i<model_names.size();i++) {
|
|
if(model_codes[i] == info.model) {
|
|
return model_names.at(i);
|
|
}
|
|
}
|
|
return "UNKNOWN";
|
|
}
|
|
uint32_t CFG::version()
|
|
{
|
|
return info.version;
|
|
}
|
|
void CFG::clear()
|
|
{
|
|
memset(CFG::stored,0,SETTINGS_CFG_SIZE);
|
|
memset(CFG::data,0,SETTINGS_CFG_SIZE);
|
|
}
|
|
|
|
bool CFG::save(QString path)
|
|
{
|
|
bool bSuccess = false;
|
|
|
|
DWORD dwAttrib = ::GetFileAttributes((LPCTSTR)path.utf16());
|
|
if((dwAttrib & FILE_ATTRIBUTE_HIDDEN)) {
|
|
::SetFileAttributes((LPCTSTR)path.utf16(),FILE_ATTRIBUTE_NORMAL);
|
|
}
|
|
|
|
FILE* f = fopen(path.toLocal8Bit(),"w+b");
|
|
if(f != NULL)
|
|
{
|
|
if(isEdited())
|
|
{
|
|
CFG::data[SD_VIEWSETTING_OFFSET] = 1;
|
|
_updateCheckSum(); // 다시 계산
|
|
}
|
|
|
|
size_t write = 0;
|
|
write = fwrite(CFG::data,1,SETTINGS_CFG_SIZE,f);
|
|
bSuccess = write > 0;
|
|
fclose(f);
|
|
|
|
::SetFileAttributes((LPCTSTR)path.utf16(),FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN);
|
|
}
|
|
CFG::backup();
|
|
return bSuccess;
|
|
}
|
|
|
|
#define COMBINE_16(h, l) (uint16_t)((((uint16_t)h)<<8) | (uint16_t)l)
|
|
uint16_t CFG::checkSum() // appGetSum16_Emt(uint16_t *Buf, uint32_t Size)
|
|
{
|
|
// 마지막 1은?
|
|
uint32_t Size = ((SETTINGS_CFG_SIZE - sizeof(_EMTINFO)) / 2) - 1;
|
|
|
|
//uint8_t bSettingFileOK = TRUE;
|
|
uint16_t* pbuf = (uint16_t*)&data[0];
|
|
|
|
uint16_t Sum = 0;
|
|
uint32_t SumTemp = 0;
|
|
while( Size )
|
|
{
|
|
SumTemp += (uint32_t)pbuf[--Size];
|
|
}
|
|
Sum = (uint16_t)((uint16_t)((SumTemp >> 16) & 0x0000ffff) | (uint16_t)(SumTemp & 0x0000ffff));
|
|
return Sum;
|
|
}
|
|
void CFG::_updateCheckSum()
|
|
{
|
|
uint16_t c = checkSum();
|
|
data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-2] = ((c >> 8) & 0xFF);
|
|
data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-1] = (c & 0xFF);
|
|
}
|
|
bool CFG::appUserSettingCheck()
|
|
{
|
|
/*
|
|
uint16_t* pbuf = (uint16_t*)&data[0];
|
|
uint16_t checkSum, CalCheckSum;
|
|
|
|
// 설정 영역의 마지막 2BYTE
|
|
uint8_t checkData1 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-2];
|
|
uint8_t checkData2 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-1];
|
|
|
|
const uint32_t dataSize = SETTINGS_CFG_SIZE - sizeof(_EMTINFO);
|
|
checkSum = COMBINE_16(checkData1, checkData2);
|
|
CalCheckSum = appGetSum16_Emt(pbuf, (dataSize / 2)); // sizeof(uiParamSetting_t)
|
|
return (checkSum != CalCheckSum);
|
|
*/
|
|
// 설정 영역의 마지막 2BYTE
|
|
uint8_t checkData1 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-2];
|
|
uint8_t checkData2 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-1];
|
|
//qInfo() << "CHECKED:" << COMBINE_16(checkData1,checkData2) << "CALCED:" << checkSum() <<__FUNCTION__;
|
|
return (COMBINE_16(checkData1,checkData2) == checkSum());
|
|
}
|
|
//uint16_t CFG::checkSum()
|
|
//{
|
|
// uint16_t* pbuf = (uint16_t*)&data[0];
|
|
// const uint32_t dataSize = SETTINGS_CFG_SIZE - sizeof(_EMTINFO);
|
|
// return appGetSum16_Emt(pbuf, (dataSize / 2) - 1);
|
|
//}
|
|
|
|
#endif // #if (USE_DEVICE_SETTINGS && RM_MODEL_EMT_KR)
|