LCOV - code coverage report
Current view: top level - basic_component/device_comm - hdc_common.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.9 % 139 125
Test Date: 2026-07-28 10:52:48 Functions: 100.0 % 10 10

            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
        

Generated by: LCOV version 2.0-1