diff --git a/services/ptable_parse/ptable.cpp b/services/ptable_parse/ptable.cpp index d91e4b2a99127ea5264891a1292e820274569aba..d2a062f474927cb50386291a4877d6b293428292 100644 --- a/services/ptable_parse/ptable.cpp +++ b/services/ptable_parse/ptable.cpp @@ -48,6 +48,21 @@ bool Ptable::CorrectBufByPtnList(uint8_t *imageBuf, uint64_t imgBufSize, const s return false; } +bool SyncABLunPtableDevice(const int sourceSlot) +{ + (void)sourceSlot; + return false; +} + +bool GetABLunPartitionInfo(const int sourceSlot, std::string &srcNode, std::string &tgtNode, uint32_t &offset) +{ + (void)sourceSlot; + (void)srcNode; + (void)tgtNode; + (void)offset; + return false; +} + uint32_t Ptable::GetPtablePartitionNum() const { return partitionInfo_.size(); @@ -529,6 +544,23 @@ void Ptable::ParsePartitionName(const uint8_t *data, const uint32_t dataLen, return; } +bool Ptable::WritePartitionName(const std::string &name, const uint32_t nameLen, + uint8_t *data, const uint32_t dataLen) +{ + // 2 : convert utf16 to utf8 , 2 bytes for 1 charactor + if (data == nullptr || dataLen == 0 || nameLen == 0 || dataLen < nameLen * 2) { + LOG(ERROR) << "Invalid parameters"; + return false; + } + // convert utf16 to utf8 , 2 bytes for 1 charactor of partition name + for (uint32_t n = 0; n < nameLen; n++) { + data[n * 2] = static_cast(tolower(name[n])); // 2 : 2 bytes + data[n * 2 + 1] = 0; // 2 : 2 bytes + } + LOG(INFO) << "Write Partition Name success: " << name; + return true; +} + bool Ptable::WriteBufferToPath(const std::string &path, const uint64_t offset, const uint8_t *buffer, const uint32_t size) { diff --git a/services/ptable_parse/ptable.h b/services/ptable_parse/ptable.h index 7bab2056afe6e629435f0dd0ca544765e02e6932..f88c5e8601f4421228d62a5b3054de86bda85207 100644 --- a/services/ptable_parse/ptable.h +++ b/services/ptable_parse/ptable.h @@ -93,6 +93,9 @@ public: virtual void AddChildPtable(std::unique_ptr child) {} virtual bool CorrectBufByPtnList(uint8_t *imageBuf, uint64_t imgBufSize, const std::vector &srcInfo, const std::vector &dstInfo); + virtual bool SyncABLunPtableDevice(const int sourceSlot); + virtual bool GetABLunPartitionInfo(const int sourceSlot, std::string &srcNode, + std::string &tgtNode, uint32_t &offset); int GetEndPtnIndex() { @@ -232,6 +235,7 @@ public: const uint32_t blockSize, GPTHeaderInfo& gptHeaderInfo); void ParsePartitionName(const uint8_t *data, const uint32_t dataLen, std::string &name, const uint32_t nameLen); + bool WritePartitionName(const std::string &name, const uint32_t nameLen, uint8_t *data, const uint32_t dataLen); uint32_t CalculateCrc32(const uint8_t *buffer, const uint32_t len); bool WritePtablePartition(const std::string &path, uint64_t offset, const uint8_t *buffer, uint32_t size); bool CheckFileExist(const std::string &fileName); diff --git a/services/ptable_parse/ufs_ptable.cpp b/services/ptable_parse/ufs_ptable.cpp index 4a0989fa91451f08b0d2dc9788211224011778ff..a8078d1fd33b6eef19c9c1a46fb4a6497ec80d6d 100644 --- a/services/ptable_parse/ufs_ptable.cpp +++ b/services/ptable_parse/ufs_ptable.cpp @@ -23,8 +23,12 @@ #include "log/log.h" #include "securec.h" #include "updater/updater_const.h" +#include "utils.h" namespace Updater { +constexpr const uint32_t LUN_FOR_SLOT_A = 3; +constexpr const uint32_t LUN_FOR_SLOT_B = 4; + uint32_t UfsPtable::GetDeviceLunNum() { return deviceLunNum_; @@ -614,7 +618,7 @@ bool UfsPtable::EditPartitionBuf(uint8_t *imageBuf, uint64_t imgBufSize, std::ve } return true; } - + bool UfsPtable::GetPtableImageBuffer(uint8_t *imageBuf, const uint32_t imgBufSize) { uint32_t imgBlockSize = ptableData_.lbaLen; // 512 @@ -664,4 +668,133 @@ bool UfsPtable::GetPtableImageBuffer(uint8_t *imageBuf, const uint32_t imgBufSiz } return true; } + +void UfsPtable::GetTgtPartitionName(std::string &name, const int sourceSlot) +{ + LOG(INFO) << "Get target PartitionName. source: " << name; + if (name.size() < PARTITION_AB_SUFFIX_SIZE) { + name += (sourceSlot == SLOT_A ? PARTITION_B_SUFFIX : PARTITION_A_SUFFIX); + LOG(INFO) << "Get target PartitionName: " << name; + return; + } + std::string suffix = name.substr(name.size() - PARTITION_AB_SUFFIX_SIZE, PARTITION_AB_SUFFIX_SIZE); + std::string partitionName = name.substr(0, name.size() - PARTITION_AB_SUFFIX_SIZE); + if (strcasecmp(suffix.c_str(), PARTITION_A_SUFFIX) == 0) { + name = partitionName + PARTITION_B_SUFFIX; + } else if (strcasecmp(suffix.c_str(), PARTITION_B_SUFFIX) == 0) { + name = partitionName + PARTITION_A_SUFFIX; + } else { + name += (sourceSlot == SLOT_A ? PARTITION_B_SUFFIX : PARTITION_A_SUFFIX); + } + return; +} + +bool UfsPtable::EditABPartition(uint8_t *gptImage, const uint32_t blockSize, const int sourceSlot) +{ + uint32_t partEntryCnt = blockSize / PARTITION_ENTRY_SIZE; // blockSize = 4096 + uint32_t partition0 = GET_LLWORD_FROM_BYTE(gptImage + blockSize + PARTITION_ENTRIES_OFFSET); + + uint32_t count = 0; + uint8_t *data = nullptr; + for (uint32_t i = 0; i < (MAX_PARTITION_NUM / partEntryCnt) && count < MAX_PARTITION_NUM; i++) { + data = gptImage + (partition0 + i) * blockSize; + for (uint32_t j = 0; j < partEntryCnt; j++) { + uint8_t typeGuid[GPT_PARTITION_TYPE_GUID_LEN] = {0}; + if (memcpy_s(typeGuid, sizeof(typeGuid), &data[(j * PARTITION_ENTRY_SIZE)], sizeof(typeGuid)) != EOK) { + LOG(ERROR) << "memcpy guid fail"; + } + if (typeGuid[0] == 0x00 && typeGuid[1] == 0x00) { // 0x00 means no partition + i = MAX_PARTITION_NUM / partEntryCnt; + break; + } + uint8_t *nameOffset = data + (j * PARTITION_ENTRY_SIZE + GPT_PARTITION_NAME_OFFSET); + // 2 bytes for 1 charactor of partition name + std::string name; + ParsePartitionName(nameOffset, MAX_GPT_NAME_SIZE, name, MAX_GPT_NAME_SIZE / 2); // 2 : 2 bytes + GetTgtPartitionName(name, sourceSlot); + if (!WritePartitionName(name, name.length(), nameOffset, MAX_GPT_NAME_SIZE)) { + LOG(ERROR) << "Write PartitionName failed: " << name; + return false; + } + count++; + } + } + LOG(INFO) << "start to Calculate Crc32"; + // Updating CRC of the Partition entry array in both headers + uint32_t partCount = GET_LWORD_FROM_BYTE(gptImage + blockSize + PARTITION_COUNT_OFFSET); + uint32_t entrySize = GET_LWORD_FROM_BYTE(gptImage + blockSize + PENTRY_SIZE_OFFSET); + // mbr len + gptHeader len = 2 blockSize + uint32_t crcValue = CalculateCrc32(gptImage + (blockSize * 2), partCount * entrySize); + PUT_LONG(gptImage + blockSize + PARTITION_CRC_OFFSET, crcValue); + // Clearing CRC fields to calculate + PUT_LONG(gptImage + blockSize + HEADER_CRC_OFFSET, 0); + crcValue = CalculateCrc32(gptImage + blockSize, GPT_CRC_LEN); + PUT_LONG(gptImage + blockSize + HEADER_CRC_OFFSET, crcValue); + return true; +} + +bool UfsPtable::ModifyBufferPartitionName(uint8_t *buffer, const uint32_t bufferSize, const int sourceSlot) +{ + LOG(INFO) << "start to modify partition name in buffer"; + if (buffer == nullptr || bufferSize == 0) { + LOG(ERROR) << "invaild input"; + return false; + } + uint32_t blockSize = GetDeviceBlockSize(); + if (blockSize == 0) { + LOG(ERROR) << "invaild blockSize: " << blockSize; + return false; + } + + if (!EditABPartition(buffer, blockSize, sourceSlot)) { + LOG(ERROR) << "Edit AB PartitionName failed"; + return false; + } + LOG(INFO) << "modify partition name in buffer finished"; + return true; +} + +bool UfsPtable::SyncABLunPtableDevice(const int sourceSlot) +{ + LOG(INFO) << "start to sync ABLun Ptable in Device"; + std::string srcNodePath = GetDeviceLunNodePath(sourceSlot == SLOT_A ? LUN_FOR_SLOT_A : LUN_FOR_SLOT_B); + uint32_t len = ptableData_.writeDeviceLunSize; + std::unique_ptr buffer = std::make_unique(len); + if (buffer == nullptr) { + LOG(ERROR) << "new buffer failed!"; + return false; + } + if (!MemReadWithOffset(srcNodePath, 0, buffer.get(), len)) { + LOG(ERROR) << "read ptable from " << srcNodePath << " failed!"; + return false; + } + if (!ModifyBufferPartitionName(buffer.get(), len, sourceSlot)) { + LOG(ERROR) << "Modify PartitionName failed!"; + return false; + } + std::string tgtNodePath = GetDeviceLunNodePath(sourceSlot == SLOT_A ? LUN_FOR_SLOT_B : LUN_FOR_SLOT_A); + if (!WriteBufferToPath(tgtNodePath, 0, buffer.get(), len)) { + LOG(ERROR) << "write first gpt fail"; + return false; + } + LOG(INFO) << "Sync ABLun Ptable in Device success"; + return true; +} + +bool UfsPtable::GetABLunPartitionInfo(const int sourceSlot, std::string &srcNode, + std::string &tgtNode, uint32_t &offset) +{ + srcNode = GetDeviceLunNodePath(sourceSlot == SLOT_A ? LUN_FOR_SLOT_A : LUN_FOR_SLOT_B); + tgtNode = GetDeviceLunNodePath(sourceSlot == SLOT_A ? LUN_FOR_SLOT_B : LUN_FOR_SLOT_A); + offset = ptableData_.writeDeviceLunSize; + if (offset == 0) { + LOG(ERROR) << "invalid offset"; + return false; + } + if (!CheckFileExist(srcNode) || !CheckFileExist(tgtNode)) { + LOG(ERROR) << "Node is not exist. srcNode:" << srcNode << " tgtNode:" << (tgtNode); + return false; + } + return true; +} } // namespace Updater diff --git a/services/ptable_parse/ufs_ptable.h b/services/ptable_parse/ufs_ptable.h index a3cde0e3eca82691786a67182e593962a57b50f8..80589fe3f5ed15f9b2dce39dcb688492dd7dce7a 100644 --- a/services/ptable_parse/ufs_ptable.h +++ b/services/ptable_parse/ufs_ptable.h @@ -33,6 +33,9 @@ public: bool GetPtableImageBuffer(uint8_t *imageBuf, const uint32_t imgBufSize) override; bool CorrectBufByPtnList(uint8_t *imageBuf, uint64_t imgBufSize, const std::vector &srcInfo, const std::vector &dstInfo) override; + bool SyncABLunPtableDevice(const int sourceSlot) override; + bool GetABLunPartitionInfo(const int sourceSlot, std::string &srcNode, + std::string &tgtNode, uint32_t &offset) override; #ifndef UPDATER_UT protected: #else @@ -68,6 +71,9 @@ private: #else public: #endif + bool EditABPartition(uint8_t *gptImage, const uint32_t blockSize, const int sourceSlot); + void GetTgtPartitionName(std::string &name, const int sourceSlot); + bool ModifyBufferPartitionName(uint8_t *buffer, const uint32_t bufferSize, const int sourceSlot); bool WriteBackupPartitionTable(uint32_t lunIdx, uint64_t lunSize); bool UfsReadGpt(const uint8_t *gptImage, const uint32_t len, const uint32_t lun, const uint32_t blockSize); void UfsReadGptEntry(const uint8_t *gptImage, const uint32_t lun, diff --git a/services/updater.cpp b/services/updater.cpp index 3163074480ef3d23113dc97ccf28818658d1f6cb..78ed1177355bc69f4cbd648cf4874527ffd0c0c9 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -307,6 +307,12 @@ UpdaterStatus SetUpdateSlotParam(UpdaterParams &upParams, bool isUpdateCurrSlot) if (!Utils::IsVabDevice()) { return UPDATE_SUCCESS; } + if (!isUpdateCurrSlot && upParams.updatePackage.size() == 1) { + std::string pkgPath = upParams.updatePackage[0]; + if (pkgPath.find("updater.zip") != std::string::npos) { + isUpdateCurrSlot = true; + } + } int currentSlot = GetCurrentSlot(); if (currentSlot < 1 || currentSlot > 2) { // 2 : max slot LOG(ERROR) << "GetCurrentSlot failed";