Line data Source code
1 : /**
2 : * Copyright (c) 2025 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 : #include "hdc_comm_opt.h"
11 : #include "hdc_api.h"
12 : #include "device/adx_dsmi.h"
13 : #include "log/adx_log.h"
14 : #include "device/adx_hdc_device.h"
15 : #include "mmpa_api.h"
16 : namespace Adx {
17 0 : std::string HdcCommOpt::CommOptName() { return "HDC"; }
18 :
19 116 : OptType HdcCommOpt::GetOptType() { return OptType::COMM_HDC; }
20 :
21 24 : OptHandle HdcCommOpt::OpenServer(const std::map<std::string, std::string>& info)
22 : {
23 24 : if (info.empty() || info.size() < 1) {
24 1 : IDE_LOGE("open server input invalid");
25 1 : return ADX_OPT_INVALID_HANDLE;
26 : }
27 :
28 : int32_t devId;
29 : drvHdcServiceType type;
30 : try {
31 23 : auto device = info.find(OPT_DEVICE_KEY);
32 23 : if (device == info.end()) {
33 1 : IDE_LOGE("open server input parameter invalid, DeviceId not found.");
34 2 : return ADX_OPT_INVALID_HANDLE;
35 : }
36 :
37 22 : auto service = info.find(OPT_SERVICE_KEY);
38 22 : if (service == info.end()) {
39 1 : IDE_LOGE("open server input parameter invalid, ServiceType not found");
40 1 : return ADX_OPT_INVALID_HANDLE;
41 : }
42 21 : devId = std::stoi(device->second); // device id
43 21 : type = (drvHdcServiceType)std::stoi(service->second); // service type
44 1 : } catch (...) {
45 1 : IDE_LOGE("Value of device id or service type is not a number");
46 1 : return ADX_OPT_INVALID_HANDLE;
47 1 : }
48 :
49 20 : if (type >= HDC_SERVICE_TYPE_MAX || devId < 0) {
50 1 : return ADX_OPT_INVALID_HANDLE;
51 : }
52 :
53 19 : IDE_RUN_LOGI("open device[%d] server[%d]", devId, type);
54 19 : HDC_SERVER server = HdcServerCreate(devId, type);
55 19 : if (server == nullptr) {
56 0 : return ADX_OPT_INVALID_HANDLE;
57 : }
58 :
59 19 : return (OptHandle)server;
60 : }
61 :
62 22 : int32_t HdcCommOpt::CloseServer(const OptHandle& handle) const
63 : {
64 22 : if (handle == ADX_OPT_INVALID_HANDLE) {
65 1 : IDE_LOGE("close server input invalid");
66 1 : return IDE_DAEMON_ERROR;
67 : }
68 :
69 21 : IDE_RUN_LOGI("close device server[%u]", static_cast<uint32_t>(handle));
70 21 : return HdcServerDestroy(reinterpret_cast<HDC_SERVER>(handle));
71 : }
72 :
73 32 : OptHandle HdcCommOpt::OpenClient(const std::map<std::string, std::string>& info)
74 : {
75 32 : if (info.empty() || info.size() == 0) {
76 1 : IDE_LOGE("open client input invalid");
77 1 : return ADX_OPT_INVALID_HANDLE;
78 : }
79 :
80 : drvHdcServiceType type;
81 : try {
82 31 : auto service = info.find(OPT_SERVICE_KEY);
83 31 : if (service == info.end()) {
84 1 : IDE_LOGE("open client input parameter invalid, ServiceType not found");
85 1 : return ADX_OPT_INVALID_HANDLE;
86 : }
87 30 : type = (drvHdcServiceType)std::stoi(service->second); // service type
88 1 : } catch (...) {
89 1 : IDE_LOGE("Value of service type is not a number");
90 1 : return ADX_OPT_INVALID_HANDLE;
91 1 : }
92 :
93 29 : if (type >= HDC_SERVICE_TYPE_MAX) {
94 1 : IDE_LOGE("open client input type out of range");
95 1 : return ADX_OPT_INVALID_HANDLE;
96 : }
97 :
98 28 : HDC_CLIENT session = HdcClientCreate(type);
99 28 : if (session == nullptr) {
100 0 : IDE_LOGE("hdc client create exception");
101 0 : return ADX_OPT_INVALID_HANDLE;
102 : }
103 :
104 28 : return (OptHandle)session;
105 : }
106 :
107 27 : int32_t HdcCommOpt::CloseClient(OptHandle& handle) const
108 : {
109 27 : IDE_CTRL_VALUE_FAILED(handle != ADX_OPT_INVALID_HANDLE, return IDE_DAEMON_ERROR, "hdc close client input invalid");
110 26 : return HdcClientDestroy((HDC_CLIENT)handle);
111 : }
112 :
113 13 : OptHandle HdcCommOpt::Accept(const OptHandle handle) const
114 : {
115 13 : IDE_CTRL_VALUE_FAILED(handle != ADX_OPT_INVALID_HANDLE, return ADX_OPT_INVALID_HANDLE, "hdc accept input invalid");
116 12 : HDC_SESSION session = HdcServerAccept((HDC_SERVER)handle);
117 12 : if (session == nullptr) {
118 2 : return ADX_OPT_INVALID_HANDLE;
119 : }
120 :
121 10 : return (OptHandle)session;
122 : }
123 :
124 40 : OptHandle HdcCommOpt::Connect(const OptHandle handle, const std::map<std::string, std::string>& info)
125 : {
126 40 : IDE_CTRL_VALUE_FAILED(handle != ADX_OPT_INVALID_HANDLE, return ADX_OPT_INVALID_HANDLE, "hdc connect input invalid");
127 39 : IDE_CTRL_VALUE_FAILED(!info.empty(), return ADX_OPT_INVALID_HANDLE, "hdc connect input invalid");
128 :
129 : int32_t devId;
130 38 : auto device = info.find(OPT_DEVICE_KEY);
131 38 : if (device == info.end()) {
132 1 : IDE_LOGE("connect input parameter invalid, DeviceId not found");
133 1 : return ADX_OPT_INVALID_HANDLE;
134 : }
135 : try {
136 37 : devId = std::stoi(device->second);
137 1 : } catch (...) {
138 1 : IDE_LOGE("Value of device id is not a number");
139 1 : return ADX_OPT_INVALID_HANDLE;
140 1 : }
141 36 : IDE_CTRL_VALUE_FAILED(devId >= 0 && devId < DEVICE_NUM_MAX, return ADX_OPT_INVALID_HANDLE, "devId invalid");
142 36 : HDC_SESSION session = nullptr;
143 : int32_t err;
144 : try {
145 36 : auto host = info.find(OPT_PID_KEY);
146 36 : if (host == info.end()) {
147 29 : err = HdcSessionConnect(0, devId, (HDC_CLIENT)handle, &session);
148 : } else {
149 7 : int32_t hostPid = std::stoi(host->second);
150 6 : if (hostPid < 0) {
151 1 : return ADX_OPT_INVALID_HANDLE;
152 : }
153 5 : err = HalHdcSessionConnect(0, devId, hostPid, (HDC_CLIENT)handle, &session);
154 : }
155 1 : } catch (...) {
156 1 : IDE_LOGE("Value of host pid is not a number");
157 1 : return ADX_OPT_INVALID_HANDLE;
158 1 : }
159 :
160 34 : if (err != IDE_DAEMON_OK) {
161 4 : IDE_LOGE("hdc connect error: %d", err);
162 4 : return ADX_OPT_INVALID_HANDLE;
163 : }
164 :
165 30 : return (OptHandle)session;
166 : }
167 :
168 38 : int32_t HdcCommOpt::Close(OptHandle& handle) const
169 : {
170 38 : IDE_CTRL_VALUE_WARN(
171 : handle != ADX_OPT_INVALID_HANDLE, return IDE_DAEMON_OK,
172 : "hdc handle is invalid. maybe has been closed or not connected");
173 :
174 37 : HDC_SESSION session = (HDC_SESSION)handle;
175 37 : int32_t ret = HdcSessionClose(session);
176 37 : session = nullptr;
177 37 : handle = ADX_OPT_INVALID_HANDLE;
178 37 : return ret;
179 : }
180 :
181 20 : int32_t HdcCommOpt::Write(const OptHandle handle, IdeSendBuffT buffer, int32_t length, int32_t flag)
182 : {
183 20 : IDE_CTRL_VALUE_FAILED(handle != ADX_OPT_INVALID_HANDLE, return IDE_DAEMON_ERROR, "hdc write input invalid");
184 19 : IDE_CTRL_VALUE_FAILED(buffer != nullptr, return IDE_DAEMON_ERROR, "hdc write input invalid");
185 18 : IDE_CTRL_VALUE_FAILED(length > 0, return IDE_DAEMON_ERROR, "hdc write input invalid");
186 :
187 17 : if (flag == COMM_OPT_BLOCK) {
188 16 : return HdcWrite((HDC_SESSION)handle, buffer, length);
189 : }
190 :
191 1 : return HdcWriteNb((HDC_SESSION)handle, buffer, length);
192 : }
193 :
194 53 : int32_t HdcCommOpt::Read(const OptHandle handle, IdeRecvBuffT buffer, int32_t& length, int32_t flag)
195 : {
196 53 : IDE_CTRL_VALUE_FAILED(handle != ADX_OPT_INVALID_HANDLE, return IDE_DAEMON_ERROR, "hdc read input invalid");
197 52 : IDE_CTRL_VALUE_FAILED(buffer != nullptr, return IDE_DAEMON_ERROR, "hdc read input invalid");
198 :
199 51 : if (flag == COMM_OPT_BLOCK) {
200 17 : return HdcRead(reinterpret_cast<HDC_SESSION>(handle), buffer, &length);
201 : }
202 :
203 34 : if (flag != COMM_OPT_NOBLOCK) {
204 23 : return HdcReadTimeout(reinterpret_cast<HDC_SESSION>(handle), static_cast<uint32_t>(flag), buffer, &length);
205 : }
206 :
207 : // 在投片验证阶段FPGA场景下,因hdc传输性能较差,需将maxRetryTimes设置为800,保证通过hdc接收数据成功
208 : // 在常规场景下,当hdc对端未能成功发送数据时,若maxRetryTimes设置为800,等待时间过长会影响用户体验,需修改为142
209 11 : const int32_t maxRetryTimes = 142; // 10s (1 + 2 + ... + 142)ms;
210 : int32_t err;
211 11 : int32_t retryTime = 1;
212 11 : while (retryTime < maxRetryTimes) {
213 11 : err = HdcReadNb(reinterpret_cast<HDC_SESSION>(handle), buffer, &length);
214 11 : if (err == IDE_DAEMON_RECV_NODATA) {
215 0 : mmSleep(retryTime);
216 0 : retryTime++;
217 : } else {
218 11 : break;
219 : }
220 : }
221 :
222 11 : if (retryTime >= maxRetryTimes) {
223 0 : IDE_LOGW("no received request in %d times", retryTime);
224 0 : err = IDE_DAEMON_ERROR;
225 : }
226 11 : return err;
227 : }
228 :
229 10 : SharedPtr<AdxDevice> HdcCommOpt::GetDevice()
230 : {
231 10 : if (device_ == nullptr) {
232 : try {
233 2 : device_ = std::make_shared<AdxHdcDevice>();
234 0 : } catch (...) {
235 0 : IDE_LOGE("Failed to get hdc device.");
236 0 : return nullptr;
237 0 : }
238 : }
239 :
240 10 : return device_;
241 : }
242 :
243 9 : void HdcCommOpt::Timer(void) const {}
244 : } // namespace Adx
|