#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 publicContent {}; vector privateContent {}; vector 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 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(outputFile)); std::copy(privateContentEncrypted.cbegin(), privateContentEncrypted.cend(), std::ostream_iterator(outputFile)); outputFile.close(); cout << licfileName; return true; } }