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