586 lines
22 KiB
C++
586 lines
22 KiB
C++
#include "licenceELC21.h"
|
|
#include "utils.h"
|
|
#include "SDCard.h"
|
|
#include "pugixml.hpp"
|
|
|
|
|
|
LicenceELC21::LicenceELC21()
|
|
{
|
|
}
|
|
|
|
LicenceELC21::LicenceELC21(LicenceIdentification &licIdentification, LicData &licData)
|
|
: lIdentification(licIdentification), lData(licData)
|
|
{
|
|
|
|
}
|
|
|
|
LicenceELC21::LicenceELC21(LicenceIdentification &licIdentification): lIdentification(licIdentification)
|
|
{
|
|
}
|
|
|
|
LicenceELC21::LicenceELC21(LicData &licData): lData(licData)
|
|
{
|
|
if (processInputConfiguration() == false) throw LicenceException((int)Error21::LicenceReadError, "Chyba při čtení licence");
|
|
}
|
|
|
|
bool LicenceELC21::createLicence()
|
|
{
|
|
getLicenceItems();
|
|
getHeader();
|
|
|
|
sdCard = SDCard(lData.cid, lData.csd);
|
|
if (sdCard.isLoaded == false) throw LicenceException((int)Error21::SDCardReadError, "Chyba při čtení SD karty, cesta: " + cid_cdsPath);
|
|
|
|
this->licBody.licenceIdentHeader.cardSize = sdCard.cardData.cardSize;
|
|
this->licBody.licenceIdentHeader.serialNumber = sdCard.cardData.serialNumber;
|
|
this->licBody.licenceIdentHeader.licItemCount = this->licBody.privateContent.dataItems.size();
|
|
this->licBody.licenceIdentHeader.publicHeaderLength = this->licBody.publicHeader.length();
|
|
|
|
vector<unsigned char> publicContent;
|
|
vector<unsigned char> privateContent;
|
|
vector<unsigned char> privateContentEncrypted;
|
|
|
|
|
|
publicContent.push_back(this->licBody.licId.licIdent[0]);
|
|
publicContent.push_back(this->licBody.licId.licIdent[1]);
|
|
publicContent.push_back(this->licBody.licId.licIdent[2]);
|
|
publicContent.push_back(((char)48 + (int)this->lIdentification.licElcType));
|
|
publicContent.push_back(this->licBody.licId.licIdent[4]);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.licenceType);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.licenceTypeVersion);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.licenceIndex);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.compatibilityVersion);
|
|
publicContent.push_back(this->licBody.privateContent.dataItems.size());
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.publicHeaderLength & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.publicHeaderLength >> 8) & 0xFF);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.cardSize & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.cardSize >> 8) & 0xFF);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.serialNumber & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 8) & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 16) & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 24) & 0xFF);
|
|
|
|
appendStringToVector(this->licBody.publicHeader, publicContent);
|
|
uint16_t crcPublic = calculateCRC16(publicContent);
|
|
|
|
#ifdef DEB
|
|
cout << "CRC pubblic: " << crcPublic << endl;
|
|
#endif
|
|
|
|
publicContent.push_back(crcPublic & 0xFF);
|
|
publicContent.push_back((crcPublic >> 8) & 0xFF);
|
|
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.licenceType);
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.licenceTypeVersion);
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.licenceIndex);
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.compatibilityVersion);
|
|
privateContent.push_back(this->licBody.privateContent.dataItems.size());
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.publicHeaderLength & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.publicHeaderLength >> 8) & 0xFF);
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.cardSize & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.cardSize >> 8) & 0xFF);
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.serialNumber & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 8) & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 16) & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 24) & 0xFF);
|
|
|
|
for (licDataItem dataItem : this->licBody.privateContent.dataItems)
|
|
{
|
|
privateContent.push_back(dataItem.protoId & 0xFF);
|
|
privateContent.push_back((dataItem.protoId >> 8) & 0xFF);
|
|
privateContent.push_back(dataItem.licCount & 0xFF);
|
|
privateContent.push_back((dataItem.licCount >> 8) & 0xFF);
|
|
for (unsigned int i = 0; i < sizeof(dataItem.dummy); i++)
|
|
privateContent.push_back(i);
|
|
}
|
|
|
|
vector<unsigned char> completeVector = joinVectors(publicContent, privateContent);
|
|
licBody.privateContent.crc = calculateCRC16(completeVector);
|
|
uint16_t crcComplete = calculateCRC16(completeVector);
|
|
|
|
privateContent.push_back(crcComplete & 0xFF);
|
|
privateContent.push_back((crcComplete >> 8) & 0xFF);
|
|
|
|
privateContentEncrypted = cryptPrivateContent(privateContent);
|
|
|
|
string licfileName = getLicenceName();
|
|
std::ofstream outputFile(licfileName, std::ios::out | std::ios::binary);
|
|
|
|
// Check if the file is open
|
|
if (!outputFile.is_open())
|
|
{
|
|
throw LicenceException((int)GeneralError::FileOpenError, "Chyba při zakládání souboru licence: " + cid_cdsPath);
|
|
}
|
|
|
|
std::copy(publicContent.cbegin(), publicContent.cend(), std::ostream_iterator<unsigned char>(outputFile));
|
|
std::copy(privateContentEncrypted.cbegin(), privateContentEncrypted.cend(), std::ostream_iterator<unsigned char>(outputFile));
|
|
|
|
outputFile.close();
|
|
|
|
cout << licfileName;
|
|
return true;
|
|
}
|
|
|
|
bool LicenceELC21::readLicence(LicenceInfoGeneral * licences)
|
|
{
|
|
|
|
// sdCard = SDCard("9f544930303030300000000b47015423", "400e00325b5900003a0d7f800a40008d");
|
|
sdCard = SDCard(this->cid_cdsPath);
|
|
if (sdCard.isLoaded == false) throw LicenceException((int)Error21::SDCardReadError, "Chyba při čtení SD karty, cesta: " + cid_cdsPath);
|
|
|
|
string licFileName = getLicenceName();
|
|
string licFilePath = this->licenceFilePath+licFileName;
|
|
|
|
vector<char> content;
|
|
if (readFile(licFilePath, content) == false)
|
|
{
|
|
throw LicenceException((int)GeneralError::FileOpenError, "Chyba otevření souboru licence: " + licFilePath);
|
|
}
|
|
|
|
this->licBody.licId.licIdent[0] = content[0];
|
|
this->licBody.licId.licIdent[1] = content[1];
|
|
this->licBody.licId.licIdent[2] = content[2];
|
|
this->licBody.licId.licIdent[3] = content[3];
|
|
this->licBody.licId.licIdent[4] = content[4];
|
|
|
|
this->licBody.licenceIdentHeader.licenceType = content[5];
|
|
this->licBody.licenceIdentHeader.licenceTypeVersion = content[6];
|
|
this->licBody.licenceIdentHeader.licenceIndex = content[7];
|
|
this->licBody.licenceIdentHeader.compatibilityVersion = content[8];
|
|
this->licBody.licenceIdentHeader.licItemCount = content[9];
|
|
this->licBody.licenceIdentHeader.publicHeaderLength = bytesToWord(content[10], content[11]);
|
|
this->licBody.licenceIdentHeader.cardSize = bytesToWord(content[12], content[13]);
|
|
this->licBody.licenceIdentHeader.serialNumber = bytesToDword(content[14], content[15], content[16], content[17]);
|
|
|
|
//~~~uint16_t crcPublic = bytesToWord(content[18 + licBody.licenceIdentHeader.publicHeaderLength], content[19 + licBody.licenceIdentHeader.publicHeaderLength]);
|
|
|
|
int elcVersion = (int)licBody.licId.licIdent[3] - 48;
|
|
|
|
if (elcVersion != (int)this->lIdentification.licElcType)
|
|
{
|
|
throw LicenceException((int)GeneralError::ELCMismatch, "Nesouhlasí ELC.");
|
|
}
|
|
|
|
vector<unsigned char> encryptedPart(content.begin() + licBody.licenceIdentHeader.publicHeaderLength + 20, content.begin() + content.size());
|
|
|
|
vector<unsigned char> privateContentDecrypted;
|
|
privateContentDecrypted = decryptPrivateContent(encryptedPart);
|
|
|
|
LicenceBody licBodyDecrypted;
|
|
licBodyDecrypted.licenceIdentHeader.licenceType = privateContentDecrypted[0];
|
|
licBodyDecrypted.licenceIdentHeader.licenceTypeVersion = privateContentDecrypted[1];
|
|
licBodyDecrypted.licenceIdentHeader.licenceIndex = privateContentDecrypted[2];
|
|
licBodyDecrypted.licenceIdentHeader.compatibilityVersion = privateContentDecrypted[3];
|
|
licBodyDecrypted.licenceIdentHeader.licItemCount = privateContentDecrypted[4];
|
|
licBodyDecrypted.licenceIdentHeader.publicHeaderLength = bytesToWord(privateContentDecrypted[5], privateContentDecrypted[6]);
|
|
licBodyDecrypted.licenceIdentHeader.cardSize = bytesToWord(privateContentDecrypted[7], privateContentDecrypted[8]);
|
|
licBodyDecrypted.licenceIdentHeader.serialNumber = bytesToDword(privateContentDecrypted[9], privateContentDecrypted[10], privateContentDecrypted[11], privateContentDecrypted[12]);
|
|
|
|
//~~~CRC
|
|
|
|
if (licBodyDecrypted.licenceIdentHeader.licItemCount != this->licBody.licenceIdentHeader.licItemCount)
|
|
{
|
|
throw LicenceException((int)Error21::ItemsCountMismatch, map21Errors.at(Error21::ItemsCountMismatch));
|
|
}
|
|
|
|
int index = 13;
|
|
for (int i = 0; i < this->licBody.licenceIdentHeader.licItemCount; i++)
|
|
{
|
|
licDataItem item;
|
|
item.protoId = bytesToWord(privateContentDecrypted[index], privateContentDecrypted[index + 1]);
|
|
item.licCount = bytesToWord(privateContentDecrypted[index + 2], privateContentDecrypted[index + 3]);
|
|
index += sizeof(licDataItem);
|
|
this->licBody.privateContent.dataItems.push_back(item);
|
|
this->licenceInfo.licences.insert(pair<int, int>(item.protoId, item.licCount));
|
|
licences->licences.insert(pair<int, int>(item.protoId, item.licCount));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
string LicenceELC21::getVersion(int middleVersion)
|
|
{
|
|
string result = "";
|
|
result.append(to_string(generatorVersion));
|
|
result.append(".");
|
|
result.append(to_string(middleVersion));
|
|
result.append(".");
|
|
string tempLicenceCount = "3"; // TODO
|
|
result.append(tempLicenceCount);
|
|
return result;
|
|
}
|
|
|
|
bool LicenceELC21::processInputConfiguration()
|
|
{
|
|
const char *dataRootName = "licence";
|
|
Mapping mapping;
|
|
|
|
string licType = lData.doc->child(dataRootName).child("licenceType").child_value();
|
|
if (!licType.empty())
|
|
{
|
|
this->lIdentification.licLicenceType = mapping.licMapTypes[licType]; // LicenceType::EOS_EOV;
|
|
this->lIdentification.licTypeName = licType;
|
|
}
|
|
else
|
|
{
|
|
errorMessage.code = (int)Error21::LicenceMismatch;
|
|
errorMessage.message = "ERROR MISSING licenceType";
|
|
return false;
|
|
}
|
|
|
|
this->lIdentification.licenceVersion = atoi(&lData.doc->child(dataRootName).child("licenceType").attribute("licenceVersion").value()[0]);
|
|
this->lIdentification.revision = lData.doc->child(dataRootName).attribute("revision").value()[0];
|
|
this->lIdentification.licenceIndex = atoi(&lData.doc->child(dataRootName).child("licenceType").attribute("licenceIndex").value()[0]);
|
|
this->lIdentification.licElcType = (ELCType)atoi(&lData.doc->child(dataRootName).attribute("elc").value()[0]);
|
|
|
|
this->lIdentification.licCompatibility = atoi(&lData.doc->child(dataRootName).attribute("compatibility").value()[0]);
|
|
|
|
string plcType = lData.doc->child(dataRootName).child("plcType").child_value();
|
|
if (!plcType.empty())
|
|
{
|
|
this->lIdentification.licPlcType = mapping.licMapPlcType[plcType];
|
|
}
|
|
|
|
this->lData.station = &lData.doc->child(dataRootName).child("station").child_value()[0];
|
|
this->lData.distributor = &lData.doc->child(dataRootName).child("distributor").child_value()[0];
|
|
this->lData.projectDescription = &lData.doc->child(dataRootName).child("project").child_value()[0];
|
|
|
|
licBody.licenceIdentHeader.cardSize = 0;
|
|
licBody.licenceIdentHeader.compatibilityVersion = this->lIdentification.licCompatibility;
|
|
licBody.licenceIdentHeader.licenceIndex = this->lIdentification.licenceIndex;
|
|
licBody.licenceIdentHeader.licenceType = this->lIdentification.licenceVersion;
|
|
licBody.licenceIdentHeader.licenceTypeVersion = this->lIdentification.licenceVersion;
|
|
licBody.licenceIdentHeader.serialNumber = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
void LicenceELC21::getLicenceItems()
|
|
{
|
|
int nodeIndex = 0;
|
|
int itemIndex = 0;
|
|
|
|
for (pugi::xml_node licItemNode : lData.doc->child("licence").child("items"))
|
|
{
|
|
licDataItem item;
|
|
|
|
item.protoId = atoi(licItemNode.child("protoId").child_value());
|
|
item.licCount = atoi(licItemNode.child("dataPointsCount").child_value());
|
|
|
|
this->licBody.privateContent.dataItems.push_back(item);
|
|
|
|
nodeIndex = 0;
|
|
itemIndex++;
|
|
for (pugi::xml_node child : licItemNode.children())
|
|
{
|
|
nodeIndex++;
|
|
if (nodeIndex == 1)
|
|
{
|
|
licBody.publicHeader.append("\"name\":\"");
|
|
licBody.publicHeader.append(child.child_value());
|
|
licBody.publicHeader.append("\",");
|
|
continue;
|
|
}
|
|
if (nodeIndex == 3)
|
|
{
|
|
licBody.publicHeader.append("\"dataPointsCount\":\"");
|
|
licBody.publicHeader.append(child.child_value());
|
|
licBody.publicHeader.append("\"");
|
|
}
|
|
}
|
|
if (itemIndex != lIdentification.licItemsCount)
|
|
{
|
|
licBody.publicHeader.append("},");
|
|
}
|
|
else
|
|
{
|
|
licBody.publicHeader.append("}");
|
|
}
|
|
}
|
|
}
|
|
|
|
void LicenceELC21::getHeader()
|
|
{
|
|
PublicHeader publicHeader;
|
|
publicHeader.version = getVersion(7);
|
|
publicHeader.projectDescription = lData.projectDescription;
|
|
publicHeader.date = getDate();
|
|
publicHeader.licenceType = lIdentification.licTypeName;
|
|
publicHeader.licenceType += to_string(lIdentification.licenceIndex);
|
|
|
|
licBody.publicHeader = "";
|
|
|
|
licBody.publicHeader.append("{\"version\":");
|
|
licBody.publicHeader.append(publicHeader.version);
|
|
licBody.publicHeader.append("\",");
|
|
|
|
licBody.publicHeader.append("\"project\":\"");
|
|
licBody.publicHeader.append(publicHeader.projectDescription);
|
|
licBody.publicHeader.append("\",");
|
|
|
|
licBody.publicHeader.append("\"date\":\"");
|
|
licBody.publicHeader.append(publicHeader.date);
|
|
licBody.publicHeader.append("\",");
|
|
|
|
licBody.publicHeader.append("\"note\":\"poznámka\",");
|
|
licBody.publicHeader.append("\"licenceType\":\"");
|
|
licBody.publicHeader.append(publicHeader.licenceType);
|
|
licBody.publicHeader.append("\",");
|
|
|
|
licBody.publicHeader.append("\"items\":[");
|
|
|
|
lIdentification.licItemsCount = std::distance(lData.doc->child("licence").child("items").begin(), lData.doc->child("licence").child("items").end());
|
|
|
|
int nodeIndex = 0;
|
|
int itemIndex = 0;
|
|
|
|
for (pugi::xml_node licItemNode : lData.doc->child("licence").child("items"))
|
|
{
|
|
licBody.publicHeader.append("{");
|
|
nodeIndex = 0;
|
|
itemIndex++;
|
|
for (pugi::xml_node child : licItemNode.children())
|
|
{
|
|
nodeIndex++;
|
|
if (nodeIndex == 1)
|
|
{
|
|
licBody.publicHeader.append("\"name\":\"");
|
|
licBody.publicHeader.append(child.child_value());
|
|
licBody.publicHeader.append("\",");
|
|
continue;
|
|
}
|
|
if (nodeIndex == 3)
|
|
{
|
|
licBody.publicHeader.append("\"dataPointsCount\":\"");
|
|
licBody.publicHeader.append(child.child_value());
|
|
licBody.publicHeader.append("\"");
|
|
}
|
|
}
|
|
if (itemIndex != lIdentification.licItemsCount)
|
|
{
|
|
licBody.publicHeader.append("},");
|
|
}
|
|
else
|
|
{
|
|
licBody.publicHeader.append("}");
|
|
}
|
|
}
|
|
|
|
licBody.publicHeader.append("]");
|
|
licBody.publicHeader.append("}");
|
|
}
|
|
|
|
vector<unsigned char> LicenceELC21::cryptPrivateContent(const std::vector<unsigned char> &content)
|
|
{
|
|
|
|
BYTE initVector[15] = {};
|
|
BYTE aesKey[32] = {};
|
|
|
|
LicenceELC21::initVector(initVector, aesKey);
|
|
|
|
unsigned char encrypted[10000] = {};
|
|
const unsigned char *plainTextArray = content.data();
|
|
int finalEncryptedLength = encrypt(plainTextArray, content.size(), aesKey, initVector, encrypted);
|
|
|
|
if (finalEncryptedLength <= 0) throw LicenceException((int)GeneralError::EncryptError, "Chyba při kryptování.");
|
|
|
|
std::vector<unsigned char> result(encrypted, encrypted + finalEncryptedLength);
|
|
|
|
return result;
|
|
}
|
|
|
|
vector<unsigned char> LicenceELC21::decryptPrivateContent(const std::vector<unsigned char> &content)
|
|
{
|
|
|
|
BYTE initVector[15] = {0};
|
|
BYTE aesKey[32] = {0};
|
|
|
|
LicenceELC21::initVector(initVector, aesKey);
|
|
|
|
const unsigned char *encryptedData = content.data();
|
|
unsigned char decrypted[10000] = {};
|
|
|
|
int decrypted_len = decrypt(encryptedData, content.size(), aesKey, initVector, decrypted);
|
|
if (decrypted_len <= 0) throw LicenceException((int)GeneralError::DecryptError, "Chyba při dekryptování.");
|
|
|
|
std::vector<unsigned char> result(decrypted, decrypted + decrypted_len);
|
|
|
|
return result;
|
|
}
|
|
|
|
void LicenceELC21::initVector(BYTE (&iVector)[], BYTE (&key)[])
|
|
{
|
|
|
|
struct Vector15
|
|
{
|
|
int vec[15];
|
|
};
|
|
|
|
Vector15 vec1 = {this->sdCard.cardData.CID[10],
|
|
this->sdCard.cardData.CID[12],
|
|
this->sdCard.cardData.CID[11],
|
|
this->sdCard.cardData.CID[9],
|
|
this->sdCard.cardData.CID_nibble[22] - 15,
|
|
this->sdCard.cardData.CID_nibble[24] - 15,
|
|
this->sdCard.cardData.CID_nibble[25] - 15,
|
|
this->sdCard.cardData.CID_nibble[21] - 15,
|
|
9, 10, 11, 12, 13, 14, 15};
|
|
Vector15 vec2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; //TODO přidat smysluplnější indexy
|
|
Vector15 vec3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
|
|
|
std::unordered_map<int, Vector15> vectors;
|
|
vectors.insert(std::pair<int, Vector15>(1, vec1));
|
|
vectors.insert(std::pair<int, Vector15>(2, vec2));
|
|
vectors.insert(std::pair<int, Vector15>(3, vec3));
|
|
|
|
struct Key32
|
|
{
|
|
int key[32];
|
|
};
|
|
|
|
Key32 key1 = {this->sdCard.cardData.CID[12],
|
|
this->sdCard.cardData.CID[23] - 15,
|
|
this->sdCard.cardData.CID[25] - 15,
|
|
this->sdCard.cardData.CID[11],
|
|
this->sdCard.cardData.CID[9],
|
|
this->sdCard.cardData.CID_nibble[21],
|
|
this->sdCard.cardData.CID[9] % 25,
|
|
this->sdCard.cardData.CID_nibble[22] - 15,
|
|
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
|
Key32 key2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
Key32 key3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
|
|
std::unordered_map<int, Key32> keys;
|
|
keys.insert(std::pair<int, Key32>(1, key1));
|
|
keys.insert(std::pair<int, Key32>(2, key2));
|
|
keys.insert(std::pair<int, Key32>(3, key3));
|
|
|
|
int lVersion = lIdentification.licenceVersion;
|
|
|
|
iVector[0] = vectors.at(lVersion).vec[0];
|
|
iVector[1] = vectors.at(lVersion).vec[1];
|
|
iVector[2] = vectors.at(lVersion).vec[2];
|
|
iVector[3] = vectors.at(lVersion).vec[3];
|
|
iVector[4] = vectors.at(lVersion).vec[4];
|
|
iVector[5] = vectors.at(lVersion).vec[5];
|
|
iVector[6] = vectors.at(lVersion).vec[6];
|
|
iVector[7] = vectors.at(lVersion).vec[7];
|
|
|
|
memcpy(&iVector[8], &iVector[0], 8);
|
|
|
|
key[0] = keys.at(lVersion).key[0];
|
|
key[1] = keys.at(lVersion).key[1];
|
|
key[2] = keys.at(lVersion).key[2];
|
|
key[3] = keys.at(lVersion).key[3];
|
|
key[4] = keys.at(lVersion).key[4];
|
|
key[5] = keys.at(lVersion).key[5];
|
|
key[6] = keys.at(lVersion).key[6];
|
|
key[7] = keys.at(lVersion).key[7];
|
|
memcpy(&key[8], &key[0], 8);
|
|
memcpy(&key[16], &key[6], 8);
|
|
memcpy(&key[24], &key[12], 8);
|
|
}
|
|
|
|
/// @brief get proper licencename
|
|
/// @param licPostfix
|
|
/// @return
|
|
string LicenceELC21::getLicenceName()
|
|
{
|
|
string result = "";
|
|
char prefixChar = 97;
|
|
int licType = (int)lIdentification.licLicenceType;
|
|
int lVersion = lIdentification.licenceVersion;
|
|
|
|
unordered_map<int, string> baseString;
|
|
baseString.insert(std::pair<int, string>((int)LicenceType::EOS_EOV, "ezlic_eovosv"));
|
|
baseString.insert(std::pair<int, string>((int)LicenceType::DDTS, "ezlic_ddts"));
|
|
baseString.insert(std::pair<int, string>((int)LicenceType::DRT, "ezlic_drt"));
|
|
|
|
struct Index
|
|
{
|
|
int index[11];
|
|
};
|
|
|
|
std::unordered_map<int, Index> indexes;
|
|
Index indexes1 = {7, 16, 20, 23, 18, 4, 9, 11, 6, 9, 13};
|
|
Index indexes2 = {12, 10, 22, 23, 24, 25, 9, 11, 2, 1, 3}; // puvodní indexy
|
|
Index indexes3 = {8, 13, 11, 9, 7, 11, 10, 13, 5, 20, 19};
|
|
|
|
indexes.insert(std::pair<int, Index>(1, indexes1));
|
|
indexes.insert(std::pair<int, Index>(2, indexes2));
|
|
indexes.insert(std::pair<int, Index>(3, indexes3));
|
|
|
|
result = baseString.at(licType) + to_string(lIdentification.licenceIndex) + "_";
|
|
|
|
result += prefixChar + ((this->sdCard.cardData.CID[indexes.at(lVersion).index[0]] + (lIdentification.licenceIndex * 11)) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID[indexes.at(lVersion).index[1]] + (lIdentification.licenceIndex * 39)) % 25);
|
|
|
|
result += prefixChar + ((this->sdCard.cardData.CID_nibble[indexes.at(lVersion).index[2]] + (lIdentification.licenceIndex * 1)) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID_nibble[indexes.at(lVersion).index[3]] * 2) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID_nibble[indexes.at(lVersion).index[4]] + (lIdentification.licenceIndex * 5)) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID_nibble[indexes.at(lVersion).index[5]] * 3) % 25);
|
|
|
|
result += prefixChar + ((this->sdCard.cardData.CID[indexes.at(lVersion).index[6]] + (lIdentification.licenceIndex * 52)) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID[indexes.at(lVersion).index[7]] + (lIdentification.licenceIndex * 34)) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID[indexes.at(lVersion).index[8]] + (lIdentification.licenceIndex * 21)) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID[indexes.at(lVersion).index[9]] + (lIdentification.licenceIndex * 47)) % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID[indexes.at(lVersion).index[10]] + (lIdentification.licenceIndex * 7)) % 25);
|
|
|
|
result += ".lic";
|
|
return result;
|
|
}
|
|
|
|
int LicenceELC21::getDataPointsCount(int protocolId)
|
|
{
|
|
if (this->readLicence(nullptr) == false)
|
|
{
|
|
}
|
|
|
|
for (auto item : this->licBody.privateContent.dataItems)
|
|
{
|
|
if (item.protoId == protocolId)
|
|
return item.licCount;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool LicenceELC21::getLicenceItemInfo(int protocolId, void *returnItemStructure)
|
|
{
|
|
if (returnItemStructure != nullptr)
|
|
{
|
|
LicenceItem21 *resultPtr = static_cast<LicenceItem21 *>(returnItemStructure);
|
|
resultPtr->protocolId = protocolId; // protocolId;
|
|
if (this->licenceInfo.licences.count(protocolId)) resultPtr->dataPointsCount=this->licenceInfo.licences.at(protocolId);
|
|
else resultPtr->dataPointsCount = 0;
|
|
}
|
|
else
|
|
{
|
|
errorMessage.code = 1;
|
|
errorMessage.message = "Error: Null pointer!";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LicenceELC21::getLicenceInfo(void *returnStructure)
|
|
{
|
|
if (returnStructure != nullptr)
|
|
{
|
|
LicenceInfo21 *resultPtr = static_cast<LicenceInfo21 *>(returnStructure);
|
|
for (auto item : this->licBody.privateContent.dataItems)
|
|
{
|
|
resultPtr->licences.insert(pair<int, int>(item.protoId, item.licCount));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
errorMessage.code = 1;
|
|
errorMessage.message = "Error: Null pointer!";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
LicenceELC21::~LicenceELC21() {}
|