Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "package_check_code_service.h"
12 : #include "tsd_log.h"
13 : #include "tsd/status.h"
14 : #include "tsd_scope_guard.h"
15 : #include "tsd_util_func.h"
16 : #include "env_internal_api.h"
17 :
18 : namespace tsd {
19 :
20 : namespace {
21 : constexpr uint32_t HELPER_PKG_LOAD_TIMEOUT = 10000U;
22 : constexpr uint32_t DRIVER_EXTEND_MAX_PROCESS_TIME = 140U;
23 :
24 : struct CheckCodeRspHandler {
25 : HDCMessage::MsgType msgType;
26 : void (*handle)(tsd::PackageCheckCodeService& svc, const HDCMessage& msg);
27 : };
28 :
29 4 : void HandleSingleCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg, tsd::TsdLoadPackageType pkgType)
30 : {
31 4 : svc.SetPeerCheckCode(static_cast<uint32_t>(pkgType), msg.check_code());
32 4 : svc.GetPkgRspCode() = ((msg.tsd_rsp_code() == 0U) ? tsd::ResponseCode::SUCCESS : tsd::ResponseCode::FAIL);
33 4 : }
34 :
35 2 : void HandleRuntimeCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg)
36 : {
37 2 : HandleSingleCheckCodeRsp(svc, msg, tsd::TsdLoadPackageType::TSD_PKG_TYPE_RUNTIME);
38 2 : }
39 :
40 2 : void HandleDshapeCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg)
41 : {
42 2 : HandleSingleCheckCodeRsp(svc, msg, tsd::TsdLoadPackageType::TSD_PKG_TYPE_DSHAPE);
43 2 : }
44 :
45 3 : void HandleMultiCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg)
46 : {
47 3 : svc.SetPeerCheckCode(static_cast<uint32_t>(tsd::TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL), msg.check_code());
48 3 : svc.SetPeerCheckCode(
49 : static_cast<uint32_t>(tsd::TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL), msg.extendpkg_check_code());
50 3 : svc.SetPeerCheckCode(
51 : static_cast<uint32_t>(tsd::TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP), msg.ascendcpppkg_check_code());
52 3 : }
53 :
54 : constexpr const CheckCodeRspHandler CHECK_CODE_RSP_HANDLERS[] = {
55 : {HDCMessage::TSD_GET_DEVICE_RUNTIME_CHECKCODE_RSP, &HandleRuntimeCheckCodeRsp},
56 : {HDCMessage::TSD_GET_DEVICE_DSHAPE_CHECKCODE_RSP, &HandleDshapeCheckCodeRsp},
57 : {HDCMessage::TSD_CHECK_PACKAGE_RETRY_RSP, &HandleMultiCheckCodeRsp},
58 : {HDCMessage::TSD_CHECK_PACKAGE_RSP, &HandleMultiCheckCodeRsp},
59 : };
60 : } // namespace
61 :
62 365 : PackageCheckCodeService::PackageCheckCodeService(
63 : DeviceCommAgent& commAgent, CapabilityManager& capabilityMgr, PackageEnvInfo& envInfo, PackageHashStore& hashStore,
64 365 : PackageContext& ctx)
65 365 : : commAgent_(commAgent), capabilityMgr_(capabilityMgr), envInfo_(envInfo), hashStore_(hashStore), ctx_(ctx)
66 365 : {}
67 :
68 12 : TSD_StatusT PackageCheckCodeService::InitTsdClient()
69 : {
70 12 : if (commAgent_.IsInit()) {
71 11 : TSD_INFO("[TsdClient] tsd client has already been initialized");
72 11 : return TSD_OK;
73 : }
74 1 : return commAgent_.InitTsdClient(envInfo_.IsAdcEnv());
75 : }
76 :
77 4 : TSD_StatusT PackageCheckCodeService::WaitPkgRsp(const uint32_t timeout, const bool ignoreRecvErr)
78 : {
79 4 : const TSD_StatusT ret = commAgent_.RecvData(ignoreRecvErr, timeout);
80 4 : if ((ret != TSD_OK) || (static_cast<uint32_t>(ctx_.pkgRspCode) != 0U)) {
81 1 : if (!ignoreRecvErr) {
82 1 : TSD_ERROR(
83 : "tsd package wait response fail, ret[%u], rspCode[%u]", static_cast<uint32_t>(ret),
84 : static_cast<uint32_t>(ctx_.pkgRspCode));
85 : }
86 1 : return TSD_INTERNAL_ERROR;
87 : }
88 3 : return TSD_OK;
89 : }
90 :
91 2 : TSD_StatusT PackageCheckCodeService::GetDeviceCheckCodeOnce(const HDCMessage& msg)
92 : {
93 2 : auto ret = commAgent_.SendMsg(msg);
94 2 : if (ret != TSD_OK) {
95 0 : TSD_ERROR("Send check_code search message failed.");
96 0 : return ret;
97 : }
98 :
99 2 : TSD_RUN_INFO(
100 : "[TsdClient][deviceId=%u] [sessionId=%u] wait package info response", envInfo_.GetLogicDeviceId(),
101 : commAgent_.GetSessionId());
102 2 : ret = commAgent_.RecvData();
103 2 : if (ret != TSD_OK) {
104 1 : TSD_RUN_INFO("not receive TSD_CHECK_PACKAGE rsp msg, just send pkg to server");
105 : }
106 2 : return TSD_OK;
107 : }
108 :
109 9 : TSD_StatusT PackageCheckCodeService::PrepareForCheckCode()
110 : {
111 9 : const TSD_StatusT ret = this->InitTsdClient();
112 9 : if (ret != TSD_OK) {
113 2 : TSD_RUN_WARN("[PackageManager][deviceId=%u] init failed for send aicpu package", envInfo_.GetLogicDeviceId());
114 2 : if (ret >= TSD_SUBPROCESS_NUM_EXCEED_THE_LIMIT) {
115 1 : return ret;
116 : }
117 1 : return TSD_HDC_CREATE_SESSION_FAILED;
118 : }
119 7 : TSD_CHECK_NULLPTR(
120 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_FOUND, "[PackageManager] devCommClient_ is null in Open function");
121 6 : return TSD_OK;
122 : }
123 :
124 6 : TSD_StatusT PackageCheckCodeService::GetDeviceCheckCode()
125 : {
126 6 : if (ctx_.aicpuPackageExistInDevice) {
127 2 : TSD_RUN_INFO(
128 : "[PackageManager][deviceId=%u] aicpu package already exist in device", envInfo_.GetLogicDeviceId());
129 2 : return TSD_AICPUPACKAGE_EXISTED;
130 : }
131 :
132 4 : const TSD_StatusT ret = this->PrepareForCheckCode();
133 4 : if (ret != TSD_OK) {
134 0 : return ret;
135 : }
136 8 : const ScopeGuard destroySessionGuard([this]() { this->commAgent_.ReleaseDeviceConnection(); });
137 :
138 4 : std::shared_ptr<VersionVerify> versionVerify = nullptr;
139 4 : (void)commAgent_.GetVersionVerify(versionVerify);
140 4 : TSD_CHECK_NULLPTR(versionVerify, TSD_INTERNAL_ERROR, "no VersionVerify available.");
141 :
142 4 : if (!versionVerify->SpecialFeatureCheck(HDCMessage::TSD_CHECK_PACKAGE)) {
143 1 : TSD_RUN_INFO("[TsdClient] Device does not support search check_code before send aicpu package.");
144 1 : ctx_.aicpuPackageExistInDevice = true;
145 1 : return TSD_OK;
146 : }
147 :
148 3 : MessageContext ctx{};
149 3 : ctx.logicDeviceId = envInfo_.GetLogicDeviceId();
150 3 : ctx.asan = IsAsanMmSysEnv();
151 3 : ctx.checkCode = ctx_.hostCheckCode[static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL)];
152 3 : ctx.extendpkgCheckCode =
153 3 : ctx_.hostCheckCode[static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL)];
154 3 : ctx.ascendcppCheckCode = ctx_.hostCheckCode[static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP)];
155 3 : HDCMessage msg;
156 3 : if (HdcMessageBuilder::BuildCheckPackage(msg, ctx) != TSD_OK) {
157 0 : TSD_ERROR("build check package msg failed");
158 0 : return TSD_INTERNAL_ERROR;
159 : }
160 3 : SetHostCheckCode(msg, TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL);
161 3 : SetHostCheckCode(msg, TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL);
162 3 : SetHostCheckCode(msg, TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP);
163 3 : if (this->GetDeviceCheckCodeOnce(msg) != TSD_OK) {
164 1 : TSD_ERROR("get check code once failed.");
165 1 : return TSD_INTERNAL_ERROR;
166 : }
167 2 : this->GetDeviceCheckCodeRetrySupport();
168 :
169 2 : ctx_.aicpuPackageExistInDevice = true;
170 :
171 2 : return TSD_OK;
172 4 : }
173 :
174 5 : void PackageCheckCodeService::GetDeviceCheckCodeRetrySupport()
175 : {
176 5 : std::shared_ptr<VersionVerify> versionVerify = nullptr;
177 5 : (void)commAgent_.GetVersionVerify(versionVerify);
178 5 : if (versionVerify == nullptr) {
179 1 : TSD_ERROR("no VersionVerify available.");
180 1 : return;
181 : }
182 4 : ctx_.getCheckCodeRetrySupport = versionVerify->SpecialFeatureCheck(HDCMessage::TSD_CHECK_PACKAGE_RETRY);
183 5 : }
184 :
185 5 : TSD_StatusT PackageCheckCodeService::GetDeviceCheckCodeRetry(const HDCMessage& msg)
186 : {
187 5 : const TSD_StatusT ret = this->PrepareForCheckCode();
188 5 : if (ret != TSD_OK) {
189 3 : return ret;
190 : }
191 4 : const ScopeGuard destroySessionGuard([this]() { this->commAgent_.ReleaseDeviceConnection(); });
192 2 : if (this->GetDeviceCheckCodeOnce(msg) != TSD_OK) {
193 1 : TSD_ERROR("get check code once failed.");
194 1 : return TSD_INTERNAL_ERROR;
195 : }
196 1 : return TSD_OK;
197 2 : }
198 :
199 9 : void PackageCheckCodeService::SetHostCheckCode(HDCMessage& msg, TsdLoadPackageType type)
200 : {
201 9 : const uint32_t packageType = static_cast<uint32_t>(type);
202 9 : if (envInfo_.GetPackageNameRef(packageType).empty()) {
203 8 : return;
204 : }
205 1 : const std::string orgFile = envInfo_.GetPackagePathRef(packageType) + envInfo_.GetPackageNameRef(packageType);
206 1 : ctx_.hostCheckCode[packageType] = static_cast<uint32_t>(CalFileSize(orgFile.c_str()));
207 1 : switch (type) {
208 0 : case TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL:
209 0 : msg.set_check_code(ctx_.hostCheckCode[packageType]);
210 0 : break;
211 1 : case TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL:
212 1 : msg.set_extendpkg_check_code(ctx_.hostCheckCode[packageType]);
213 1 : break;
214 0 : case TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP:
215 0 : msg.set_ascendcpppkg_check_code(ctx_.hostCheckCode[packageType]);
216 0 : break;
217 0 : default:
218 0 : break;
219 : }
220 1 : }
221 :
222 8 : TSD_StatusT PackageCheckCodeService::GetDeviceHsPkgCheckCode(
223 : const uint32_t checkCode, const HDCMessage::MsgType msgType, const bool beforeSendFlag,
224 : const MessageContext& baseCtx)
225 : {
226 8 : TSD_StatusT ret = this->InitTsdClient();
227 8 : if (ret != TSD_OK) {
228 0 : TSD_ERROR("InitTsdClient failed");
229 0 : return TSD_INTERNAL_ERROR;
230 : }
231 8 : HDCMessage msg;
232 8 : MessageContext ctx = baseCtx;
233 8 : ctx.msgType = static_cast<uint32_t>(msgType);
234 8 : ctx.checkCode = checkCode;
235 8 : ctx.beforeSendPkg = beforeSendFlag;
236 8 : if (HdcMessageBuilder::BuildPackageCheckCode(msg, ctx) != TSD_OK) {
237 0 : TSD_ERROR("build package check code msg failed");
238 0 : return TSD_INTERNAL_ERROR;
239 : }
240 8 : ret = commAgent_.SendMsg(msg);
241 8 : if (ret != TSD_OK) {
242 1 : TSD_ERROR("Send runtime checkcode failed msgtype:%u.", static_cast<uint32_t>(msgType));
243 1 : commAgent_.ReleaseDeviceConnection();
244 1 : return TSD_INTERNAL_ERROR;
245 : }
246 7 : TSD_RUN_INFO(
247 : "[TsdClient][deviceId=%u] [sessionId=%u] wait package info response msgType:%u", envInfo_.GetLogicDeviceId(),
248 : commAgent_.GetSessionId(), static_cast<uint32_t>(msgType));
249 7 : ret = this->WaitPkgRsp(HELPER_PKG_LOAD_TIMEOUT);
250 7 : if (ret != TSD_OK) {
251 1 : if (beforeSendFlag) {
252 0 : TSD_RUN_INFO("not receive TSD_CHECK_PACKAGE rsp msg, just send pkg to server");
253 : } else {
254 1 : TSD_ERROR("not receive TSD_CHECK_PACKAGE failed Msgtype:%u", static_cast<uint32_t>(msgType));
255 1 : return TSD_INTERNAL_ERROR;
256 : }
257 : }
258 6 : TSD_RUN_INFO("GetDeviceHsPkgCheckCode success Msgtype:%u", static_cast<uint32_t>(msgType));
259 6 : return TSD_OK;
260 8 : }
261 :
262 6 : TSD_StatusT PackageCheckCodeService::GetCannHsPkgCheckCode(
263 : const std::string& pkgPureName, const std::string& hostPkgHash, const MessageContext& baseCtx)
264 : {
265 6 : TSD_StatusT ret = this->InitTsdClient();
266 6 : if (ret != TSD_OK) {
267 1 : TSD_ERROR("InitTsdClient failed");
268 1 : return TSD_INTERNAL_ERROR;
269 : }
270 :
271 5 : HDCMessage msg;
272 5 : MessageContext ctx = baseCtx;
273 5 : ctx.packageMaxProcessTime = DRIVER_EXTEND_MAX_PROCESS_TIME;
274 5 : ctx.packageWorkerType = static_cast<uint32_t>(PackageWorkerType::PACKAGE_WORKER_COMMON_SINK);
275 5 : ctx.packageType = static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_COMMON_SINK);
276 5 : ctx.packageName = pkgPureName;
277 5 : ctx.hashCode = hostPkgHash;
278 5 : if (HdcMessageBuilder::BuildCannHsCheckCode(msg, ctx) != TSD_OK) {
279 0 : TSD_ERROR("build cann hs check code msg failed");
280 0 : return TSD_INTERNAL_ERROR;
281 : }
282 5 : ret = commAgent_.SendMsg(msg);
283 5 : if (ret != TSD_OK) {
284 2 : TSD_ERROR("Send cann hs check code failed");
285 2 : return TSD_INTERNAL_ERROR;
286 : }
287 :
288 3 : TSD_RUN_INFO(
289 : "[TsdClient][deviceId=%u] [sessionId=%u] wait cann package info response for %s", envInfo_.GetLogicDeviceId(),
290 : commAgent_.GetSessionId(), pkgPureName.c_str());
291 3 : ret = this->WaitPkgRsp(DRIVER_EXTEND_MAX_PROCESS_TIME * 1000U);
292 3 : if (ret != TSD_OK) {
293 0 : TSD_ERROR("Wait response for package %s failed", pkgPureName.c_str());
294 0 : return TSD_INTERNAL_ERROR;
295 : }
296 3 : TSD_RUN_INFO("Get check code for package %s success", pkgPureName.c_str());
297 3 : return TSD_OK;
298 5 : }
299 :
300 2 : void PackageCheckCodeService::HandleNormalPackageCheckCodeRsp(const HDCMessage& msg)
301 : {
302 2 : const uint32_t packageType = static_cast<uint32_t>(msg.package_type());
303 2 : constexpr uint32_t packageTypeMax = static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_MAX);
304 2 : if (packageType >= packageTypeMax) {
305 1 : TSD_ERROR("The package type is larger than the max, max=%u, type=%u", packageTypeMax, packageType);
306 1 : return;
307 : }
308 1 : if (packageType == static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_COMMON_SINK)) {
309 0 : hashStore_.StoreAllPkgHashValue(msg);
310 : } else {
311 1 : ctx_.peerCheckCode[packageType] = msg.check_code();
312 : }
313 1 : ctx_.deviceIdle = msg.device_idle();
314 1 : if (!ctx_.deviceIdle) {
315 0 : TSD_RUN_WARN("device has process is running, skip load driver extend package");
316 : }
317 1 : ctx_.pkgRspCode = ((msg.tsd_rsp_code() == 0U) ? ResponseCode::SUCCESS : ResponseCode::FAIL);
318 1 : ctx_.loadPackageErrorMsg = msg.error_info().error_log();
319 : }
320 :
321 1 : void PackageCheckCodeService::HandleCannHsCheckCodeRsp(const HDCMessage& msg)
322 : {
323 1 : if (msg.package_hash_code_list_size() == 0) {
324 0 : TSD_ERROR("Get package hash size from msg failed, is empty");
325 0 : return;
326 : }
327 1 : std::string pkgName = msg.package_hash_code_list(0).package_name();
328 1 : std::string deviceHashValue = msg.package_hash_code_list(0).hash_code();
329 1 : hashStore_.SetDeviceCommonSinkPackHashValue(pkgName, deviceHashValue);
330 1 : ctx_.pkgRspCode = (msg.tsd_rsp_code() == 0U) ? ResponseCode::SUCCESS : ResponseCode::FAIL;
331 1 : TSD_INFO("Set check code for %s success. rsp=%u", pkgName.c_str(), ctx_.pkgRspCode);
332 1 : }
333 :
334 11 : void PackageCheckCodeService::SaveDeviceCheckCode(const HDCMessage& msg)
335 : {
336 11 : const HDCMessage::MsgType msgType = msg.type();
337 37 : for (const auto& handler : CHECK_CODE_RSP_HANDLERS) {
338 33 : if (handler.msgType == msgType) {
339 7 : handler.handle(*this, msg);
340 7 : if (msgType == HDCMessage::TSD_CHECK_PACKAGE_RSP) {
341 2 : capabilityMgr_.UpdateStateFromMsg(msg);
342 : }
343 7 : return;
344 : }
345 : }
346 4 : if (msgType == HDCMessage::TSD_GET_DEVICE_PACKAGE_CHECKCODE_NORMAL_RSP) {
347 2 : HandleNormalPackageCheckCodeRsp(msg);
348 2 : } else if (msgType == HDCMessage::TSD_GET_DEVICE_CANN_HS_CHECKCODE_RSP) {
349 1 : HandleCannHsCheckCodeRsp(msg);
350 : } else {
351 1 : TSD_RUN_INFO("msgType[%u] is not supported", static_cast<uint32_t>(msgType));
352 : }
353 : }
354 :
355 : } // namespace tsd
|