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 if (root.find("checkResults") == root.end()) {
108 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key checkResults");
109 return CAST_INT(JsonParseError::MISSING_PROP);
110 }
111 FIRMWARE_LOGI("checkResults size is %{public}" PRIu64 "", static_cast<uint64_t>(root["checkResults"].size()));
112 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
113 std::string componentId;
114 for (auto &result : root["checkResults"]) {
115 FirmwareComponent component;
116 int32_t componetSize = 0;
117 ret += JsonUtils::GetValueAndSetTo(result, "descriptPackageId", component.descriptPackageId);
118 ret += JsonUtils::GetValueAndSetTo(result, "url", component.url);
119 ret += JsonUtils::GetValueAndSetTo(result, "size", componetSize);
120 component.size = static_cast<int64_t>(componetSize);
121 component.fileName = StringUtils::GetLastSplitString(component.url, "/");
122 ret += JsonUtils::GetValueAndSetTo(result, "verifyInfo", component.verifyInfo);
123 ret += JsonUtils::GetValueAndSetTo(result, "versionCode", component.versionNumber);
124 ret += JsonUtils::GetValueAndSetTo(result, "versionName", component.targetBlVersionNumber);
125 component.targetBlDisplayVersionNumber = component.targetBlVersionNumber;
126 component.blVersionType = 1;
127 component.componentId = component.descriptPackageId;
128 component.versionPackageType = PackageType::NORMAL;
129 componentId = component.descriptPackageId;
130 components_.push_back(component);
131 }
132
133 if (root.find("descriptInfo") == root.end()) {
134 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key descriptInfo");
135 return CAST_INT(JsonParseError::MISSING_PROP);
136 }
137 for (auto &descriptInfo : root["descriptInfo"]) {
138 int32_t descriptInfoType;
139 std::string descContent;
140 std::string subString = "quota";
141 std::string replString = "\"";
142 ret += JsonUtils::GetValueAndSetTo(descriptInfo, "descriptionType", descriptInfoType);
143 ret += JsonUtils::GetValueAndSetTo(descriptInfo, "content", descContent);
144 StringUtils::ReplaceStringAll(descContent, subString, replString);
145 std::string changelogFilePath = Firmware::CHANGELOG_PATH + "/" + componentId + ".xml";
146 FIRMWARE_LOGI("changelog file %{public}s", changelogFilePath.c_str());
147 std::string data = std::to_string(descriptInfoType) + "|" + descContent;
148 if (!FileUtils::SaveDataToFile(changelogFilePath, data)) {
149 FIRMWARE_LOGE("write data to description file error, %{public}s", changelogFilePath.c_str());
150 }
151 }
152
153 return ret;
154 }
155
IsLegalStatus(int32_t status)156 bool FirmwareCheckAnalyzeUtils::IsLegalStatus(int32_t status)
157 {
158 return status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE) ||
159 status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_NOT_AVAILABLE);
160 }
161 } // namespace UpdateEngine
162 } // namespace OHOS