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 "update_commander.h" 17 18#include <unordered_map> 19 20#include "datetime_ex.h" 21#include "flashd_define.h" 22#include "flashd_utils.h" 23#include "fs_manager/mount.h" 24#include "package/pkg_manager.h" 25#include "updater/updater.h" 26#include "updater/updater_const.h" 27#include "updaterkits/updaterkits.h" 28#include "utils.h" 29 30namespace Flashd { 31namespace { 32constexpr size_t CMD_PARAM_COUNT_MIN = 1; 33} 34 35UpdateCommander::~UpdateCommander() 36{ 37 SafeCloseFile(fd_); 38} 39 40void UpdateCommander::DoCommand(const std::string &cmdParam, size_t fileSize) 41{ 42 FLASHD_LOGI("start to update"); 43 startTime_ = OHOS::GetMicroTickCount(); 44 auto params = Split(cmdParam, { "-f" }); 45 if (params.size() < CMD_PARAM_COUNT_MIN) { 46 FLASHD_LOGE("update param count is %u, not invaild", params.size()); 47 NotifyFail(CmdType::UPDATE); 48 return; 49 } 50 51 if (auto ret = Updater::MountForPath(GetPathRoot(FLASHD_FILE_PATH)); ret != 0) { 52 FLASHD_LOGE("MountForPath fail, ret = %d", ret); 53 NotifyFail(CmdType::UPDATE); 54 return; 55 } 56 57 if (access(FLASHD_FILE_PATH, F_OK) == -1) { 58 mkdir(FLASHD_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 59 } 60 61 fileSize_ = fileSize; 62 filePath_ = FLASHD_FILE_PATH + GetFileName(cmdParam); 63 fd_ = open(filePath_.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 64 if (fd_ < 0) { 65 NotifyFail(CmdType::UPDATE); 66 FLASHD_LOGE("open file fail, errno = %d ", errno); 67 return; 68 } 69} 70 71void UpdateCommander::DoCommand(const uint8_t *payload, int payloadSize) 72{ 73 if (payload == nullptr || payloadSize <= 0) { 74 NotifyFail(CmdType::UPDATE); 75 FLASHD_LOGE("payload is null or payloadSize is invaild"); 76 return; 77 } 78 79 if (!DoUpdate(payload, payloadSize)) { 80 NotifyFail(CmdType::UPDATE); 81 return; 82 } 83} 84 85bool UpdateCommander::DoUpdate(const uint8_t *payload, int payloadSize) 86{ 87 if (fd_ < 0) { 88 FLASHD_LOGE("file fd is invaild"); 89 return false; 90 } 91 92 auto writeSize = std::min(static_cast<size_t>(payloadSize), fileSize_ - currentSize_); 93 if (writeSize <= 0) { 94 FLASHD_LOGW("all the data has been written"); 95 return true; 96 } 97 98 if (!Updater::Utils::WriteFully(fd_, payload, writeSize)) { 99 FLASHD_LOGE("WriteFully fail, errno = %d", errno); 100 return false; 101 } 102 103 currentSize_ += writeSize; 104 if (currentSize_ >= fileSize_) { 105 fsync(fd_); 106 SafeCloseFile(fd_); 107 auto useSec = static_cast<double>(OHOS::GetMicroTickCount() - startTime_) / OHOS::SEC_TO_MICROSEC; 108 FLASHD_LOGI("update write file success, size = %u bytes, %.3lf s", fileSize_, useSec); 109 NotifySuccess(CmdType::UPDATE); 110 return true; 111 } 112 UpdateProgress(CmdType::UPDATE); 113 return true; 114} 115 116bool UpdateCommander::ExecUpdate() const 117{ 118 const std::string miscFile = "/dev/block/by-name/misc"; 119 std::vector<std::string> filePath; 120 filePath.push_back(filePath_); 121 if (RebootAndInstallUpgradePackage(miscFile, filePath) == 0) { 122 return true; 123 } 124 return false; 125} 126 127void UpdateCommander::PostCommand() 128{ 129 SaveLog(); 130 if (!ExecUpdate()) { 131 FLASHD_LOGE("ExecUpdate failed"); 132 } 133} 134 135void UpdateCommander::SaveLog() const 136{ 137 const std::unordered_map<std::string, std::string> logMap = { 138 { Updater::TMP_LOG, Updater::UPDATER_LOG }, 139 { Updater::TMP_ERROR_CODE_PATH, Updater::ERROR_CODE_PATH }, 140 { FLASHD_HDC_LOG_PATH, Updater::UPDATER_HDC_LOG }, 141 { Updater::TMP_STAGE_LOG, Updater::UPDATER_STAGE_LOG }, 142 }; 143 constexpr mode_t mode = 0640; 144 145 for (const auto &iter : logMap) { 146 if (!Updater::Utils::CopyUpdaterLogs(iter.first, iter.second)) { 147 FLASHD_LOGW("Copy %s failed!", GetFileName(iter.second).c_str()); 148 } 149 chmod((iter.second).c_str(), mode); 150 } 151} 152} // namespace Flashd