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 <ohos_types.h>
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
GetUpdaterResult(const std::vector<FirmwareComponent> & components,std::map<std::string,UpdateResult> & resultMap)41 UpdateResultCode FirmwareResultProcess::GetUpdaterResult(const std::vector<FirmwareComponent> &components,
42 std::map<std::string, UpdateResult> &resultMap)
43 {
44 FIRMWARE_LOGE("GetUpdaterResult");
45 if (components.empty()) {
46 FIRMWARE_LOGE("components is empty");
47 return UpdateResultCode::FAILURE;
48 }
49 resultMap.clear();
50 std::ifstream infile;
51 infile.open(UPDATER_RESULT_FILE, std::ios_base::in);
52 if (!infile.is_open()) {
53 FIRMWARE_LOGE("open update status file fail!");
54 HandleFileError(resultMap, components);
55 } else {
56 std::string buffer;
57 while (!infile.eof()) {
58 getline(infile, buffer);
59 ParseUpdaterResultRecord(buffer, resultMap);
60 }
61 infile.close();
62 }
63 return HandleFileResults(resultMap, components);
64 }
65
CompareVersion(const FirmwareComponent & component)66 UpdateResult FirmwareResultProcess::CompareVersion(const FirmwareComponent &component)
67 {
68 bool isResultSuccess = false;
69 isResultSuccess = component.versionNumber == FirmwareUpdateAdapter::GetDisplayVersion();
70 FIRMWARE_LOGI("component.versionNumber=%{pubilc}s, GetDisplayVersion=%{pubilc}s",
71 component.versionNumber.c_str(), FirmwareUpdateAdapter::GetDisplayVersion().c_str());
72 UpdateResult updateResult;
73 updateResult.spath = component.spath;
74 if (isResultSuccess) {
75 updateResult.result = UPDATER_RESULT_SUCCESS;
76 updateResult.reason = UPDATER_RESULT_SUCCESS_REASON;
77 } else {
78 updateResult.result = UPDATER_RESULT_FAILURE;
79 updateResult.reason = UPDATER_RESULT_FAILURE_REASON;
80 }
81 return updateResult;
82 }
83
84 /*
85 /data/update/ota_package/firmware/versions/0856210b1bf14427a0706aff1bdd4aed/updater.zip|pass
86 /data/update/ota_package/firmware/versions/1faa6ba19df044449ab8a10cb05bf1a6/updater.zip|
87 fail:;02:145768,41554,454656487,1463ac:-1
88 /data/update/ota_package/firmware/versions/971c50415d604c80a170f911993c2e2a/updater.zip
89 spath为 /data/update/ota_package/firmware/versions/52e700cdd0974ee79c721dad4a54f119/updater.zip
90 result为 pass或者fail 没有则为空
91 reason为 ;02:145768,41554,454656487,1463ac:-1 没有则为空
92 */
ParseUpdaterResultRecord(const std::string & resultLine,std::map<std::string,UpdateResult> & resultMap)93 void FirmwareResultProcess::ParseUpdaterResultRecord(const std::string &resultLine,
94 std::map<std::string, UpdateResult> &resultMap)
95 {
96 if (resultLine.empty()) {
97 FIRMWARE_LOGE("resultLine is null");
98 return;
99 }
100 UpdateResult updaterReason;
101 std::string::size_type verticalPlace = resultLine.find_first_of("|");
102 std::string resultAndReason;
103 if (verticalPlace == std::string::npos) {
104 updaterReason.spath = resultLine;
105 } else {
106 updaterReason.spath = resultLine.substr(0, verticalPlace);
107 resultAndReason = resultLine.substr(verticalPlace + SYMBOL_LENGTH);
108 }
109
110 std::string::size_type colonPlace = resultAndReason.find_first_of(":");
111 if (colonPlace == std::string::npos) {
112 updaterReason.result = resultAndReason;
113 } else {
114 updaterReason.result = resultAndReason.substr(0, colonPlace);
115 updaterReason.reason = resultAndReason.substr(colonPlace + SYMBOL_LENGTH);
116 }
117 StringUtils::Trim(updaterReason.spath);
118 StringUtils::Trim(updaterReason.result);
119 StringUtils::Trim(updaterReason.reason);
120 resultMap.emplace(std::make_pair(updaterReason.spath, updaterReason));
121 }
122
HandleFileError(std::map<std::string,UpdateResult> & resultMap,const std::vector<FirmwareComponent> & components)123 void FirmwareResultProcess::HandleFileError(std::map<std::string, UpdateResult> &resultMap,
124 const std::vector<FirmwareComponent> &components)
125 {
126 resultMap.clear();
127 for (const auto &component : components) {
128 UpdateResult updateResult = CompareVersion(component);
129 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
130 }
131 }
132
HandleFileResults(std::map<std::string,UpdateResult> & resultMap,const std::vector<FirmwareComponent> & components)133 UpdateResultCode FirmwareResultProcess::HandleFileResults(std::map<std::string, UpdateResult> &resultMap,
134 const std::vector<FirmwareComponent> &components)
135 {
136 FirmwareTask task;
137 FirmwareTaskOperator().QueryTask(task);
138 if (!task.isExistTask) {
139 FIRMWARE_LOGI("HandleFileResults has no task");
140 return UpdateResultCode::FAILURE;
141 }
142 uint32_t hotaUpdateResult = 0;
143 for (const auto &component : components) {
144 std::string updateResultStatus;
145 auto result = resultMap.find(component.spath);
146 if (result == resultMap.end()) {
147 UpdateResult updateResult = CompareVersion(component);
148 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
149 FIRMWARE_LOGE("spath %{public}s, result %{public}s", component.spath.c_str(), updateResult.result.c_str());
150 updateResultStatus = updateResult.result;
151 } else {
152 updateResultStatus = result->second.result;
153 }
154 hotaUpdateResult |= updateResultStatus == UPDATER_RESULT_SUCCESS ? UPDATE_SUCCESSED : UPDATE_FAILED;
155 }
156
157 if (task.combinationType == CombinationType::HOTA) {
158 return hotaUpdateResult == UPDATE_SUCCESSED ? UpdateResultCode::SUCCESS : UpdateResultCode::FAILURE;
159 }
160
161 if (hotaUpdateResult != UPDATE_SUCCESSED) {
162 return UpdateResultCode::FAILURE;
163 }
164 return UpdateResultCode::SUCCESS;
165 }
166 } // namespace UpdateEngine
167 } // namespace OHOS
168