• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "daemon_updater.h"
16 
17 #include "daemon_common.h"
18 #include "flashd_define.h"
19 #include "hdi/client/update_hdi_client.h"
20 #include "updater/updater.h"
21 #include "updater/updater_const.h"
22 using namespace std;
23 namespace Hdc {
24 namespace {
25 constexpr uint8_t PAYLOAD_FIX_RESERVER = 64;
26 }
27 
28 std::atomic<bool> DaemonUpdater::isRunning_ = false;
29 
DaemonUpdater(HTaskInfo hTaskInfo)30 DaemonUpdater::DaemonUpdater(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo)
31 {
32     commandBegin = CMD_UPDATER_BEGIN;
33     commandData = CMD_UPDATER_DATA;
34 }
35 
~DaemonUpdater()36 DaemonUpdater::~DaemonUpdater()
37 {
38     FLASHD_LOGI("~DaemonUpdater refCount %d", refCount);
39 }
40 
CommandDispatch(const uint16_t command,uint8_t * payload,const int payloadSize)41 bool DaemonUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize)
42 {
43     if (IsDeviceLocked()) {
44         std::string echo = "operation is not allowed";
45         vector<uint8_t> buffer;
46         buffer.push_back(command);
47         buffer.push_back(Hdc::MSG_FAIL);
48         buffer.insert(buffer.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size());
49         SendToAnother(Hdc::CMD_UPDATER_FINISH, buffer.data(), buffer.size());
50         FLASHD_LOGE("The devic is locked and operation is not allowed");
51         return false;
52     }
53 
54     if (!isInit_) {
55         Init();
56         isInit_ = true;
57     }
58 
59     auto iter = cmdFunc_.find(command);
60     if (iter == cmdFunc_.end()) {
61         FLASHD_LOGE("command is invalid, command = %d", command);
62         return false;
63     }
64     iter->second(payload, payloadSize);
65     return true;
66 }
67 
SendToHost(Flashd::CmdType type,Flashd::UpdaterState state,const std::string & msg)68 bool DaemonUpdater::SendToHost(Flashd::CmdType type, Flashd::UpdaterState state, const std::string &msg)
69 {
70     if (!DaemonUpdater::isRunning_) {
71         FLASHD_LOGW("flasd is not runing");
72         return true;
73     }
74 
75     if (state == Flashd::UpdaterState::DOING) {
76         uint32_t temp = 0;
77         std::stringstream percentageStream(msg);
78         if (!(percentageStream >> temp)) {
79             temp = 0;
80         }
81         uint8_t percentage = static_cast<uint8_t>(temp);
82         SendToAnother(Hdc::CMD_UPDATER_PROGRESS, &percentage, sizeof(percentage));
83         return true;
84     }
85 
86     if (state == Flashd::UpdaterState::FAIL || state == Flashd::UpdaterState::SUCCESS) {
87         uint8_t percentage = (state == Flashd::UpdaterState::SUCCESS) ? Flashd::PERCENT_FINISH : Flashd::PERCENT_CLEAR;
88         SendToAnother(Hdc::CMD_UPDATER_PROGRESS, &percentage, sizeof(percentage));
89 
90         std::string echo = Hdc::Base::ReplaceAll(msg, "\n", " ");
91         vector<uint8_t> buffer;
92         buffer.push_back(static_cast<uint8_t>(type));
93         buffer.push_back((state == Flashd::UpdaterState::SUCCESS) ? Hdc::MSG_OK : Hdc::MSG_FAIL);
94         buffer.insert(buffer.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size());
95         SendToAnother(Hdc::CMD_UPDATER_FINISH, buffer.data(), buffer.size());
96         TaskFinish();
97         if (commander_ != nullptr) {
98             commander_->PostCommand();
99         }
100         DaemonUpdater::isRunning_ = false;
101     }
102     return true;
103 }
104 
CreateCommander(const std::string & cmd)105 std::unique_ptr<Flashd::Commander> DaemonUpdater::CreateCommander(const std::string &cmd)
106 {
107     if (DaemonUpdater::isRunning_) {
108         FLASHD_LOGE("flashd has been running");
109         return nullptr;
110     }
111     DaemonUpdater::isRunning_ = true;
112     auto callback = [this](Flashd::CmdType type, Flashd::UpdaterState state, const std::string &msg) {
113         SendToHost(type, state, msg);
114     };
115     return Flashd::CommanderFactory::GetInstance().CreateCommander(cmd, callback);
116 }
117 
CheckCommand(const uint8_t * payload,int payloadSize)118 void DaemonUpdater::CheckCommand(const uint8_t *payload, int payloadSize)
119 {
120     if (payloadSize < static_cast<int>(sizeof(int64_t))) {
121         FLASHD_LOGE("payloadSize is invalid");
122         return;
123     }
124 
125     string bufString(reinterpret_cast<const char *>(payload + sizeof(int64_t)), payloadSize - sizeof(int64_t));
126     SerialStruct::ParseFromString(ctxNow.transferConfig, bufString);
127 
128     ctxNow.master = false;
129     ctxNow.fsOpenReq.data = &ctxNow;
130     ctxNow.fileSize = ctxNow.transferConfig.fileSize;
131 
132     FLASHD_LOGI("functionName = %s, options = %s, fileSize = %u", ctxNow.transferConfig.functionName.c_str(),
133         ctxNow.transferConfig.options.c_str(), ctxNow.transferConfig.fileSize);
134 
135     commander_ = CreateCommander(ctxNow.transferConfig.functionName.c_str());
136     if (commander_ == nullptr) {
137         FLASHD_LOGE("commander_ is null for cmd = %s", ctxNow.transferConfig.functionName.c_str());
138         return;
139     }
140     commander_->DoCommand(ctxNow.transferConfig.options, ctxNow.transferConfig.fileSize);
141 
142     SendToAnother(commandBegin, nullptr, 0);
143     refCount++;
144 }
145 
DataCommand(const uint8_t * payload,int payloadSize) const146 void DaemonUpdater::DataCommand(const uint8_t *payload, int payloadSize) const
147 {
148     if (commander_ == nullptr) {
149         FLASHD_LOGE("commander_ is null");
150         return;
151     }
152 
153     if (payloadSize <= PAYLOAD_FIX_RESERVER) {
154         FLASHD_LOGE("payloadSize is invaild");
155         return;
156     }
157 
158     string serialStrring(reinterpret_cast<const char *>(payload), PAYLOAD_FIX_RESERVER);
159     TransferPayload pld = {};
160     SerialStruct::ParseFromString(pld, serialStrring);
161     commander_->DoCommand(payload + PAYLOAD_FIX_RESERVER, pld.uncompressSize);
162 }
163 
EraseCommand(const uint8_t * payload,int payloadSize)164 void DaemonUpdater::EraseCommand(const uint8_t *payload, int payloadSize)
165 {
166     commander_ = CreateCommander(CMDSTR_ERASE_PARTITION);
167     if (commander_ == nullptr) {
168         FLASHD_LOGE("commander_ is null for cmd = %s", CMDSTR_ERASE_PARTITION);
169         return;
170     }
171     commander_->DoCommand(payload, payloadSize);
172 }
173 
FormatCommand(const uint8_t * payload,int payloadSize)174 void DaemonUpdater::FormatCommand(const uint8_t *payload, int payloadSize)
175 {
176     commander_ = CreateCommander(CMDSTR_FORMAT_PARTITION);
177     if (commander_ == nullptr) {
178         FLASHD_LOGE("commander_ is null for cmd = %s", CMDSTR_FORMAT_PARTITION);
179         return;
180     }
181     commander_->DoCommand(payload, payloadSize);
182 }
183 
Init()184 void DaemonUpdater::Init()
185 {
186     cmdFunc_.emplace(CMD_UPDATER_CHECK, bind(&DaemonUpdater::CheckCommand, this, placeholders::_1, placeholders::_2));
187     cmdFunc_.emplace(CMD_UPDATER_DATA, bind(&DaemonUpdater::DataCommand, this, placeholders::_1, placeholders::_2));
188     cmdFunc_.emplace(CMD_UPDATER_ERASE, bind(&DaemonUpdater::EraseCommand, this, placeholders::_1, placeholders::_2));
189     cmdFunc_.emplace(CMD_UPDATER_FORMAT, bind(&DaemonUpdater::FormatCommand, this, placeholders::_1, placeholders::_2));
190 }
191 
IsDeviceLocked() const192 bool DaemonUpdater::IsDeviceLocked() const
193 {
194     bool isLocked = true;
195     if (auto ret = Updater::UpdateHdiClient::GetInstance().GetLockStatus(isLocked); ret != 0) {
196         FLASHD_LOGE("GetLockStatus fail, ret = %d", ret);
197         return true;
198     }
199     return isLocked;
200 }
201 } // namespace Hdc