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 :
11 : #include "tsd_hdc_common.h"
12 : #include <string>
13 : #include <securec.h>
14 : #include "tsd_util_func.h"
15 : namespace tsd {
16 : namespace {
17 : // message head size
18 : constexpr uint32_t MAX_HEAP_BUFF_BYTE = 0x20000000U;
19 :
20 : // 收发消息中,默认的buf使用个数
21 : constexpr uint32_t HDC_DEFAULT_BUFF_COUNT(1U);
22 :
23 : // 获取接收消息的buff index,当前只有1个buff,固定为0
24 : constexpr uint32_t HDC_DEFAULT_BUFF_INDEX(0U);
25 :
26 : // 消息的头部各字段偏移(int32_t)
27 : constexpr uint32_t HDC_MSG_SEG_COUNT_OFFSET(1U);
28 :
29 : // 0: 非Image type 非0: Image Data
30 : constexpr uint32_t HDC_MSG_SIZE_OFFSET(2U);
31 :
32 : // 短头消息头部长度 12 字节
33 : // msg size(4) + seg count(4) + type size(4)
34 : constexpr uint32_t HDC_MSG_SHORT_HEAD_SIZE(12U);
35 :
36 : // 长头消息头部长度 24 字节
37 : // msg size(4) + seg count(4) + seg index(4)
38 : // + id(4) + total size(4) + type size(4)
39 : constexpr uint32_t HDC_MSG_LONG_HEAD_SIZE(24U);
40 :
41 : // halHdcSend接口超时时间
42 : constexpr uint32_t HDC_CLIENT_SEND_WAIT_TIMEOUT_MS = 150000U; // 150s
43 : } // namespace
44 :
45 : /**
46 : * @ingroup HdcCommon
47 : * @brief HdcCommon默认构造函数,初始化环境标识与消息长度变量
48 : */
49 113 : HdcCommon::HdcCommon() : isAdcEnv_(false), msgMaxSize_(0U), msgShortHeadDataMaxSize_(0U), msgLongHeadDataMaxSize_(0U) {}
50 :
51 : /**
52 : * @ingroup HdcCommon
53 : * @brief InitMsgSize 初始化Msg长度
54 : * return Status成功TSD_OK,失败:其他错误码
55 : */
56 46 : TSD_StatusT HdcCommon::InitMsgSize()
57 : {
58 46 : TSD_INFO("HdcCommon::InitMsgSize Start");
59 : drvHdcCapacity drvHdcCapacityObj;
60 46 : const hdcError_t drvRet = drvHdcGetCapacity(&drvHdcCapacityObj);
61 46 : if ((drvRet != DRV_ERROR_NONE) || (drvHdcCapacityObj.maxSegment <= HDC_MSG_LONG_HEAD_SIZE)) {
62 2 : TSD_ERROR("drvHdcCapacityObj.maxSegment = %u bytes", drvHdcCapacityObj.maxSegment);
63 2 : return TSD_INTERNAL_ERROR;
64 : }
65 :
66 44 : msgMaxSize_ = drvHdcCapacityObj.maxSegment;
67 :
68 44 : msgShortHeadDataMaxSize_ = msgMaxSize_ - HDC_MSG_SHORT_HEAD_SIZE;
69 44 : msgLongHeadDataMaxSize_ = msgMaxSize_ - HDC_MSG_LONG_HEAD_SIZE;
70 44 : TSD_INFO(
71 : "msgMaxSize_ = %u bytes, msgShortHeadDataMaxSize_ = %u bytes, msgLongHeadDataMaxSize_ = %u bytes", msgMaxSize_,
72 : msgShortHeadDataMaxSize_, msgLongHeadDataMaxSize_);
73 44 : return TSD_OK;
74 : }
75 :
76 : /**
77 : * @ingroup HdcCommon
78 : * @brief SendNormalShortMsg 获得普通的短消息
79 : * @param [in] msg : 短消息
80 : * @param [in] size : 长度,上级调用保证size小于GetMsgShortHeadDataMaxSize
81 : * @param [in] session : 会话
82 : * return Status成功TSD_OK,失败:其他错误码
83 : */
84 161 : TSD_StatusT HdcCommon::SendNormalShortMsg(const HDCMessage& msg, const uint32_t size, HDC_SESSION const session)
85 : {
86 161 : if (size == 0U) {
87 1 : TSD_ERROR("SendNormalShortMsg cannot send msg when size = 0");
88 1 : return TSD_HDC_SEND_MSG_ERROR;
89 : }
90 :
91 160 : if (size > (MAX_HEAP_BUFF_BYTE - HDC_MSG_SHORT_HEAD_SIZE)) {
92 1 : TSD_ERROR("Message size[%u] must less than %u", size, MAX_HEAP_BUFF_BYTE - HDC_MSG_SHORT_HEAD_SIZE);
93 1 : return TSD_INTERGER_REVERSED;
94 : }
95 :
96 159 : const uint32_t serialMsgSizeCur = HDC_MSG_SHORT_HEAD_SIZE + size;
97 159 : char_t* serializedMsg = new (std::nothrow) char_t[serialMsgSizeCur];
98 159 : if (serializedMsg == nullptr) {
99 0 : TSD_ERROR("Create serializedMsg failed.");
100 0 : return TSD_HDC_SEND_MSG_ERROR;
101 : }
102 0 : const ScopeGuard memoryGuard([&serializedMsg]() {
103 159 : delete[] serializedMsg;
104 159 : serializedMsg = nullptr;
105 159 : });
106 159 : if (memset_s(serializedMsg, static_cast<size_t>(serialMsgSizeCur), '\0', static_cast<size_t>(serialMsgSizeCur)) !=
107 : 0) {
108 0 : TSD_ERROR("Set memory for serializedMsg failed.");
109 0 : return TSD_HDC_SEND_MSG_ERROR;
110 : }
111 159 : *(PtrToPtr<char_t, uint32_t>(serializedMsg)) = size + HDC_MSG_SHORT_HEAD_SIZE;
112 159 : *(PtrToPtr<char_t, uint32_t>(serializedMsg) + HDC_MSG_SEG_COUNT_OFFSET) = 1U;
113 159 : *(PtrToPtr<char_t, uint32_t>(serializedMsg) + HDC_MSG_SIZE_OFFSET) = 0U;
114 159 : (void)msg.SerializePartialToArray(serializedMsg + HDC_MSG_SHORT_HEAD_SIZE, static_cast<int32_t>(size));
115 159 : const TSD_StatusT result = SendHdcDefaultMsg(session, serializedMsg, serialMsgSizeCur);
116 159 : if (result != TSD_OK) {
117 2 : TSD_CHECK_EQ_RETURN_RUNWARN_LOG(
118 : result == TSD_HDC_SERVER_CLIENT_SOCKET_CLOSED, TSD_HDC_SERVER_CLIENT_SOCKET_CLOSED,
119 : "halHdcSend return socket close");
120 :
121 1 : TSD_CHECK_NO_RETURN(result == TSD_HDC_SERVER_CLIENT_SOCKET_CLOSED, "Send failed ret[%u]", result);
122 1 : return TSD_HDC_SEND_MSG_ERROR;
123 : }
124 157 : return TSD_OK;
125 159 : }
126 :
127 : /**
128 : * @ingroup HdcCommon
129 : * @brief SendNormalMsg 发送普通消息
130 : * @param [in] msg : 普通消息
131 : * @param [int] session : 会话
132 : * return Status成功TSD_OK,失败:其他错误码
133 : */
134 157 : TSD_StatusT HdcCommon::SendNormalMsg(const HDCMessage& msg, HDC_SESSION const session)
135 : {
136 : // 上层调用会打日志,比如扩缩
137 157 : const uint32_t size = static_cast<uint32_t>(msg.ByteSizeLong()); // msg length
138 157 : return SendNormalShortMsg(msg, size, session);
139 : }
140 :
141 : /**
142 : * @ingroup HdcCommon
143 : * @brief Send 发送
144 : * @param [in] session : 会话连接信息
145 : * @param [in] hdcMsgBuf : 消息buffer
146 : * @param [in] size : 消息buffer长度
147 : * return Status成功TSD_OK,失败:其他错误码
148 : */
149 164 : TSD_StatusT HdcCommon::SendHdcDefaultMsg(HDC_SESSION const session, char_t* const hdcMsgBuf, const uint32_t size)
150 : {
151 164 : drvHdcMsg* drvMsg = nullptr;
152 164 : hdcError_t drvRet = drvHdcAllocMsg(session, &drvMsg, static_cast<int32_t>(HDC_DEFAULT_BUFF_COUNT));
153 164 : if (drvMsg == nullptr) {
154 1 : TSD_ERROR("drvHdcAllocMsg failed ret[%d]", drvRet);
155 1 : return TSD_HDC_SEND_ERROR;
156 : }
157 :
158 163 : drvRet = drvHdcAddMsgBuffer(drvMsg, hdcMsgBuf, static_cast<int32_t>(size));
159 163 : if (drvRet != DRV_ERROR_NONE) {
160 1 : TSD_ERROR("drvHdcAddMsgBuffer failed ret[%d]", drvRet);
161 1 : drvRet = drvHdcFreeMsg(drvMsg);
162 1 : TSD_CHECK_NO_RETURN(drvRet == DRV_ERROR_NONE, "drvHdcFreeMsg failed ret[%d]", drvRet);
163 1 : return TSD_HDC_SEND_ERROR;
164 : }
165 :
166 : {
167 162 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
168 : drvRet =
169 162 : halHdcSend(session, drvMsg, static_cast<uint64_t>(HDC_FLAG_WAIT_TIMEOUT), HDC_CLIENT_SEND_WAIT_TIMEOUT_MS);
170 162 : }
171 162 : if (drvRet != DRV_ERROR_NONE) {
172 4 : const hdcError_t drvRetTmp = drvHdcFreeMsg(drvMsg);
173 4 : TSD_CHECK_NO_RETURN(drvRetTmp == DRV_ERROR_NONE, "drvHdcFreeMsg failed ret[%d]", drvRetTmp);
174 4 : TSD_CHECK_EQ_RETURN_RUNWARN_LOG(
175 : drvRet == DRV_ERROR_SOCKET_CLOSE, TSD_HDC_SERVER_CLIENT_SOCKET_CLOSED, "halHdcSend return socket close");
176 2 : TSD_CHECK_NO_RETURN(drvRet == DRV_ERROR_SOCKET_CLOSE, "halHdcSend failed ret[%d]", drvRet);
177 2 : return TSD_HDC_SEND_ERROR;
178 : }
179 :
180 158 : drvRet = drvHdcFreeMsg(drvMsg);
181 158 : if (drvRet != DRV_ERROR_NONE) {
182 1 : TSD_ERROR("drvHdcFreeMsg failed ret[%d]", drvRet);
183 1 : return TSD_HDC_SEND_ERROR;
184 : }
185 157 : return TSD_OK;
186 : }
187 :
188 : /**
189 : * @ingroup HdcCommon
190 : * @brief RecvMsg 接收消息
191 : * @param [in] session : 会话连接唯一标识
192 : * @param [out] msg :消息
193 : * return Status成功TSD_OK,失败:其他错误码
194 : */
195 160 : TSD_StatusT HdcCommon::RecvMsg(HDC_SESSION session, HDCMessage& msg, const uint32_t timeout)
196 : {
197 160 : drvHdcMsg* hdcMsg = nullptr;
198 160 : hdcError_t drvRet = drvHdcAllocMsg(session, &hdcMsg, static_cast<int32_t>(HDC_DEFAULT_BUFF_COUNT));
199 160 : if (hdcMsg == nullptr) {
200 1 : TSD_ERROR("drvHdcAllocMsg failed ret[%d]", drvRet);
201 1 : return TSD_HDC_RECV_MSG_ERROR;
202 : }
203 159 : char_t* tempBuf = nullptr;
204 159 : uint32_t bufferLengthOut = 0U;
205 : // 此处是hiaiengine中hdc代码移植过来,去除了长消息发送功能
206 159 : const TSD_StatusT ret = RecvHdcDefaultMsg(session, hdcMsg, tempBuf, bufferLengthOut, timeout);
207 159 : if ((ret != TSD_OK) || (tempBuf == nullptr) || (bufferLengthOut < HDC_MSG_SHORT_HEAD_SIZE)) {
208 35 : TSD_WARN("Receiving was not successful, ret[%d], bufferLengthOut[%u]", ret, bufferLengthOut);
209 : } else {
210 124 : (void)msg.ParseFromArray(
211 124 : tempBuf + HDC_MSG_SHORT_HEAD_SIZE,
212 124 : static_cast<int32_t>(bufferLengthOut) - static_cast<int32_t>(HDC_MSG_SHORT_HEAD_SIZE));
213 : }
214 159 : drvRet = drvHdcFreeMsg(hdcMsg);
215 159 : if (drvRet != DRV_ERROR_NONE) {
216 1 : TSD_ERROR("drvHdcFreeMsg failed ret[%d]", drvRet);
217 1 : return TSD_HDC_RECV_MSG_ERROR;
218 : }
219 158 : return ret;
220 : }
221 :
222 : /**
223 : * @ingroup HdcCommon
224 : * @brief Receive 接收
225 : * @param [in] session : 会话
226 : * @param [int] drvMsg : 驱动hdc消息
227 : * @param [out] buffer : 解析后的buffer
228 : * @param [out] bufferLengthOut : 解析后的buffer长度
229 : * @param [in] timeout : 超时时长
230 : * return Status成功TSD_OK,失败:其他错误码
231 : */
232 165 : TSD_StatusT HdcCommon::RecvHdcDefaultMsg(
233 : const HDC_SESSION& session, drvHdcMsg* drvMsg, char_t*& buffer, uint32_t& bufferLengthOut, const uint32_t timeout)
234 : {
235 165 : int32_t recvBufCounter = 0;
236 165 : int32_t receivedLenEachTime = 0;
237 165 : hdcError_t drvRet = DRV_ERROR_NONE;
238 : {
239 165 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
240 165 : drvRet = halHdcRecv(
241 165 : session, drvMsg, static_cast<int32_t>(GetMsgMaxSize()), static_cast<uint64_t>(HDC_FLAG_WAIT_TIMEOUT),
242 : &recvBufCounter, timeout);
243 165 : }
244 :
245 165 : if (drvRet != DRV_ERROR_NONE) {
246 41 : if (!isAdcEnv_) {
247 41 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
248 41 : int32_t value = 0;
249 41 : const auto ret = halHdcGetSessionAttr(session, HDC_SESSION_ATTR_DFX, &value);
250 41 : if (ret != DRV_ERROR_NONE) {
251 1 : TSD_RUN_INFO("halHdcGetSessionAttr HDC_SESSION_ATTR_DFX was not successful, ret[%d].", ret);
252 : }
253 41 : if (value < 0) {
254 1 : TSD_RUN_INFO("halHdcGetSessionAttr HDC_SESSION_ATTR_DFX was not successful, value[%d].", value);
255 : }
256 41 : TSD_INFO("halHdcGetSessionAttr HDC_SESSION_ATTR_DFX finish");
257 41 : }
258 41 : TSD_RUN_INFO("halHdcRecv ret[%d]", drvRet);
259 41 : if (drvRet == DRV_ERROR_SOCKET_CLOSE) {
260 3 : return TSD_HDC_SERVER_CLIENT_SOCKET_CLOSED;
261 : }
262 38 : return TSD_HDC_RECV_MSG_ERROR;
263 : }
264 :
265 124 : drvRet = drvHdcGetMsgBuffer(drvMsg, static_cast<int32_t>(HDC_DEFAULT_BUFF_INDEX), &buffer, &receivedLenEachTime);
266 124 : if (drvRet != DRV_ERROR_NONE) {
267 0 : TSD_ERROR("drvHdcGetMsgBuffer failed ret[%d]", drvRet);
268 0 : return TSD_HDC_RECV_MSG_ERROR;
269 : }
270 :
271 124 : if (buffer == nullptr) {
272 0 : TSD_ERROR("drvHdcGetMsgBuffer buffer is null");
273 0 : return TSD_HDC_RECV_MSG_ERROR;
274 : }
275 : // start check head
276 124 : const uint32_t currMsgSize = *(PtrToPtr<char_t, uint32_t>(buffer));
277 124 : if (static_cast<uint32_t>(receivedLenEachTime) != currMsgSize) {
278 0 : TSD_ERROR("length not match receivedLenEachTime[%d], currMsgSize[%u]", receivedLenEachTime, currMsgSize);
279 0 : return TSD_HDC_RECV_MSG_ERROR;
280 : }
281 124 : bufferLengthOut = static_cast<uint32_t>(receivedLenEachTime);
282 124 : return TSD_OK;
283 : }
284 :
285 : /**
286 : * @ingroup HdcCommon
287 : * @brief 创建VersionVerify实例
288 : * @return VersionVerify实例
289 : */
290 56 : std::shared_ptr<VersionVerify> HdcCommon::MakeVersionVerifyNoThrow() const
291 : {
292 : try {
293 56 : return std::make_shared<VersionVerify>();
294 0 : } catch (...) {
295 0 : return std::shared_ptr<VersionVerify>();
296 0 : }
297 : }
298 :
299 : /**
300 : * @ingroup HdcCommon
301 : * @brief 查询HDC session当前的连接状态属性
302 : * @param [in] session : HDC session句柄
303 : * @param [out] hdcSessStat : 返回的session状态
304 : * @return TSD_OK:成功 或者其他错误码
305 : */
306 7 : TSD_StatusT HdcCommon::GetHdcAttrStatus(HDC_SESSION session, int32_t& hdcSessStat)
307 : {
308 7 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
309 7 : const hdcError_t drvRet = halHdcGetSessionAttr(session, HDC_SESSION_ATTR_STATUS, &hdcSessStat);
310 7 : if (drvRet != DRV_ERROR_NONE) {
311 2 : TSD_ERROR("halHdcGetSessionAttr failed ret[%d]", drvRet);
312 2 : return TSD_HDC_SESSION_STATUS_GET_FAILED;
313 : }
314 5 : return TSD_OK;
315 7 : }
316 : } // namespace tsd
|