1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "flash_commander.h" 17 18#include "datetime_ex.h" 19#include "flashd_define.h" 20#include "flashd_utils.h" 21#include "fs_manager/mount.h" 22#include "ptable_parse/ptable_manager.h" 23#include "updater/updater.h" 24 25namespace Flashd { 26namespace { 27constexpr size_t CMD_PARAM_COUNT_MIN = 2; 28} 29 30void FlashCommander::DoCommand(const std::string &cmmParam, size_t fileSize) 31{ 32 FLASHD_LOGI("start to flash"); 33 auto params = Split(cmmParam, { "-f" }); 34 if (params.size() < CMD_PARAM_COUNT_MIN) { 35 FLASHD_LOGE("flash param count is %u, not invaild", params.size()); 36 NotifyFail(CmdType::FLASH); 37 return; 38 } 39 40 fileSize_ = fileSize; 41 partName_ = params[0]; 42 startTime_ = OHOS::GetMicroTickCount(); 43 44 if (auto ret = Updater::MountForPath(GetPathRoot(FLASHD_FILE_PATH)); ret != 0) { 45 FLASHD_LOGE("MountForPath fail, ret = %d", ret); 46 NotifyFail(CmdType::FLASH); 47 return; 48 } 49 50 if (access(FLASHD_FILE_PATH, F_OK) == -1) { 51 mkdir(FLASHD_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 52 } 53 return; 54} 55 56void FlashCommander::DoCommand(const uint8_t *payload, int payloadSize) 57{ 58 if (payload == nullptr || payloadSize <= 0) { 59 FLASHD_LOGE("payload is null or payloadSize is invaild"); 60 NotifyFail(CmdType::FLASH); 61 return; 62 } 63 64 auto writeSize = DoFlash(payload, payloadSize); 65 if (writeSize < 0) { 66 NotifyFail(CmdType::FLASH); 67 return; 68 } 69 70 currentSize_ += static_cast<size_t>(writeSize); 71 if (currentSize_ >= fileSize_) { 72 auto useSec = static_cast<double>(OHOS::GetMicroTickCount() - startTime_) / OHOS::SEC_TO_MICROSEC; 73 FLASHD_LOGI("flash success, size = %u bytes, %.3lf s", fileSize_, useSec); 74 NotifySuccess(CmdType::FLASH); 75 return; 76 } 77 UpdateProgress(CmdType::FLASH); 78} 79 80bool FlashCommander::InitPartition(const std::string &partName, const uint8_t *buffer, int bufferSize) 81{ 82#ifdef UPDATER_USE_PTABLE 83 DevicePtable::GetInstance().LoadPartitionInfo(); 84#endif 85 std::unique_ptr<FlashdWriter> writer = FlashdImageWriter::GetInstance().GetWriter( 86 partName, buffer, bufferSize); 87 if (writer == nullptr) { 88 FLASHD_LOGE("FlashdImageWriter GetWriter error"); 89 return false; 90 } 91 partition_ = std::make_unique<Partition>(partName, std::move(writer)); 92 return (partition_ == nullptr) ? false : true; 93} 94 95int FlashCommander::DoFlash(const uint8_t *payload, int payloadSize) 96{ 97 if (partition_ == nullptr) { 98 if (!InitPartition(partName_, payload, payloadSize)) { 99 FLASHD_LOGE("DoFlash InitPartition fail"); 100 return -1; 101 } 102 } 103 104 auto writeSize = std::min(static_cast<size_t>(payloadSize), fileSize_ - currentSize_); 105 if (writeSize <= 0) { 106 FLASHD_LOGW("all the data is written"); 107 return 0; 108 } 109 110 if (partition_->DoFlash(payload, writeSize) != 0) { 111 FLASHD_LOGE("DoFlash fail"); 112 return -1; 113 } 114 return writeSize; 115} 116 117void FlashCommander::PostCommand() 118{ 119 Updater::PostUpdater(false); 120} 121} // namespace Flashd