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 124 : 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 49 : TSD_StatusT HdcCommon::InitMsgSize()
57 : {
58 49 : TSD_INFO("HdcCommon::InitMsgSize Start");
59 : drvHdcCapacity drvHdcCapacityObj;
60 49 : const hdcError_t drvRet = drvHdcGetCapacity(&drvHdcCapacityObj);
61 49 : 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 47 : msgMaxSize_ = drvHdcCapacityObj.maxSegment;
67 :
68 47 : msgShortHeadDataMaxSize_ = msgMaxSize_ - HDC_MSG_SHORT_HEAD_SIZE;
69 47 : msgLongHeadDataMaxSize_ = msgMaxSize_ - HDC_MSG_LONG_HEAD_SIZE;
70 47 : TSD_INFO(
71 : "msgMaxSize_ = %u bytes, msgShortHeadDataMaxSize_ = %u bytes, msgLongHeadDataMaxSize_ = %u bytes", msgMaxSize_,
72 : msgShortHeadDataMaxSize_, msgLongHeadDataMaxSize_);
73 47 : 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 167 : TSD_StatusT HdcCommon::SendNormalShortMsg(const HDCMessage& msg, const uint32_t size, HDC_SESSION const session)
85 : {
86 167 : 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 166 : 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 165 : const uint32_t serialMsgSizeCur = HDC_MSG_SHORT_HEAD_SIZE + size;
97 165 : char_t* serializedMsg = new (std::nothrow) char_t[serialMsgSizeCur];
98 165 : 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 165 : delete[] serializedMsg;
104 165 : serializedMsg = nullptr;
105 165 : });
106 165 : 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 165 : *(PtrToPtr<char_t, uint32_t>(serializedMsg)) = size + HDC_MSG_SHORT_HEAD_SIZE;
112 165 : *(PtrToPtr<char_t, uint32_t>(serializedMsg) + HDC_MSG_SEG_COUNT_OFFSET) = 1U;
113 165 : *(PtrToPtr<char_t, uint32_t>(serializedMsg) + HDC_MSG_SIZE_OFFSET) = 0U;
114 165 : (void)msg.SerializePartialToArray(serializedMsg + HDC_MSG_SHORT_HEAD_SIZE, static_cast<int32_t>(size));
115 165 : const TSD_StatusT result = SendHdcDefaultMsg(session, serializedMsg, serialMsgSizeCur);
116 165 : 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 163 : return TSD_OK;
125 165 : }
126 :
127 : /**
128 : * @ingroup HdcCommon
129 : * @brief SendNormalMsg 发送普通消息
130 : * @param [in] msg : 普通消息
131 : * @param [int] session : 会话
132 : * return Status成功TSD_OK,失败:其他错误码
133 : */
134 163 : TSD_StatusT HdcCommon::SendNormalMsg(const HDCMessage& msg, HDC_SESSION const session)
135 : {
136 : // 上层调用会打日志,比如扩缩
137 163 : const uint32_t size = static_cast<uint32_t>(msg.ByteSizeLong()); // msg length
138 163 : 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 170 : TSD_StatusT HdcCommon::SendHdcDefaultMsg(HDC_SESSION const session, char_t* const hdcMsgBuf, const uint32_t size)
150 : {
151 170 : drvHdcMsg* drvMsg = nullptr;
152 170 : hdcError_t drvRet = drvHdcAllocMsg(session, &drvMsg, static_cast<int32_t>(HDC_DEFAULT_BUFF_COUNT));
153 170 : if (drvMsg == nullptr) {
154 1 : TSD_ERROR("drvHdcAllocMsg failed ret[%d]", drvRet);
155 1 : return TSD_HDC_SEND_ERROR;
156 : }
157 :
158 169 : drvRet = drvHdcAddMsgBuffer(drvMsg, hdcMsgBuf, static_cast<int32_t>(size));
159 169 : 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 168 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
168 : drvRet =
169 168 : halHdcSend(session, drvMsg, static_cast<uint64_t>(HDC_FLAG_WAIT_TIMEOUT), HDC_CLIENT_SEND_WAIT_TIMEOUT_MS);
170 168 : }
171 168 : 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 164 : drvRet = drvHdcFreeMsg(drvMsg);
181 164 : if (drvRet != DRV_ERROR_NONE) {
182 1 : TSD_ERROR("drvHdcFreeMsg failed ret[%d]", drvRet);
183 1 : return TSD_HDC_SEND_ERROR;
184 : }
185 163 : 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 169 : TSD_StatusT HdcCommon::RecvMsg(HDC_SESSION session, HDCMessage& msg, const uint32_t timeout)
196 : {
197 169 : drvHdcMsg* hdcMsg = nullptr;
198 169 : hdcError_t drvRet = drvHdcAllocMsg(session, &hdcMsg, static_cast<int32_t>(HDC_DEFAULT_BUFF_COUNT));
199 169 : if (hdcMsg == nullptr) {
200 1 : TSD_ERROR("drvHdcAllocMsg failed ret[%d]", drvRet);
201 1 : return TSD_HDC_RECV_MSG_ERROR;
202 : }
203 168 : char_t* tempBuf = nullptr;
204 168 : uint32_t bufferLengthOut = 0U;
205 : // 此处是hiaiengine中hdc代码移植过来,去除了长消息发送功能
206 168 : const TSD_StatusT ret = RecvHdcDefaultMsg(session, hdcMsg, tempBuf, bufferLengthOut, timeout);
207 168 : if ((ret != TSD_OK) || (tempBuf == nullptr) || (bufferLengthOut < HDC_MSG_SHORT_HEAD_SIZE)) {
208 31 : TSD_WARN("Receiving was not successful, ret[%d], bufferLengthOut[%u]", ret, bufferLengthOut);
209 : } else {
210 137 : (void)msg.ParseFromArray(
211 137 : tempBuf + HDC_MSG_SHORT_HEAD_SIZE,
212 137 : static_cast<int32_t>(bufferLengthOut) - static_cast<int32_t>(HDC_MSG_SHORT_HEAD_SIZE));
213 : }
214 168 : drvRet = drvHdcFreeMsg(hdcMsg);
215 168 : if (drvRet != DRV_ERROR_NONE) {
216 1 : TSD_ERROR("drvHdcFreeMsg failed ret[%d]", drvRet);
217 1 : return TSD_HDC_RECV_MSG_ERROR;
218 : }
219 167 : 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 173 : TSD_StatusT HdcCommon::RecvHdcDefaultMsg(
233 : const HDC_SESSION& session, drvHdcMsg* drvMsg, char_t*& buffer, uint32_t& bufferLengthOut, const uint32_t timeout)
234 : {
235 173 : int32_t recvBufCounter = 0;
236 173 : int32_t receivedLenEachTime = 0;
237 173 : hdcError_t drvRet = DRV_ERROR_NONE;
238 : {
239 173 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
240 173 : drvRet = halHdcRecv(
241 173 : session, drvMsg, static_cast<int32_t>(GetMsgMaxSize()), static_cast<uint64_t>(HDC_FLAG_WAIT_TIMEOUT),
242 : &recvBufCounter, timeout);
243 173 : }
244 :
245 173 : if (drvRet != DRV_ERROR_NONE) {
246 36 : if (!isAdcEnv_) {
247 36 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
248 36 : int32_t value = 0;
249 36 : const auto ret = halHdcGetSessionAttr(session, HDC_SESSION_ATTR_DFX, &value);
250 36 : if (ret != DRV_ERROR_NONE) {
251 1 : TSD_RUN_INFO("halHdcGetSessionAttr HDC_SESSION_ATTR_DFX was not successful, ret[%d].", ret);
252 : }
253 36 : if (value < 0) {
254 1 : TSD_RUN_INFO("halHdcGetSessionAttr HDC_SESSION_ATTR_DFX was not successful, value[%d].", value);
255 : }
256 36 : TSD_INFO("halHdcGetSessionAttr HDC_SESSION_ATTR_DFX finish");
257 36 : }
258 36 : TSD_RUN_INFO("halHdcRecv ret[%d]", drvRet);
259 36 : if (drvRet == DRV_ERROR_SOCKET_CLOSE) {
260 3 : return TSD_HDC_SERVER_CLIENT_SOCKET_CLOSED;
261 : }
262 33 : return TSD_HDC_RECV_MSG_ERROR;
263 : }
264 :
265 137 : drvRet = drvHdcGetMsgBuffer(drvMsg, static_cast<int32_t>(HDC_DEFAULT_BUFF_INDEX), &buffer, &receivedLenEachTime);
266 137 : 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 137 : 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 137 : const uint32_t currMsgSize = *(PtrToPtr<char_t, uint32_t>(buffer));
277 137 : 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 137 : bufferLengthOut = static_cast<uint32_t>(receivedLenEachTime);
282 137 : return TSD_OK;
283 : }
284 :
285 : /**
286 : * @ingroup HdcCommon
287 : * @brief 创建VersionVerify实例
288 : * @return VersionVerify实例
289 : */
290 60 : std::shared_ptr<VersionVerify> HdcCommon::MakeVersionVerifyNoThrow() const
291 : {
292 : try {
293 60 : 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 6 : TSD_StatusT HdcCommon::GetHdcAttrStatus(HDC_SESSION session, int32_t& hdcSessStat)
307 : {
308 6 : const std::lock_guard<std::mutex> lk(hdcSessionMutex_);
309 6 : const hdcError_t drvRet = halHdcGetSessionAttr(session, HDC_SESSION_ATTR_STATUS, &hdcSessStat);
310 6 : 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 4 : return TSD_OK;
315 6 : }
316 : } // namespace tsd
|