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 "flash_commander.h"
17
18 #include "datetime_ex.h"
19 #include "flashd_define.h"
20 #include "flashd_utils.h"
21 #include "fs_manager/mount.h"
22 #include "ptable_parse/ptable_manager.h"
23 #include "updater/updater.h"
24
25 namespace Flashd {
26 namespace {
27 constexpr size_t CMD_PARAM_COUNT_MIN = 2;
28 }
29
DoCommand(const std::string & cmmParam,size_t fileSize)30 void FlashCommander::DoCommand(const std::string &cmmParam, size_t fileSize)
31 {
32 FLASHD_LOGI("start to flash");
33 auto params = Split(cmmParam, { "-f" });
34 if (params.size() < CMD_PARAM_COUNT_MIN) {
35 FLASHD_LOGE("flash param count is %u, not invaild", params.size());
36 NotifyFail(CmdType::FLASH);
37 return;
38 }
39
40 fileSize_ = fileSize;
41 partName_ = params[0];
42 startTime_ = OHOS::GetMicroTickCount();
43
44 if (auto ret = Updater::MountForPath(GetPathRoot(FLASHD_FILE_PATH)); ret != 0) {
45 FLASHD_LOGE("MountForPath fail, ret = %d", ret);
46 NotifyFail(CmdType::FLASH);
47 return;
48 }
49
50 if (access(FLASHD_FILE_PATH, F_OK) == -1) {
51 mkdir(FLASHD_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
52 }
53 return;
54 }
55
DoCommand(const uint8_t * payload,int payloadSize)56 void FlashCommander::DoCommand(const uint8_t *payload, int payloadSize)
57 {
58 if (payload == nullptr || payloadSize <= 0) {
59 FLASHD_LOGE("payload is null or payloadSize is invaild");
60 NotifyFail(CmdType::FLASH);
61 return;
62 }
63
64 auto writeSize = DoFlash(payload, payloadSize);
65 if (writeSize < 0) {
66 NotifyFail(CmdType::FLASH);
67 return;
68 }
69
70 currentSize_ += static_cast<size_t>(writeSize);
71 if (currentSize_ >= fileSize_) {
72 auto useSec = static_cast<double>(OHOS::GetMicroTickCount() - startTime_) / OHOS::SEC_TO_MICROSEC;
73 FLASHD_LOGI("flash success, size = %u bytes, %.3lf s", fileSize_, useSec);
74 NotifySuccess(CmdType::FLASH);
75 return;
76 }
77 UpdateProgress(CmdType::FLASH);
78 }
79
InitPartition(const std::string & partName,const uint8_t * buffer,int bufferSize)80 bool FlashCommander::InitPartition(const std::string &partName, const uint8_t *buffer, int bufferSize)
81 {
82 #ifdef UPDATER_USE_PTABLE
83 DevicePtable::GetInstance().LoadPartitionInfo();
84 #endif
85 std::unique_ptr<FlashdWriter> writer = FlashdImageWriter::GetInstance().GetWriter(
86 partName, buffer, bufferSize);
87 if (writer == nullptr) {
88 FLASHD_LOGE("FlashdImageWriter GetWriter error");
89 return false;
90 }
91 partition_ = std::make_unique<Partition>(partName, std::move(writer));
92 return (partition_ == nullptr) ? false : true;
93 }
94
DoFlash(const uint8_t * payload,int payloadSize)95 int FlashCommander::DoFlash(const uint8_t *payload, int payloadSize)
96 {
97 if (partition_ == nullptr) {
98 if (!InitPartition(partName_, payload, payloadSize)) {
99 FLASHD_LOGE("DoFlash InitPartition fail");
100 return -1;
101 }
102 }
103
104 auto writeSize = std::min(static_cast<size_t>(payloadSize), fileSize_ - currentSize_);
105 if (writeSize <= 0) {
106 FLASHD_LOGW("all the data is written");
107 return 0;
108 }
109
110 if (partition_->DoFlash(payload, writeSize) != 0) {
111 FLASHD_LOGE("DoFlash fail");
112 return -1;
113 }
114 return writeSize;
115 }
116
PostCommand()117 void FlashCommander::PostCommand()
118 {
119 Updater::PostUpdater(false);
120 }
121 } // namespace Flashd