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