1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci#include "daemon_updater.h" 16fb299fa2Sopenharmony_ci 17fb299fa2Sopenharmony_ci#include "daemon_common.h" 18fb299fa2Sopenharmony_ci#include "flashd_define.h" 19fb299fa2Sopenharmony_ci#include "hdi/client/update_hdi_client.h" 20fb299fa2Sopenharmony_ci#include "updater/updater.h" 21fb299fa2Sopenharmony_ci#include "updater/updater_const.h" 22fb299fa2Sopenharmony_ciusing namespace std; 23fb299fa2Sopenharmony_cinamespace Hdc { 24fb299fa2Sopenharmony_cinamespace { 25fb299fa2Sopenharmony_ciconstexpr uint8_t PAYLOAD_FIX_RESERVER = 64; 26fb299fa2Sopenharmony_ci} 27fb299fa2Sopenharmony_ci 28fb299fa2Sopenharmony_cistd::atomic<bool> DaemonUpdater::isRunning_ = false; 29fb299fa2Sopenharmony_ci 30fb299fa2Sopenharmony_ciDaemonUpdater::DaemonUpdater(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) 31fb299fa2Sopenharmony_ci{ 32fb299fa2Sopenharmony_ci commandBegin = CMD_UPDATER_BEGIN; 33fb299fa2Sopenharmony_ci commandData = CMD_UPDATER_DATA; 34fb299fa2Sopenharmony_ci} 35fb299fa2Sopenharmony_ci 36fb299fa2Sopenharmony_ciDaemonUpdater::~DaemonUpdater() 37fb299fa2Sopenharmony_ci{ 38fb299fa2Sopenharmony_ci FLASHD_LOGI("~DaemonUpdater refCount %d", refCount); 39fb299fa2Sopenharmony_ci} 40fb299fa2Sopenharmony_ci 41fb299fa2Sopenharmony_cibool DaemonUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) 42fb299fa2Sopenharmony_ci{ 43fb299fa2Sopenharmony_ci if (IsDeviceLocked()) { 44fb299fa2Sopenharmony_ci std::string echo = "operation is not allowed"; 45fb299fa2Sopenharmony_ci vector<uint8_t> buffer; 46fb299fa2Sopenharmony_ci buffer.push_back(command); 47fb299fa2Sopenharmony_ci buffer.push_back(Hdc::MSG_FAIL); 48fb299fa2Sopenharmony_ci buffer.insert(buffer.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size()); 49fb299fa2Sopenharmony_ci SendToAnother(Hdc::CMD_UPDATER_FINISH, buffer.data(), buffer.size()); 50fb299fa2Sopenharmony_ci FLASHD_LOGE("The devic is locked and operation is not allowed"); 51fb299fa2Sopenharmony_ci return false; 52fb299fa2Sopenharmony_ci } 53fb299fa2Sopenharmony_ci 54fb299fa2Sopenharmony_ci if (!isInit_) { 55fb299fa2Sopenharmony_ci Init(); 56fb299fa2Sopenharmony_ci isInit_ = true; 57fb299fa2Sopenharmony_ci } 58fb299fa2Sopenharmony_ci 59fb299fa2Sopenharmony_ci auto iter = cmdFunc_.find(command); 60fb299fa2Sopenharmony_ci if (iter == cmdFunc_.end()) { 61fb299fa2Sopenharmony_ci FLASHD_LOGE("command is invalid, command = %d", command); 62fb299fa2Sopenharmony_ci return false; 63fb299fa2Sopenharmony_ci } 64fb299fa2Sopenharmony_ci iter->second(payload, payloadSize); 65fb299fa2Sopenharmony_ci return true; 66fb299fa2Sopenharmony_ci} 67fb299fa2Sopenharmony_ci 68fb299fa2Sopenharmony_cibool DaemonUpdater::SendToHost(Flashd::CmdType type, Flashd::UpdaterState state, const std::string &msg) 69fb299fa2Sopenharmony_ci{ 70fb299fa2Sopenharmony_ci if (!DaemonUpdater::isRunning_) { 71fb299fa2Sopenharmony_ci FLASHD_LOGW("flasd is not runing"); 72fb299fa2Sopenharmony_ci return true; 73fb299fa2Sopenharmony_ci } 74fb299fa2Sopenharmony_ci 75fb299fa2Sopenharmony_ci if (state == Flashd::UpdaterState::DOING) { 76fb299fa2Sopenharmony_ci uint32_t temp = 0; 77fb299fa2Sopenharmony_ci std::stringstream percentageStream(msg); 78fb299fa2Sopenharmony_ci if (!(percentageStream >> temp)) { 79fb299fa2Sopenharmony_ci temp = 0; 80fb299fa2Sopenharmony_ci } 81fb299fa2Sopenharmony_ci uint8_t percentage = static_cast<uint8_t>(temp); 82fb299fa2Sopenharmony_ci SendToAnother(Hdc::CMD_UPDATER_PROGRESS, &percentage, sizeof(percentage)); 83fb299fa2Sopenharmony_ci return true; 84fb299fa2Sopenharmony_ci } 85fb299fa2Sopenharmony_ci 86fb299fa2Sopenharmony_ci if (state == Flashd::UpdaterState::FAIL || state == Flashd::UpdaterState::SUCCESS) { 87fb299fa2Sopenharmony_ci uint8_t percentage = (state == Flashd::UpdaterState::SUCCESS) ? Flashd::PERCENT_FINISH : Flashd::PERCENT_CLEAR; 88fb299fa2Sopenharmony_ci SendToAnother(Hdc::CMD_UPDATER_PROGRESS, &percentage, sizeof(percentage)); 89fb299fa2Sopenharmony_ci 90fb299fa2Sopenharmony_ci std::string echo = Hdc::Base::ReplaceAll(msg, "\n", " "); 91fb299fa2Sopenharmony_ci vector<uint8_t> buffer; 92fb299fa2Sopenharmony_ci buffer.push_back(static_cast<uint8_t>(type)); 93fb299fa2Sopenharmony_ci buffer.push_back((state == Flashd::UpdaterState::SUCCESS) ? Hdc::MSG_OK : Hdc::MSG_FAIL); 94fb299fa2Sopenharmony_ci buffer.insert(buffer.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size()); 95fb299fa2Sopenharmony_ci SendToAnother(Hdc::CMD_UPDATER_FINISH, buffer.data(), buffer.size()); 96fb299fa2Sopenharmony_ci TaskFinish(); 97fb299fa2Sopenharmony_ci if (commander_ != nullptr) { 98fb299fa2Sopenharmony_ci commander_->PostCommand(); 99fb299fa2Sopenharmony_ci } 100fb299fa2Sopenharmony_ci DaemonUpdater::isRunning_ = false; 101fb299fa2Sopenharmony_ci } 102fb299fa2Sopenharmony_ci return true; 103fb299fa2Sopenharmony_ci} 104fb299fa2Sopenharmony_ci 105fb299fa2Sopenharmony_cistd::unique_ptr<Flashd::Commander> DaemonUpdater::CreateCommander(const std::string &cmd) 106fb299fa2Sopenharmony_ci{ 107fb299fa2Sopenharmony_ci if (DaemonUpdater::isRunning_) { 108fb299fa2Sopenharmony_ci FLASHD_LOGE("flashd has been running"); 109fb299fa2Sopenharmony_ci return nullptr; 110fb299fa2Sopenharmony_ci } 111fb299fa2Sopenharmony_ci DaemonUpdater::isRunning_ = true; 112fb299fa2Sopenharmony_ci auto callback = [this](Flashd::CmdType type, Flashd::UpdaterState state, const std::string &msg) { 113fb299fa2Sopenharmony_ci SendToHost(type, state, msg); 114fb299fa2Sopenharmony_ci }; 115fb299fa2Sopenharmony_ci return Flashd::CommanderFactory::GetInstance().CreateCommander(cmd, callback); 116fb299fa2Sopenharmony_ci} 117fb299fa2Sopenharmony_ci 118fb299fa2Sopenharmony_civoid DaemonUpdater::CheckCommand(const uint8_t *payload, int payloadSize) 119fb299fa2Sopenharmony_ci{ 120fb299fa2Sopenharmony_ci if (payloadSize < static_cast<int>(sizeof(int64_t))) { 121fb299fa2Sopenharmony_ci FLASHD_LOGE("payloadSize is invalid"); 122fb299fa2Sopenharmony_ci return; 123fb299fa2Sopenharmony_ci } 124fb299fa2Sopenharmony_ci 125fb299fa2Sopenharmony_ci string bufString(reinterpret_cast<const char *>(payload + sizeof(int64_t)), payloadSize - sizeof(int64_t)); 126fb299fa2Sopenharmony_ci SerialStruct::ParseFromString(ctxNow.transferConfig, bufString); 127fb299fa2Sopenharmony_ci 128fb299fa2Sopenharmony_ci ctxNow.master = false; 129fb299fa2Sopenharmony_ci ctxNow.fsOpenReq.data = &ctxNow; 130fb299fa2Sopenharmony_ci ctxNow.fileSize = ctxNow.transferConfig.fileSize; 131fb299fa2Sopenharmony_ci 132fb299fa2Sopenharmony_ci FLASHD_LOGI("functionName = %s, options = %s, fileSize = %u", ctxNow.transferConfig.functionName.c_str(), 133fb299fa2Sopenharmony_ci ctxNow.transferConfig.options.c_str(), ctxNow.transferConfig.fileSize); 134fb299fa2Sopenharmony_ci 135fb299fa2Sopenharmony_ci commander_ = CreateCommander(ctxNow.transferConfig.functionName.c_str()); 136fb299fa2Sopenharmony_ci if (commander_ == nullptr) { 137fb299fa2Sopenharmony_ci FLASHD_LOGE("commander_ is null for cmd = %s", ctxNow.transferConfig.functionName.c_str()); 138fb299fa2Sopenharmony_ci return; 139fb299fa2Sopenharmony_ci } 140fb299fa2Sopenharmony_ci commander_->DoCommand(ctxNow.transferConfig.options, ctxNow.transferConfig.fileSize); 141fb299fa2Sopenharmony_ci 142fb299fa2Sopenharmony_ci SendToAnother(commandBegin, nullptr, 0); 143fb299fa2Sopenharmony_ci refCount++; 144fb299fa2Sopenharmony_ci} 145fb299fa2Sopenharmony_ci 146fb299fa2Sopenharmony_civoid DaemonUpdater::DataCommand(const uint8_t *payload, int payloadSize) const 147fb299fa2Sopenharmony_ci{ 148fb299fa2Sopenharmony_ci if (commander_ == nullptr) { 149fb299fa2Sopenharmony_ci FLASHD_LOGE("commander_ is null"); 150fb299fa2Sopenharmony_ci return; 151fb299fa2Sopenharmony_ci } 152fb299fa2Sopenharmony_ci 153fb299fa2Sopenharmony_ci if (payloadSize <= PAYLOAD_FIX_RESERVER) { 154fb299fa2Sopenharmony_ci FLASHD_LOGE("payloadSize is invaild"); 155fb299fa2Sopenharmony_ci return; 156fb299fa2Sopenharmony_ci } 157fb299fa2Sopenharmony_ci 158fb299fa2Sopenharmony_ci string serialStrring(reinterpret_cast<const char *>(payload), PAYLOAD_FIX_RESERVER); 159fb299fa2Sopenharmony_ci TransferPayload pld = {}; 160fb299fa2Sopenharmony_ci SerialStruct::ParseFromString(pld, serialStrring); 161fb299fa2Sopenharmony_ci commander_->DoCommand(payload + PAYLOAD_FIX_RESERVER, pld.uncompressSize); 162fb299fa2Sopenharmony_ci} 163fb299fa2Sopenharmony_ci 164fb299fa2Sopenharmony_civoid DaemonUpdater::EraseCommand(const uint8_t *payload, int payloadSize) 165fb299fa2Sopenharmony_ci{ 166fb299fa2Sopenharmony_ci commander_ = CreateCommander(CMDSTR_ERASE_PARTITION); 167fb299fa2Sopenharmony_ci if (commander_ == nullptr) { 168fb299fa2Sopenharmony_ci FLASHD_LOGE("commander_ is null for cmd = %s", CMDSTR_ERASE_PARTITION); 169fb299fa2Sopenharmony_ci return; 170fb299fa2Sopenharmony_ci } 171fb299fa2Sopenharmony_ci commander_->DoCommand(payload, payloadSize); 172fb299fa2Sopenharmony_ci} 173fb299fa2Sopenharmony_ci 174fb299fa2Sopenharmony_civoid DaemonUpdater::FormatCommand(const uint8_t *payload, int payloadSize) 175fb299fa2Sopenharmony_ci{ 176fb299fa2Sopenharmony_ci commander_ = CreateCommander(CMDSTR_FORMAT_PARTITION); 177fb299fa2Sopenharmony_ci if (commander_ == nullptr) { 178fb299fa2Sopenharmony_ci FLASHD_LOGE("commander_ is null for cmd = %s", CMDSTR_FORMAT_PARTITION); 179fb299fa2Sopenharmony_ci return; 180fb299fa2Sopenharmony_ci } 181fb299fa2Sopenharmony_ci commander_->DoCommand(payload, payloadSize); 182fb299fa2Sopenharmony_ci} 183fb299fa2Sopenharmony_ci 184fb299fa2Sopenharmony_civoid DaemonUpdater::Init() 185fb299fa2Sopenharmony_ci{ 186fb299fa2Sopenharmony_ci cmdFunc_.emplace(CMD_UPDATER_CHECK, bind(&DaemonUpdater::CheckCommand, this, placeholders::_1, placeholders::_2)); 187fb299fa2Sopenharmony_ci cmdFunc_.emplace(CMD_UPDATER_DATA, bind(&DaemonUpdater::DataCommand, this, placeholders::_1, placeholders::_2)); 188fb299fa2Sopenharmony_ci cmdFunc_.emplace(CMD_UPDATER_ERASE, bind(&DaemonUpdater::EraseCommand, this, placeholders::_1, placeholders::_2)); 189fb299fa2Sopenharmony_ci cmdFunc_.emplace(CMD_UPDATER_FORMAT, bind(&DaemonUpdater::FormatCommand, this, placeholders::_1, placeholders::_2)); 190fb299fa2Sopenharmony_ci} 191fb299fa2Sopenharmony_ci 192fb299fa2Sopenharmony_cibool DaemonUpdater::IsDeviceLocked() const 193fb299fa2Sopenharmony_ci{ 194fb299fa2Sopenharmony_ci bool isLocked = true; 195fb299fa2Sopenharmony_ci if (auto ret = Updater::UpdateHdiClient::GetInstance().GetLockStatus(isLocked); ret != 0) { 196fb299fa2Sopenharmony_ci FLASHD_LOGE("GetLockStatus fail, ret = %d", ret); 197fb299fa2Sopenharmony_ci return true; 198fb299fa2Sopenharmony_ci } 199fb299fa2Sopenharmony_ci return isLocked; 200fb299fa2Sopenharmony_ci} 201fb299fa2Sopenharmony_ci 202fb299fa2Sopenharmony_ciInvalidDaemon::InvalidDaemon(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) 203fb299fa2Sopenharmony_ci{ 204fb299fa2Sopenharmony_ci FLASHD_LOGI("InvalidDaemon init"); 205fb299fa2Sopenharmony_ci} 206fb299fa2Sopenharmony_ci 207fb299fa2Sopenharmony_ciInvalidDaemon::~InvalidDaemon() 208fb299fa2Sopenharmony_ci{ 209fb299fa2Sopenharmony_ci FLASHD_LOGI("~InvalidDaemon refCount %d", refCount); 210fb299fa2Sopenharmony_ci} 211fb299fa2Sopenharmony_ci 212fb299fa2Sopenharmony_cibool InvalidDaemon::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) 213fb299fa2Sopenharmony_ci{ 214fb299fa2Sopenharmony_ci std::string echo = "operation is not allowed"; 215fb299fa2Sopenharmony_ci vector<uint8_t> buffer; 216fb299fa2Sopenharmony_ci buffer.push_back(command); 217fb299fa2Sopenharmony_ci buffer.push_back(Hdc::MSG_FAIL); 218fb299fa2Sopenharmony_ci buffer.insert(buffer.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size()); 219fb299fa2Sopenharmony_ci LogMsg(MSG_FAIL, "Operation is not allowed"); 220fb299fa2Sopenharmony_ci TaskFinish(); 221fb299fa2Sopenharmony_ci FLASHD_LOGE("The operation is not allowed"); 222fb299fa2Sopenharmony_ci return false; 223fb299fa2Sopenharmony_ci} 224fb299fa2Sopenharmony_ci} // namespace Hdc