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_check_analyze_utils.h"
17
18 #include <cinttypes>
19 #include <iostream>
20 #include <memory>
21 #include <map>
22 #include <string>
23
24 #include "constant.h"
25 #include "dupdate_json_utils.h"
26 #include "file_utils.h"
27 #include "firmware_combine_version_utils.h"
28 #include "firmware_constant.h"
29 #include "firmware_log.h"
30 #include "firmware_preferences_utils.h"
31 #include "string_utils.h"
32
33 namespace OHOS {
34 namespace UpdateEngine {
DoAnalyze(const std::string & rawJson,std::vector<FirmwareComponent> & components,Duration & duration,CheckAndAuthInfo & checkAndAuthInfo)35 void FirmwareCheckAnalyzeUtils::DoAnalyze(const std::string &rawJson, std::vector<FirmwareComponent> &components,
36 Duration &duration, CheckAndAuthInfo &checkAndAuthInfo)
37 {
38 BlCheckResponse response;
39 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
40 nlohmann::json root;
41 if (!JsonUtils::ParseAndGetJsonObject(rawJson, root)) {
42 FIRMWARE_LOGE("fail to parse out a json object");
43 return;
44 }
45
46 int32_t status = CAST_INT(CheckResultStatus::STATUS_SYSTEM_ERROR);
47 JsonUtils::GetValueAndSetTo(root, "searchStatus", status);
48
49 checkAndAuthInfo.responseStatus = std::to_string(status);
50 if (!IsLegalStatus(status)) {
51 FIRMWARE_LOGI("not found new version!");
52 return;
53 }
54 if (status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE)) {
55 ret += AnalyzeBlVersionCheckResults(root, response);
56 ret += AnalyzeComponents(root);
57 }
58
59 // 解析的都是必须字段,全部解析正常,才能给component赋值
60 if (ret == CAST_INT(JsonParseError::ERR_OK)) {
61 components = components_;
62 }
63 }
64
AnalyzeBlVersionCheckResults(nlohmann::json & root,BlCheckResponse & response)65 int32_t FirmwareCheckAnalyzeUtils::AnalyzeBlVersionCheckResults(nlohmann::json &root, BlCheckResponse &response)
66 {
67 if (root.find("checkResults") == root.end()) {
68 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeBlVersionCheckResults no key checkResults");
69 return CAST_INT(JsonParseError::MISSING_PROP);
70 }
71 FIRMWARE_LOGI("checkResults size is %{public}" PRIu64 "", static_cast<uint64_t>(root["checkResults"].size()));
72 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
73 for (auto &result : root["checkResults"]) {
74 int32_t status = CAST_INT(CheckResultStatus::STATUS_SYSTEM_ERROR);
75 JsonUtils::GetValueAndSetTo(root, "searchStatus", status);
76 if (status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE)) {
77 BlVersionCheckResult checkResult;
78 ret += JsonUtils::GetValueAndSetTo(result, "descriptPackageId", checkResult.descriptPackageId);
79 checkResult.blVersionType = 1;
80 checkResult.status = std::to_string(status);
81 UpdatePackage package;
82 package.versionId = "1";
83 int32_t versionPackageType = CAST_INT(PackageType::DYNAMIC);
84 ret += JsonUtils::GetValueAndSetTo(result, "packageType", versionPackageType);
85 package.versionPackageType = static_cast<PackageType>(versionPackageType);
86 package.packageIndex = 0;
87 checkResult.updatePackages.push_back(package);
88 TargetBlComponent component;
89 component.versionPackageType = package.versionPackageType;
90 ret += JsonUtils::GetValueAndSetTo(result, "versionName", component.displayVersionNumber);
91 ret += JsonUtils::GetValueAndSetTo(result, "versionName", component.versionNumber);
92 checkResult.targetBlComponents.push_back(component);
93 checkResult.blVersionInfo = result["blVersionInfo"].dump();
94 response.blVersionCheckResults.push_back(checkResult);
95 Version version;
96 version.versionId = "1";
97 ret += JsonUtils::GetValueAndSetTo(result, "versionCode", version.versionNumber);
98 ret += JsonUtils::GetValueAndSetTo(result, "url", version.url);
99 response.versionList.push_back(version);
100 }
101 }
102 return ret;
103 }
104
AnalyzeComponents(nlohmann::json & root)105 int32_t FirmwareCheckAnalyzeUtils::AnalyzeComponents(nlohmann::json &root)
106 {
107 // 检查 "checkResults" 是否存在
108 if (root.find("checkResults") == root.end()) {
109 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key checkResults");
110 return CAST_INT(JsonParseError::MISSING_PROP);
111 }
112 FIRMWARE_LOGI("checkResults size is %{public}" PRIu64 "", static_cast<uint64_t>(root["checkResults"].size()));
113
114 // 初始化返回值
115 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
116
117 // 处理 "checkResults" 部分
118 ret += ProcessCheckResults(root["checkResults"]);
119
120 // 检查 "descriptInfo" 是否存在
121 if (root.find("descriptInfo") == root.end()) {
122 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key descriptInfo");
123 return CAST_INT(JsonParseError::MISSING_PROP);
124 }
125
126 // 处理 "descriptInfo" 部分
127 ret += ProcessDescriptInfo(root["descriptInfo"]);
128
129 return ret;
130 }
131
ProcessCheckResults(const nlohmann::json & checkResults)132 int32_t FirmwareCheckAnalyzeUtils::ProcessCheckResults(const nlohmann::json &checkResults)
133 {
134 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
135 std::string componentId;
136
137 for (auto &result : checkResults) {
138 FirmwareComponent component;
139 int32_t componetSize = 0;
140
141 // 获取组件相关属性
142 ret += JsonUtils::GetValueAndSetTo(result, "descriptPackageId", component.descriptPackageId);
143 ret += JsonUtils::GetValueAndSetTo(result, "url", component.url);
144 ret += JsonUtils::GetValueAndSetTo(result, "size", componetSize);
145 component.size = static_cast<int64_t>(componetSize);
146 component.fileName = StringUtils::GetLastSplitString(component.url, "/");
147 ret += JsonUtils::GetValueAndSetTo(result, "verifyInfo", component.verifyInfo);
148 ret += JsonUtils::GetValueAndSetTo(result, "versionCode", component.versionNumber);
149 ret += JsonUtils::GetValueAndSetTo(result, "versionName", component.targetBlVersionNumber);
150
151 int32_t versionPackageType = CAST_INT(PackageType::DYNAMIC);
152 ret += JsonUtils::GetValueAndSetTo(result, "packageType", versionPackageType);
153 component.versionPackageType = static_cast<PackageType>(versionPackageType);
154
155 int32_t otaType = CAST_INT(OtaType::REGULAR);
156 ret += JsonUtils::GetValueAndSetTo(result, "otaType", otaType);
157 component.otaType = static_cast<OtaType>(otaType);
158
159 component.targetBlDisplayVersionNumber = component.targetBlVersionNumber;
160 component.blVersionType = 1;
161 component.componentId = component.descriptPackageId;
162 componentId = component.descriptPackageId;
163
164 components_.push_back(component);
165 }
166
167 return ret;
168 }
169
ProcessDescriptInfo(const nlohmann::json & descriptInfo)170 int32_t FirmwareCheckAnalyzeUtils::ProcessDescriptInfo(const nlohmann::json &descriptInfo)
171 {
172 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
173 std::string componentId = components_.empty() ? "" : components_.back().descriptPackageId;
174
175 for (auto &info : descriptInfo) {
176 int32_t descriptInfoType;
177 std::string descContent;
178 std::string subString = "quota";
179 std::string replString = "\"";
180
181 ret += JsonUtils::GetValueAndSetTo(info, "descriptionType", descriptInfoType);
182 ret += JsonUtils::GetValueAndSetTo(info, "content", descContent);
183
184 StringUtils::ReplaceStringAll(descContent, subString, replString);
185
186 std::string changelogFilePath = Firmware::CHANGELOG_PATH + "/" + componentId + ".xml";
187 FIRMWARE_LOGI("changelog file %{public}s", changelogFilePath.c_str());
188
189 std::string data = std::to_string(descriptInfoType) + "|" + descContent;
190 if (!FileUtils::SaveDataToFile(changelogFilePath, data)) {
191 FIRMWARE_LOGE("write data to description file error, %{public}s", changelogFilePath.c_str());
192 }
193 }
194
195 return ret;
196 }
197
IsLegalStatus(int32_t status)198 bool FirmwareCheckAnalyzeUtils::IsLegalStatus(int32_t status)
199 {
200 return status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE) ||
201 status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_NOT_AVAILABLE);
202 }
203 } // namespace UpdateEngine
204 } // namespace OHOS