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