1 /*
2 * Copyright (c) 2023 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 "firmware_result_process.h"
17
18 #include <fstream>
19 #include <iostream>
20 #include <map>
21 #include <sstream>
22 #include <string>
23 #include <unistd.h>
24
25 #include "string_utils.h"
26 #include "firmware_callback_utils.h"
27 #include "firmware_common.h"
28 #include "firmware_preferences_utils.h"
29 #include "firmware_task.h"
30 #include "firmware_task_operator.h"
31 #include "firmware_update_adapter.h"
32 #include "firmware_update_helper.h"
33
34 namespace OHOS {
35 namespace UpdateEngine {
36 static const std::string UPDATER_RESULT_FILE = "/data/updater/updater_result";
37 constexpr int32_t SYMBOL_LENGTH = 1;
38 constexpr uint32_t UPDATE_SUCCESSED = 1;
39 constexpr uint32_t UPDATE_FAILED = 2;
40 constexpr size_t PKG_PATH_INDEX = 0;
41 constexpr size_t RESULT_INDEX = 1;
42 constexpr size_t REASON_INDEX = 2;
43
ParseResult(const std::vector<std::string> & results,std::string & value,size_t index)44 void FirmwareResultProcess::ParseResult(const std::vector<std::string> &results, std::string &value, size_t index)
45 {
46 if (index >= results.size()) {
47 return;
48 }
49 value = results[index];
50 StringUtils::Trim(value);
51 }
52
GetUpdaterResult(const std::vector<FirmwareComponent> & components,std::map<std::string,UpdateResult> & resultMap)53 UpdateResultCode FirmwareResultProcess::GetUpdaterResult(const std::vector<FirmwareComponent> &components,
54 std::map<std::string, UpdateResult> &resultMap)
55 {
56 FIRMWARE_LOGE("GetUpdaterResult");
57 if (components.empty()) {
58 FIRMWARE_LOGE("components is empty");
59 return UpdateResultCode::FAILURE;
60 }
61 resultMap.clear();
62 std::ifstream infile;
63 infile.open(UPDATER_RESULT_FILE, std::ios_base::in);
64 if (!infile.is_open()) {
65 FIRMWARE_LOGE("open update status file fail!");
66 HandleFileError(resultMap, components);
67 } else {
68 std::string buffer;
69 while (!infile.eof()) {
70 getline(infile, buffer);
71 ParseUpdaterResultRecord(buffer, resultMap);
72 }
73 infile.close();
74 }
75 return HandleFileResults(resultMap, components);
76 }
77
CompareVersion(const FirmwareComponent & component)78 UpdateResult FirmwareResultProcess::CompareVersion(const FirmwareComponent &component)
79 {
80 bool isResultSuccess = false;
81 isResultSuccess = component.versionNumber == FirmwareUpdateAdapter::GetDisplayVersion();
82 FIRMWARE_LOGI("component.versionNumber=%{pubilc}s, GetDisplayVersion=%{pubilc}s",
83 component.versionNumber.c_str(), FirmwareUpdateAdapter::GetDisplayVersion().c_str());
84 UpdateResult updateResult;
85 updateResult.spath = component.spath;
86 if (isResultSuccess) {
87 updateResult.result = UPDATER_RESULT_SUCCESS;
88 updateResult.reason = UPDATER_RESULT_SUCCESS_REASON;
89 } else {
90 updateResult.result = UPDATER_RESULT_FAILURE;
91 updateResult.reason = UPDATER_RESULT_FAILURE_REASON;
92 }
93 return updateResult;
94 }
95
96 /*
97 /data/update/ota_package/firmware/versions/0856210b1bf14427a0706aff1bdd4aed/updater.zip|pass
98 /data/update/ota_package/firmware/versions/1faa6ba19df044449ab8a10cb05bf1a6/updater.zip|
99 fail:;02:145768,41554,454656487,1463ac:-1
100 /data/update/ota_package/firmware/versions/971c50415d604c80a170f911993c2e2a/updater.zip
101 spath为 /data/update/ota_package/firmware/versions/52e700cdd0974ee79c721dad4a54f119/updater.zip
102 result为 pass或者fail 没有则为空
103 reason为 ;02:145768,41554,454656487,1463ac:-1 没有则为空
104 */
ParseUpdaterResultRecord(const std::string & resultLine,std::map<std::string,UpdateResult> & resultMap)105 void FirmwareResultProcess::ParseUpdaterResultRecord(const std::string &resultLine,
106 std::map<std::string, UpdateResult> &resultMap)
107 {
108 FIRMWARE_LOGE("ParseUpdaterResultRecord");
109 if (resultLine.empty()) {
110 FIRMWARE_LOGE("resultLine is null");
111 return;
112 }
113 UpdateResult updateResult;
114 std::vector<std::string> results;
115 std::stringstream stringStream(resultLine);
116 std::string token;
117 while (std::getline(stringStream, token, '|')) {
118 results.push_back(token);
119 }
120
121 ParseResult(results, updateResult.spath, PKG_PATH_INDEX);
122 ParseResult(results, updateResult.result, RESULT_INDEX);
123 ParseResult(results, updateResult.reason, REASON_INDEX);
124
125 auto colonPlace = updateResult.result.find_first_of(":");
126 if (colonPlace != std::string::npos) {
127 updateResult.result = updateResult.result.substr(0, colonPlace);
128 updateResult.reason = results[RESULT_INDEX].substr(colonPlace + SYMBOL_LENGTH);
129 }
130 StringUtils::Trim(updateResult.spath);
131 StringUtils::Trim(updateResult.result);
132 StringUtils::Trim(updateResult.reason);
133 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
134 }
135
HandleFileError(std::map<std::string,UpdateResult> & resultMap,const std::vector<FirmwareComponent> & components)136 void FirmwareResultProcess::HandleFileError(std::map<std::string, UpdateResult> &resultMap,
137 const std::vector<FirmwareComponent> &components)
138 {
139 resultMap.clear();
140 for (const auto &component : components) {
141 UpdateResult updateResult = CompareVersion(component);
142 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
143 }
144 }
145
HandleFileResults(std::map<std::string,UpdateResult> & resultMap,const std::vector<FirmwareComponent> & components)146 UpdateResultCode FirmwareResultProcess::HandleFileResults(std::map<std::string, UpdateResult> &resultMap,
147 const std::vector<FirmwareComponent> &components)
148 {
149 FirmwareTask task;
150 FirmwareTaskOperator().QueryTask(task);
151 if (!task.isExistTask) {
152 FIRMWARE_LOGI("HandleFileResults has no task");
153 return UpdateResultCode::FAILURE;
154 }
155 uint32_t hotaUpdateResult = 0;
156 for (const auto &component : components) {
157 std::string updateResultStatus;
158 auto result = resultMap.find(component.spath);
159 if (result == resultMap.end()) {
160 UpdateResult updateResult = CompareVersion(component);
161 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
162 FIRMWARE_LOGE("spath %{public}s, result %{public}s", component.spath.c_str(), updateResult.result.c_str());
163 updateResultStatus = updateResult.result;
164 } else {
165 updateResultStatus = result->second.result;
166 }
167 hotaUpdateResult |= updateResultStatus == UPDATER_RESULT_SUCCESS ? UPDATE_SUCCESSED : UPDATE_FAILED;
168 }
169
170 if (task.combinationType == CombinationType::HOTA) {
171 return hotaUpdateResult == UPDATE_SUCCESSED ? UpdateResultCode::SUCCESS : UpdateResultCode::FAILURE;
172 }
173
174 if (hotaUpdateResult != UPDATE_SUCCESSED) {
175 return UpdateResultCode::FAILURE;
176 }
177 return UpdateResultCode::SUCCESS;
178 }
179 } // namespace UpdateEngine
180 } // namespace OHOS
181