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 "file_utils.h"
26 #include "firmware_combine_version_utils.h"
27 #include "firmware_constant.h"
28 #include "firmware_log.h"
29 #include "firmware_preferences_utils.h"
30 #include "string_utils.h"
31 #include "updateservice_json_utils.h"
32
33 namespace OHOS {
34 namespace UpdateService {
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 auto root = UpdateServiceJsonUtils::ParseJson(rawJson);
41 if (root == nullptr) {
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 UpdateServiceJsonUtils::GetValueAndSetTo(root.get(), "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.get(), response);
56 ret += AnalyzeComponents(root.get());
57 }
58
59 // 解析的都是必须字段,全部解析正常,才能给component赋值
60 if (ret == CAST_INT(JsonParseError::ERR_OK)) {
61 components = components_;
62 }
63 }
64
AnalyzeBlVersionCheckResults(cJSON * root,BlCheckResponse & response)65 int32_t FirmwareCheckAnalyzeUtils::AnalyzeBlVersionCheckResults(cJSON *root, BlCheckResponse &response)
66 {
67 cJSON *itemCheckResults = cJSON_GetObjectItemCaseSensitive(root, "checkResults");
68 if (itemCheckResults == nullptr) {
69 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeBlVersionCheckResults no key checkResults");
70 return CAST_INT(JsonParseError::MISSING_PROP);
71 }
72
73 FIRMWARE_LOGI("checkResults size is %{public}" PRIu64 "",
74 static_cast<uint64_t>(cJSON_IsArray(itemCheckResults) ? cJSON_GetArraySize(itemCheckResults) : 0));
75
76 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
77 int32_t status = CAST_INT(CheckResultStatus::STATUS_SYSTEM_ERROR);
78 UpdateServiceJsonUtils::GetValueAndSetTo(root, "searchStatus", status);
79 if (status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE)) {
80 int32_t arraySize = cJSON_GetArraySize(itemCheckResults);
81 for (int i = 0; i < arraySize; i++) {
82 auto item = cJSON_GetArrayItem(itemCheckResults, i);
83 BlVersionCheckResult checkResult;
84 ret += UpdateServiceJsonUtils::GetValueAndSetTo(item, "descriptPackageId", checkResult.descriptPackageId);
85 checkResult.blVersionType = 1;
86 checkResult.status = std::to_string(status);
87 UpdatePackage package;
88 package.versionId = "1";
89 int32_t versionPackageType = CAST_INT(PackageType::DYNAMIC);
90 ret += UpdateServiceJsonUtils::GetValueAndSetTo(item, "packageType", versionPackageType);
91 package.versionPackageType = static_cast<PackageType>(versionPackageType);
92 package.packageIndex = 0;
93 checkResult.updatePackages.push_back(package);
94 TargetBlComponent component;
95 component.versionPackageType = package.versionPackageType;
96 ret += UpdateServiceJsonUtils::GetValueAndSetTo(item, "versionName", component.displayVersionNumber);
97 ret += UpdateServiceJsonUtils::GetValueAndSetTo(item, "versionName", component.versionNumber);
98 checkResult.targetBlComponents.push_back(component);
99 response.blVersionCheckResults.push_back(checkResult);
100 Version version;
101 version.versionId = "1";
102 ret += UpdateServiceJsonUtils::GetValueAndSetTo(item, "versionCode", version.versionNumber);
103 ret += UpdateServiceJsonUtils::GetValueAndSetTo(item, "url", version.url);
104 response.versionList.push_back(version);
105 }
106 }
107 return ret;
108 }
109
AnalyzeComponents(cJSON * root)110 int32_t FirmwareCheckAnalyzeUtils::AnalyzeComponents(cJSON *root)
111 {
112 // 检查 "checkResults" 是否存在
113 cJSON *itemCheckResults = cJSON_GetObjectItemCaseSensitive(root, "checkResults");
114 if (itemCheckResults == nullptr) {
115 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key checkResults");
116 return CAST_INT(JsonParseError::MISSING_PROP);
117 }
118 FIRMWARE_LOGI("checkResults size is %{public}" PRIu64 "",
119 static_cast<uint64_t>(cJSON_IsArray(itemCheckResults) ? cJSON_GetArraySize(itemCheckResults) : 0));
120
121 // 初始化返回值
122 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
123
124 // 处理 "checkResults" 部分
125 ret += ProcessCheckResults(itemCheckResults);
126
127 // 检查 "descriptInfo" 是否存在
128 cJSON *itemDescriptInfo = cJSON_GetObjectItemCaseSensitive(root, "descriptInfo");
129 if (itemDescriptInfo == nullptr) {
130 FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key descriptInfo");
131 return CAST_INT(JsonParseError::MISSING_PROP);
132 }
133
134 // 处理 "descriptInfo" 部分
135 ret += ProcessDescriptInfo(itemDescriptInfo);
136
137 return ret;
138 }
139
ProcessCheckResults(cJSON * checkResults)140 int32_t FirmwareCheckAnalyzeUtils::ProcessCheckResults(cJSON *checkResults)
141 {
142 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
143 std::string componentId;
144
145 int32_t arraySize = cJSON_GetArraySize(checkResults);
146 for (int i = 0; i < arraySize; i++) {
147 cJSON *itemResult = cJSON_GetArrayItem(checkResults, i);
148
149 FirmwareComponent component;
150 int32_t componetSize = 0;
151
152 // 获取组件相关属性
153 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "descriptPackageId", component.descriptPackageId);
154 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "url", component.url);
155 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "size", componetSize);
156 component.size = static_cast<int64_t>(componetSize);
157 component.fileName = StringUtils::GetLastSplitString(component.url, "/");
158 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "verifyInfo", component.verifyInfo);
159 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "versionCode", component.versionNumber);
160 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "versionName", component.targetBlVersionNumber);
161
162 int32_t versionPackageType = CAST_INT(PackageType::DYNAMIC);
163 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "packageType", versionPackageType);
164 component.versionPackageType = static_cast<PackageType>(versionPackageType);
165
166 int32_t otaType = CAST_INT(OtaType::REGULAR);
167 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemResult, "otaType", otaType);
168 component.otaType = static_cast<OtaType>(otaType);
169
170 component.targetBlDisplayVersionNumber = component.targetBlVersionNumber;
171 component.blVersionType = 1;
172 component.componentId = component.descriptPackageId;
173 componentId = component.descriptPackageId;
174
175 components_.push_back(component);
176 }
177 return ret;
178 }
179
ProcessDescriptInfo(cJSON * descriptInfo)180 int32_t FirmwareCheckAnalyzeUtils::ProcessDescriptInfo(cJSON *descriptInfo)
181 {
182 int32_t ret = CAST_INT(JsonParseError::ERR_OK);
183 std::string componentId = components_.empty() ? "" : components_.back().descriptPackageId;
184
185 int32_t arraySize = cJSON_GetArraySize(descriptInfo);
186 for (int i = 0; i < arraySize; i++) {
187 cJSON *itemInfo = cJSON_GetArrayItem(descriptInfo, i);
188 int32_t descriptInfoType;
189 std::string descContent;
190 std::string subString = "quota";
191 std::string replString = "\"";
192
193 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemInfo, "descriptionType", descriptInfoType);
194 ret += UpdateServiceJsonUtils::GetValueAndSetTo(itemInfo, "content", descContent);
195
196 StringUtils::ReplaceStringAll(descContent, subString, replString);
197
198 std::string changelogFilePath = Firmware::CHANGELOG_PATH + "/" + componentId + ".xml";
199 FIRMWARE_LOGI("changelog file %{public}s", changelogFilePath.c_str());
200
201 std::string data = std::to_string(descriptInfoType) + "|" + descContent;
202 if (!FileUtils::SaveDataToFile(changelogFilePath, data)) {
203 FIRMWARE_LOGE("write data to description file error, %{public}s", changelogFilePath.c_str());
204 }
205 }
206
207 return ret;
208 }
209
IsLegalStatus(int32_t status)210 bool FirmwareCheckAnalyzeUtils::IsLegalStatus(int32_t status)
211 {
212 return status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE) ||
213 status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_NOT_AVAILABLE);
214 }
215 } // namespace UpdateService
216 } // namespace OHOS