Files
sd_gen/src/generator/licGenELC2.cpp
2024-04-10 08:03:43 +02:00

328 lines
12 KiB
C++

#include "licGenELC2.h"
namespace Generator
{
Licence2::Licence2()
{
}
Licence2::~Licence2() {}
Licence2::Licence2(string cid, string csd, pugi::xml_document *xmlDoc)
{
this->cid = cid;
this->csd = csd;
this->xmlDoc = xmlDoc;
if (processInputConfiguration() == false)
throw LicenceException((int)GeneralError::LicenceReadError, "Chyba při čtení licence");
}
void Licence2::getHeader()
{
PublicHeader publicHeader;
publicHeader.version = getVersion(lIdentification.revision);
publicHeader.projectDescription = projectDescription;
publicHeader.date = "4.4.2024"; //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(xmlDoc->child("licence").child("items").begin(), xmlDoc->child("licence").child("items").end());
int nodeIndex = 0;
int itemIndex = 0;
for (pugi::xml_node licItemNode : xmlDoc->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("}");
}
string Licence2::getVersion(int middleVersion)
{
string result = "";
result.append(to_string(generatorVersion));
result.append(".");
result.append(to_string(middleVersion));
result.append(".");
string tempLicenceCount = "1"; // TODO
result.append(tempLicenceCount);
return result;
}
bool Licence2::processInputConfiguration()
{
const char *dataRootName = "licence";
string licType = xmlDoc->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)GeneralError::LicenceMismatch;
errorMessage.message = "ERROR MISSING licenceType";
return false;
}
this->lIdentification.licenceVersion = atoi(&xmlDoc->child(dataRootName).child("licenceType").attribute("licenceVersion").value()[0]);
this->lIdentification.revision = atoi(&xmlDoc->child(dataRootName).attribute("revision").value()[0]);
this->lIdentification.licenceIndex = atoi(&xmlDoc->child(dataRootName).child("licenceType").attribute("licenceIndex").value()[0]);
this->lIdentification.licElcType = (ELCType)atoi(&xmlDoc->child(dataRootName).attribute("elc").value()[0]);
this->lIdentification.licCompatibility = atoi(&xmlDoc->child(dataRootName).attribute("compatibility").value()[0]);
string plcType = xmlDoc->child(dataRootName).child("plcType").child_value();
if (!plcType.empty())
{
this->lIdentification.licPlcType = mapping.licMapPlcType[plcType];
}
this->projectDescription = &xmlDoc->child(dataRootName).child("project").child_value()[0];
licBody.licenceIdentHeader.cardSize={};
licBody.licenceIdentHeader.compatibilityVersion = this->lIdentification.licCompatibility;
licBody.licenceIdentHeader.licenceIndex = this->lIdentification.licenceIndex;
licBody.licenceIdentHeader.licenceType = (BYTE)this->lIdentification.licLicenceType;
licBody.licenceIdentHeader.licenceTypeVersion = this->lIdentification.licenceVersion;
licBody.licenceIdentHeader.serialNumber={};
return true;
}
void Licence2::getLicenceItems()
{
int nodeIndex = 0;
int itemIndex = 0;
for (pugi::xml_node licItemNode : xmlDoc->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("}");
}
}
}
bool Licence2::createLicence()
{
getLicenceItems();
getHeader();
sdCard = SDCard(this->cid, this->csd);
if (sdCard.isLoaded == false)
throw LicenceException((int)GeneralError::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);
#ifdef CRCCHECK
cout << "CRC public size: " << publicContent.size() << "\n";
cout << "CRC gen public: " << calculateCRC16(publicContent) << "\n";
#endif
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);
privateContent.push_back(1);
privateContent.push_back(1);
privateContent.push_back(1);
// cout << "basic private: \n";
// for (const auto x : privateContent) cout << (int)x << "-";
// cout << "\n";
for (licDataItem dataItem : this->licBody.privateContent.dataItems)
{
cout << "proto: " << dataItem.protoId << "---";
privateContent.push_back(dataItem.protoId & 0xFF);
privateContent.push_back((dataItem.protoId >> 8) & 0xFF);
privateContent.push_back((dataItem.protoId >> 16) & 0xFF);
privateContent.push_back((dataItem.protoId >> 24) & 0xFF);
privateContent.push_back(dataItem.licCount & 0xFF);
privateContent.push_back((dataItem.licCount >> 8) & 0xFF);
privateContent.push_back((dataItem.licCount >> 16) & 0xFF);
privateContent.push_back((dataItem.licCount >> 24) & 0xFF);
for (const auto x : privateContent) cout << (int)x << "-";
cout << "\n";
//for (unsigned int i = 0; i < sizeof(dataItem.dummy); i++) privateContent.push_back(i);
}
cout << "\n final private \n";
#ifdef CRCCHECK
cout << "CRC private size: " << privateContent.size() << "\n";
cout << "CRC gen private: " << calculateCRC16(privateContent) << "\n";
#endif
vector<unsigned char> completeVector = joinVectors(publicContent, privateContent);
uint16_t crcComplete = calculateCRC16(completeVector);
#ifdef CRCCHECK
cout << "CRC complete size: " << completeVector.size() << "\n";
cout << "CRC gen complete: " << crcComplete << "\n";
#endif
privateContent.push_back(crcComplete & 0xFF);
privateContent.push_back((crcComplete >> 8) & 0xFF);
// cout << "crc complete: " << crcComplete << "\n";
// cout << "privateContent length: " << privateContent.size() << "\n";
// for (auto x : privateContent) cout << (int)x << "-";
// cout << "\n";
privateContentEncrypted = cryptPrivateContent(privateContent);
// cout << "privateContentEncrypted length: " << privateContentEncrypted.size() << "\n";
// for (auto x : privateContentEncrypted) cout << (int)x << "-";
// cout << "\n";
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;
}
}