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 "capability_manager.h"
12 : #include "error_manager.h"
13 : #include "tsd_log.h"
14 : #include "tsd/status.h"
15 : #include "tsd_util_func.h"
16 : #include "tsd/tsd_client.h"
17 :
18 : namespace tsd {
19 : namespace {
20 : constexpr uint32_t COMMON_SUPPORT_TIMEOUT = 10000U;
21 : constexpr uint32_t SUPPORT_OM_INNER_DEC_MSG_TIMEOUT = 10000U;
22 : constexpr uint64_t TSD_SUPPORT_OM_INNER_DEC = 1UL;
23 : constexpr uint64_t TSD_NOT_SUPPORT_OM_INNER_DEC = 0UL;
24 :
25 : // ===========================================================================
26 : // Strategy functions — one set per capability type.
27 : // Each group of free functions below encapsulates the per-type "business"
28 : // that was previously scattered across multiple switch-case blocks. They are
29 : // wired into the kCapabilitySpecs table as function pointers, so the member
30 : // functions of CapabilityManager contain **zero** switch statements.
31 : // Adding a new capability type that reuses an existing strategy only requires
32 : // appending one row to kCapabilitySpecs. Only a brand-new result-write or
33 : // state-update strategy requires writing a new strategy function — no existing
34 : // function body changes.
35 : // ===========================================================================
36 :
37 : // ---- PID_QOS ----
38 3 : bool PidQosTryUseStored(CapabilityManager& mgr, uint64_t ptr)
39 : {
40 : (void)mgr;
41 : (void)ptr;
42 3 : return false;
43 : }
44 :
45 4 : TSD_StatusT PidQosSaveResult(const CapabilityManager& mgr, uint64_t ptr)
46 : {
47 4 : uint64_t* const resultPtr = reinterpret_cast<uint64_t*>(static_cast<uintptr_t>(ptr));
48 4 : if (resultPtr == nullptr) {
49 0 : TSD_ERROR("input ptr is null");
50 0 : return TSD_CLT_OPEN_FAILED;
51 : }
52 4 : const int64_t pidQos = mgr.GetPidQos();
53 4 : if (pidQos != -1) {
54 3 : *resultPtr = static_cast<uint64_t>(pidQos);
55 : }
56 4 : return TSD_OK;
57 : }
58 :
59 0 : void PidQosWriteUnsupported(uint64_t ptr) { *reinterpret_cast<uint64_t*>(static_cast<uintptr_t>(ptr)) = 0UL; }
60 :
61 0 : void PidQosUpdateState(CapabilityManager& mgr, const HDCMessage& msg) { mgr.SetPidQos(msg.pid_of_qos()); }
62 :
63 : // ---- SUPPORT_LEVEL ----
64 5 : bool LevelTryUseStored(CapabilityManager& mgr, uint64_t ptr)
65 : {
66 5 : const uint32_t level = mgr.GetTsdSupportLevel();
67 5 : if (TSD_BITMAP_GET(level, TSD_SUPPORT_HS_AISERVER_FEATURE_BIT) != 0U) {
68 3 : uint32_t* const resultPtr = PtrToPtr<void, uint32_t>(ValueToPtr(static_cast<uintptr_t>(ptr)));
69 3 : *resultPtr = level;
70 3 : return true;
71 : }
72 2 : return false;
73 : }
74 :
75 2 : TSD_StatusT LevelSaveResult(const CapabilityManager& mgr, uint64_t ptr)
76 : {
77 2 : uint32_t* const resultPtr = PtrToPtr<void, uint32_t>(ValueToPtr(static_cast<uintptr_t>(ptr)));
78 2 : if (resultPtr == nullptr) {
79 0 : TSD_ERROR("input ptr is null");
80 0 : return TSD_CLT_OPEN_FAILED;
81 : }
82 2 : *resultPtr = static_cast<uint32_t>(mgr.GetTsdSupportLevel());
83 2 : return TSD_OK;
84 : }
85 :
86 0 : void LevelWriteUnsupported(uint64_t ptr) { *reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(ptr)) = 0U; }
87 :
88 32 : void LevelUpdateState(CapabilityManager& mgr, const HDCMessage& msg)
89 : {
90 32 : const uint32_t level = msg.capability_level();
91 32 : if ((msg.tsd_rsp_code() == 0U) && (level != 0U)) {
92 4 : mgr.SetTsdSupportLevel(level);
93 : }
94 32 : }
95 :
96 : // ---- OM_INNER_DEC ----
97 3 : bool OmInnerDecTryUseStored(CapabilityManager& mgr, uint64_t ptr)
98 : {
99 3 : if (mgr.IsSupportOmInnerDec()) {
100 2 : uint64_t* const resultPtr = reinterpret_cast<uint64_t*>(static_cast<uintptr_t>(ptr));
101 2 : *resultPtr = TSD_SUPPORT_OM_INNER_DEC;
102 2 : return true;
103 : }
104 1 : return false;
105 : }
106 :
107 4 : TSD_StatusT OmInnerDecSaveResult(const CapabilityManager& mgr, uint64_t ptr)
108 : {
109 4 : uint64_t* const resultPtr = reinterpret_cast<uint64_t*>(static_cast<uintptr_t>(ptr));
110 4 : *resultPtr = mgr.IsSupportOmInnerDec() ? TSD_SUPPORT_OM_INNER_DEC : TSD_NOT_SUPPORT_OM_INNER_DEC;
111 4 : return TSD_OK;
112 : }
113 :
114 2 : void OmInnerDecWriteUnsupported(uint64_t ptr) { *reinterpret_cast<uint64_t*>(static_cast<uintptr_t>(ptr)) = 0UL; }
115 :
116 4 : void OmInnerDecUpdateState(CapabilityManager& mgr, const HDCMessage& msg)
117 : {
118 4 : mgr.SetSupportOmInnerDec(msg.tsd_rsp_code() == 0U);
119 4 : }
120 :
121 : // ---- BUILTIN_UDF ----
122 3 : bool BuiltinUdfTryUseStored(CapabilityManager& mgr, uint64_t ptr)
123 : {
124 3 : if (TSD_BITMAP_GET(mgr.GetTsdSupportLevel(), TSD_SUPPORT_BUILTIN_UDF_BIT)) {
125 3 : bool* const resultPtr = reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr));
126 3 : *resultPtr = true;
127 3 : return true;
128 : }
129 0 : return false;
130 : }
131 :
132 2 : TSD_StatusT BuiltinUdfSaveResult(const CapabilityManager& mgr, uint64_t ptr)
133 : {
134 2 : bool* const resultPtr = reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr));
135 2 : *resultPtr = TSD_BITMAP_GET(mgr.GetTsdSupportLevel(), TSD_SUPPORT_BUILTIN_UDF_BIT) ? true : false;
136 2 : return TSD_OK;
137 : }
138 :
139 0 : void BuiltinUdfWriteUnsupported(uint64_t ptr) { *reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr)) = false; }
140 :
141 : // ---- DRIVER_VERSION ----
142 2 : bool DriverVersionTryUseStored(CapabilityManager& mgr, uint64_t ptr)
143 : {
144 : (void)mgr;
145 2 : uint64_t* const resultPtr = PtrToPtr<void, uint64_t>(ValueToPtr(static_cast<uintptr_t>(ptr)));
146 2 : *resultPtr = 0UL;
147 2 : return true;
148 : }
149 :
150 1 : TSD_StatusT DriverVersionSaveResult(const CapabilityManager& mgr, uint64_t ptr)
151 : {
152 : (void)mgr;
153 : (void)ptr;
154 : // DRIVER_VERSION is always served by tryUseStored; reaching saveResult
155 : // indicates a logic error.
156 1 : return TSD_CLT_OPEN_FAILED;
157 : }
158 :
159 0 : void DriverVersionWriteUnsupported(uint64_t ptr) { *reinterpret_cast<uint64_t*>(static_cast<uintptr_t>(ptr)) = 0UL; }
160 :
161 : // ---- ADPROF ----
162 1 : bool AdprofTryUseStored(CapabilityManager& mgr, uint64_t ptr)
163 : {
164 1 : if (mgr.IsAdprofSupport()) {
165 1 : bool* const resultPtr = reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr));
166 1 : *resultPtr = true;
167 1 : return true;
168 : }
169 0 : return false;
170 : }
171 :
172 3 : TSD_StatusT AdprofSaveResult(const CapabilityManager& mgr, uint64_t ptr)
173 : {
174 3 : bool* const resultPtr = reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr));
175 3 : if (resultPtr == nullptr) {
176 1 : TSD_ERROR("input ptr is null");
177 1 : return TSD_CLT_OPEN_FAILED;
178 : }
179 2 : *resultPtr = mgr.IsAdprofSupport();
180 2 : return TSD_OK;
181 : }
182 :
183 0 : void AdprofWriteUnsupported(uint64_t ptr) { *reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr)) = false; }
184 :
185 2 : void AdprofUpdateState(CapabilityManager& mgr, const HDCMessage& msg) { mgr.SetAdprofSupport(msg.support_adprof()); }
186 :
187 : // ---- MULTIPLE_HCCP ----
188 2 : bool MultipleHccpTryUseStored(CapabilityManager& mgr, uint64_t ptr)
189 : {
190 2 : if (TSD_BITMAP_GET(mgr.GetTsdSupportLevel(), TSD_SUPPORT_MUL_HCCP) != 0U) {
191 2 : bool* const resultPtr = reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr));
192 2 : *resultPtr = true;
193 2 : return true;
194 : }
195 0 : return false;
196 : }
197 :
198 1 : TSD_StatusT MultipleHccpSaveResult(const CapabilityManager& mgr, uint64_t ptr)
199 : {
200 1 : bool* const resultPtr = reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr));
201 1 : *resultPtr = TSD_BITMAP_GET(mgr.GetTsdSupportLevel(), TSD_SUPPORT_MUL_HCCP) != 0U ? true : false;
202 1 : return TSD_OK;
203 : }
204 :
205 0 : void MultipleHccpWriteUnsupported(uint64_t ptr) { *reinterpret_cast<bool*>(static_cast<uintptr_t>(ptr)) = false; }
206 :
207 : // ===========================================================================
208 : // The single registration point — one row per capability type.
209 : // Note: BUILTIN_UDF and MULTIPLE_HCCP share the same rspMsgType as LEVEL
210 : // (TSD_GET_SUPPORT_CAPABILITY_LEVEL_RSP). In UpdateStateFromMsg the first
211 : // matching spec with a non-null updateStateFromMsg wins; since BUILTIN_UDF
212 : // and MULTIPLE_HCCP have updateStateFromMsg=nullptr they are skipped, and
213 : // LEVEL's handler processes the shared response. This is intentional —
214 : // those types read their result from the same tsdSupportLevel_ bitmap.
215 : // ===========================================================================
216 : const CapabilitySpec kCapabilitySpecs[] = {
217 : {
218 : TSD_CAPABILITY_PIDQOS,
219 : HDCMessage::TSD_GET_PID_QOS,
220 : HDCMessage::TSD_GET_PID_QOS_RSP,
221 : true,
222 : 0U,
223 : false,
224 : false,
225 : PidQosTryUseStored,
226 : PidQosSaveResult,
227 : PidQosWriteUnsupported,
228 : PidQosUpdateState,
229 : },
230 : {
231 : TSD_CAPABILITY_LEVEL,
232 : HDCMessage::TSD_GET_SUPPORT_CAPABILITY_LEVEL,
233 : HDCMessage::TSD_GET_SUPPORT_CAPABILITY_LEVEL_RSP,
234 : false,
235 : COMMON_SUPPORT_TIMEOUT,
236 : true,
237 : false,
238 : LevelTryUseStored,
239 : LevelSaveResult,
240 : LevelWriteUnsupported,
241 : LevelUpdateState,
242 : },
243 : {
244 : TSD_CAPABILITY_OM_INNER_DEC,
245 : HDCMessage::TSD_SUPPORT_OM_INNER_DEC,
246 : HDCMessage::TSD_SUPPORT_OM_INNER_DEC_RSP,
247 : false,
248 : SUPPORT_OM_INNER_DEC_MSG_TIMEOUT,
249 : true,
250 : true,
251 : OmInnerDecTryUseStored,
252 : OmInnerDecSaveResult,
253 : OmInnerDecWriteUnsupported,
254 : OmInnerDecUpdateState,
255 : },
256 : {
257 : TSD_CAPABILITY_BUILTIN_UDF,
258 : HDCMessage::TSD_GET_SUPPORT_CAPABILITY_LEVEL,
259 : HDCMessage::TSD_GET_SUPPORT_CAPABILITY_LEVEL_RSP,
260 : false,
261 : COMMON_SUPPORT_TIMEOUT,
262 : true,
263 : false,
264 : BuiltinUdfTryUseStored,
265 : BuiltinUdfSaveResult,
266 : BuiltinUdfWriteUnsupported,
267 : nullptr,
268 : },
269 : {
270 : TSD_CAPABILITY_DRIVER_VERSION,
271 : HDCMessage::INIT,
272 : HDCMessage::INIT,
273 : false,
274 : 0U,
275 : false,
276 : false,
277 : DriverVersionTryUseStored,
278 : DriverVersionSaveResult,
279 : DriverVersionWriteUnsupported,
280 : nullptr,
281 : },
282 : {
283 : TSD_CAPABILITY_ADPROF,
284 : HDCMessage::TSD_GET_SUPPORT_ADPROF,
285 : HDCMessage::TSD_GET_SUPPORT_ADPROF_RSP,
286 : false,
287 : COMMON_SUPPORT_TIMEOUT,
288 : true,
289 : false,
290 : AdprofTryUseStored,
291 : AdprofSaveResult,
292 : AdprofWriteUnsupported,
293 : AdprofUpdateState,
294 : },
295 : {
296 : TSD_CAPABILITY_MUTIPLE_HCCP,
297 : HDCMessage::TSD_GET_SUPPORT_CAPABILITY_LEVEL,
298 : HDCMessage::TSD_GET_SUPPORT_CAPABILITY_LEVEL_RSP,
299 : false,
300 : COMMON_SUPPORT_TIMEOUT,
301 : true,
302 : false,
303 : MultipleHccpTryUseStored,
304 : MultipleHccpSaveResult,
305 : MultipleHccpWriteUnsupported,
306 : nullptr,
307 : },
308 : };
309 : } // namespace
310 :
311 132 : const CapabilitySpec* FindCapabilitySpec(const int32_t type)
312 : {
313 394 : for (const CapabilitySpec& spec : kCapabilitySpecs) {
314 388 : if (spec.type == type) {
315 126 : return &spec;
316 : }
317 : }
318 6 : return nullptr;
319 : }
320 :
321 263 : CapabilityManager::CapabilityManager(uint32_t logicDeviceId, DeviceCommAgent& commAgent, bool isAdcEnv)
322 263 : : logicDeviceId_(logicDeviceId), commAgent_(commAgent), isAdcEnv_(isAdcEnv)
323 263 : {}
324 :
325 263 : CapabilityManager::~CapabilityManager() {}
326 :
327 51 : void CapabilityManager::ConstructCapabilityMsg(HDCMessage& msg, const int32_t type)
328 : {
329 51 : MessageContext ctx{};
330 51 : ctx.logicDeviceId = logicDeviceId_;
331 51 : ctx.procSign = commAgent_.GetProcSign();
332 51 : ctx.capabilityType = type;
333 51 : (void)HdcMessageBuilder::BuildCapability(msg, ctx);
334 51 : }
335 :
336 19 : bool CapabilityManager::IsOkToGetCapability(const int32_t type) const
337 : {
338 19 : const CapabilitySpec* spec = FindCapabilitySpec(type);
339 19 : if (spec == nullptr) {
340 1 : return false;
341 : }
342 18 : if (!spec->requiresStartCpAndComm) {
343 12 : return true;
344 : }
345 6 : return tsdStartCp_ && (commAgent_.GetDeviceComm() != nullptr);
346 : }
347 :
348 43 : TSD_StatusT CapabilityManager::SendCapabilityMsg(const int32_t type)
349 : {
350 43 : if (!commAgent_.IsInit()) {
351 0 : TSD_WARN("[TsdClient] tsd client need open first");
352 0 : return TSD_OK;
353 : }
354 43 : HDCMessage msg;
355 43 : ConstructCapabilityMsg(msg, type);
356 43 : const TSD_StatusT ret = commAgent_.SendMsg(msg);
357 43 : return ret;
358 43 : }
359 :
360 87 : bool CapabilityManager::IsSupportCommonInterface(const uint32_t level)
361 : {
362 87 : const uint32_t tsdSupportLevel = tsdSupportLevel_;
363 87 : if (tsdSupportLevel != 0U) {
364 27 : return TSD_BITMAP_GET(tsdSupportLevel, level) != 0U;
365 : }
366 :
367 60 : TSD_StatusT ret = commAgent_.InitTsdClient(isAdcEnv_);
368 60 : if ((ret != TSD_OK) || (commAgent_.GetDeviceComm() == nullptr)) {
369 15 : TSD_ERROR("Init hdc client failed.");
370 15 : return false;
371 : }
372 45 : ret = SendCapabilityMsg(TSD_CAPABILITY_LEVEL);
373 45 : if (ret != TSD_OK) {
374 1 : TSD_ERROR("SendCapabilityMsg failed");
375 1 : return false;
376 : }
377 44 : ret = commAgent_.RecvData(true, COMMON_SUPPORT_TIMEOUT);
378 44 : if (ret != TSD_OK) {
379 7 : TSD_RUN_INFO("TSD_CAPABILITY_LEVEL is not supported");
380 7 : return false;
381 : }
382 37 : const uint32_t curSupportLevel = tsdSupportLevel_;
383 37 : if (TSD_BITMAP_GET(curSupportLevel, level)) {
384 0 : return true;
385 : }
386 :
387 37 : TSD_RUN_INFO(
388 : "IsSupportCommonInterface check was not successful, level[%u], tsd support level[%u]", level, curSupportLevel);
389 37 : return false;
390 : }
391 :
392 93 : bool CapabilityManager::IsSupportCommonSink()
393 : {
394 93 : if (!hasGetHostSoPath_) {
395 38 : hostSoPath_ = tsd::GetHostSoPath();
396 38 : hasGetHostSoPath_ = true;
397 : }
398 93 : if (!hostSoPath_.empty()) {
399 91 : const std::string mutexFile = hostSoPath_ + MUTEX_FILE_PREFIX + "0.cfg";
400 91 : if (CheckRealPath(mutexFile)) {
401 1 : TSD_RUN_INFO("mutexFile[%s] found means supporting common sink", mutexFile.c_str());
402 1 : return true;
403 : }
404 91 : }
405 :
406 92 : TSD_INFO("hostSoPath is %s.", hostSoPath_.c_str());
407 92 : return IsSupportCommonInterface(TSD_SUPPORT_COMMON_SINK_PKG_CONFIG);
408 : }
409 :
410 17 : bool CapabilityManager::CheckSubProcSupported(SubProcType procType)
411 : {
412 : struct SubProcCapabilityEntry {
413 : SubProcType procType;
414 : uint32_t capabilityBit;
415 : };
416 : static const SubProcCapabilityEntry kSubProcCapabilityMap[] = {
417 : {TSD_SUB_PROC_UDF, TSD_SUPPORT_HS_AISERVER_FEATURE_BIT},
418 : {TSD_SUB_PROC_NPU, TSD_SUPPORT_HS_AISERVER_FEATURE_BIT},
419 : {TSD_SUB_PROC_BUILTIN_UDF, TSD_SUPPORT_BUILTIN_UDF_BIT},
420 : {TSD_SUB_PROC_ADPROF, TSD_SUPPORT_ADPROF_BIT},
421 : };
422 48 : for (const SubProcCapabilityEntry& entry : kSubProcCapabilityMap) {
423 41 : if (entry.procType == procType) {
424 10 : return IsSupportCommonInterface(entry.capabilityBit);
425 : }
426 : }
427 7 : return true;
428 : }
429 :
430 20 : bool CapabilityManager::UseStoredCapabityInfo(const int32_t type, const uint64_t ptr)
431 : {
432 20 : const CapabilitySpec* spec = FindCapabilitySpec(type);
433 20 : if (spec == nullptr) {
434 1 : return false;
435 : }
436 19 : return spec->tryUseStored(*this, ptr);
437 : }
438 :
439 : // Thin wrapper around commAgent_.RecvData().
440 : // The legacy ProcessModeManager::WaitRsp() additionally checked rspCode_ and
441 : // mapped structured error codes via MapFailCodeToStatus(). That check is
442 : // omitted here because all capability-query responses on the device side are
443 : // written with rspCode_ = SUCCESS (0) unconditionally — the device never
444 : // returns a non-zero rspCode_ for capability queries. Therefore the rspCode_
445 : // branch was dead code for this path, and its removal does not change
446 : // observable behaviour. Error reporting granularity is limited to the
447 : // RecvData return value, which is sufficient for the ignoreFail=true
448 : // majority of capability queries.
449 2 : TSD_StatusT CapabilityManager::WaitRspForCapability(const uint32_t timeout, const bool ignoreRecvErr)
450 : {
451 2 : const TSD_StatusT ret = commAgent_.RecvData(ignoreRecvErr, timeout);
452 2 : if (ret != TSD_OK) {
453 0 : if (!ignoreRecvErr) {
454 0 : TSD_ERROR("tsd client wait capability response fail, ret=%u", static_cast<uint32_t>(ret));
455 : TSD_REPORT_INNER_ERROR("tsd client wait capability response fail, ret=%u", static_cast<uint32_t>(ret));
456 : }
457 0 : return TSD_CLT_OPEN_FAILED;
458 : }
459 2 : return TSD_OK;
460 : }
461 :
462 10 : TSD_StatusT CapabilityManager::WaitCapabilityRsp(const int32_t type, const uint64_t ptr)
463 : {
464 10 : const CapabilitySpec* spec = FindCapabilitySpec(type);
465 10 : const uint32_t timeout = (spec != nullptr) ? spec->waitTimeout : 0U;
466 10 : const bool ignoreFail = (spec != nullptr) ? spec->waitIgnoreFail : false;
467 :
468 10 : const TSD_StatusT ret = WaitRspForCapability(timeout, ignoreFail);
469 10 : if ((ignoreFail) && (ret != TSD_OK)) {
470 4 : TSD_RUN_INFO("not recv capability:%d rsp", type);
471 4 : if ((spec != nullptr) && (spec->hasTimeoutFallback)) {
472 2 : spec->writeUnsupported(ptr);
473 : }
474 4 : return TSD_OK;
475 : }
476 6 : TSD_CHECK(ret == TSD_OK, ret, "Wait capability response from device failed.");
477 5 : const TSD_StatusT saveRet = SaveCapabilityResult(type, ptr);
478 5 : TSD_CHECK(saveRet == TSD_OK, saveRet, "SaveCapabilityResult failed.");
479 5 : return TSD_OK;
480 : }
481 :
482 12 : TSD_StatusT CapabilityManager::CapabilityGet(const int32_t type, const uint64_t ptr)
483 : {
484 12 : if ((!commAgent_.IsInit()) && (type == TSD_CAPABILITY_PIDQOS)) {
485 1 : TSD_WARN("[CapabilityManager] tsd client need open first");
486 1 : return TSD_OK;
487 : }
488 :
489 11 : TSD_RUN_INFO("[CapabilityManager] enter into CapabilityGet process deviceId[%u] type[%d].", logicDeviceId_, type);
490 11 : if (ptr == 0UL) {
491 2 : TSD_ERROR("input ptr is null");
492 2 : return TSD_CLT_OPEN_FAILED;
493 : }
494 9 : if (!IsOkToGetCapability(type)) {
495 1 : TSD_ERROR(
496 : "[CapabilityManager] startCp[%u],type[%d],sessionid[%u]", static_cast<uint32_t>(tsdStartCp_), type,
497 : commAgent_.GetSessionId());
498 1 : return TSD_CLT_OPEN_FAILED;
499 : }
500 8 : if (UseStoredCapabityInfo(type, ptr)) {
501 4 : return TSD_OK;
502 : }
503 4 : TSD_StatusT ret = commAgent_.InitTsdClient(isAdcEnv_);
504 4 : TSD_CHECK(ret == TSD_OK, ret, "Init hdc client failed.");
505 :
506 4 : TSD_CHECK_NULLPTR(
507 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED,
508 : "[CapabilityManager] devCommClient_ is null in Close function.");
509 4 : ret = SendCapabilityMsg(type);
510 4 : TSD_CHECK(ret == TSD_OK, ret, "SendCapabilityMsg failed.");
511 :
512 4 : TSD_RUN_INFO(
513 : "[CapabilityManager][deviceId=%u] [sessionId=%u] [type=%d]send capability successfully.", logicDeviceId_,
514 : commAgent_.GetSessionId(), type);
515 :
516 4 : ret = WaitCapabilityRsp(type, ptr);
517 :
518 4 : TSD_RUN_INFO(
519 : "[CapabilityManager][logicDeviceId_=%u][type=%d][pidQos=%lld][ret=%u]recv capability response finished.",
520 : logicDeviceId_, type, pidQos_, ret);
521 4 : return TSD_OK;
522 : }
523 :
524 18 : TSD_StatusT CapabilityManager::SaveCapabilityResult(const int32_t type, const uint64_t ptr) const
525 : {
526 18 : const CapabilitySpec* spec = FindCapabilitySpec(type);
527 18 : if (spec == nullptr) {
528 1 : return TSD_CLT_OPEN_FAILED;
529 : }
530 17 : return spec->saveResult(*this, ptr);
531 : }
532 :
533 107 : void CapabilityManager::UpdateStateFromMsg(const HDCMessage& msg)
534 : {
535 107 : const HDCMessage::MsgType msgType = msg.type();
536 107 : bool handledBySpec = false;
537 640 : for (const CapabilitySpec& spec : kCapabilitySpecs) {
538 571 : if ((spec.rspMsgType != msgType) || (spec.updateStateFromMsg == nullptr)) {
539 533 : continue;
540 : }
541 38 : spec.updateStateFromMsg(*this, msg);
542 38 : handledBySpec = true;
543 38 : break;
544 : }
545 : // Fallback: for messages other than TSD_GET_SUPPORT_CAPABILITY_LEVEL_RSP,
546 : // any non-zero capability_level still updates tsdSupportLevel_ (legacy
547 : // behaviour preserved). LEVEL_RSP is fully handled by its spec handler
548 : // (which checks rsp_code) and must not be overridden here.
549 107 : if (!handledBySpec || (msgType != HDCMessage::TSD_GET_SUPPORT_CAPABILITY_LEVEL_RSP)) {
550 75 : if (msg.capability_level() != 0U) {
551 12 : tsdSupportLevel_ = msg.capability_level();
552 : }
553 : }
554 107 : }
555 :
556 4 : void CapabilityManager::HandlePidQosRsp(const HDCMessage& msg)
557 : {
558 4 : pidQos_ = msg.pid_of_qos();
559 4 : const uint32_t realDeviceId = msg.real_device_id();
560 4 : const uint32_t deviceId = msg.device_id();
561 4 : const HDCMessage::MsgType msgType = msg.type();
562 4 : TSD_RUN_INFO(
563 : "[TsdClient] PidQosMsgProc recvMsg realDeviceId[%u] msgType[%u] localDevId[%u] rspCode[%u],pidqos[%lld]",
564 : realDeviceId, static_cast<uint32_t>(msgType), deviceId, msg.tsd_rsp_code(), pidQos_);
565 4 : }
566 :
567 : } // namespace tsd
|