LCOV - code coverage report
Current view: top level - adump/device - adx_dump_hdc_helper.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.7 % 128 125
Test Date: 2026-08-31 10:09:28 Functions: 92.3 % 13 12

            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 "ascend_hal.h"
      11              : #include "protocol/adx_msg_proto.h"
      12              : #include "adx_datadump_callback.h"
      13              : #include "log/adx_log.h"
      14              : #include "memory_utils.h"
      15              : #include "hdc_api.h"
      16              : #include "adcore_api.h"
      17              : #include "string_utils.h"
      18              : #include "create_func.h"
      19              : #include "sys_utils.h"
      20              : #include "config.h"
      21              : #include "adx_dump_hdc_helper.h"
      22              : 
      23              : namespace Adx {
      24            1 : AdxDumpHdcHelper::AdxDumpHdcHelper() : init_(false)
      25              : {
      26            1 :     client_.type = NR_COMM;
      27            1 :     client_.session = 0U;
      28            1 :     client_.comp = NR_COMPONENTS;
      29            1 :     client_.timeout = 0;
      30            1 :     client_.client = nullptr;
      31            1 : }
      32              : 
      33            1 : AdxDumpHdcHelper::~AdxDumpHdcHelper() { UnInit(); }
      34              : 
      35            2 : bool AdxDumpHdcHelper::Init()
      36              : {
      37            2 :     if (!init_) {
      38            1 :         std::unique_ptr<AdxCommOpt> opt(CreateAdxCommOpt(OptType::COMM_HDC));
      39            1 :         IDE_CTRL_VALUE_FAILED(opt != nullptr, return false, "create hdc commopt exception");
      40            1 :         bool ret = AdxCommOptManager::Instance().CommOptsRegister(opt);
      41            1 :         IDE_CTRL_VALUE_FAILED(ret, return false, "register hdc failed");
      42            1 :         std::map<std::string, std::string> info;
      43            1 :         info[OPT_SERVICE_KEY] = std::to_string(HDC_SERVICE_TYPE_DUMP);
      44            1 :         client_ = AdxCommOptManager::Instance().OpenClient(OptType::COMM_HDC, info);
      45            1 :         IDE_CTRL_VALUE_FAILED(client_.session != ADX_OPT_INVALID_HANDLE, return false, "open client failed");
      46            1 :         IDE_LOGI("dump data client init end<%lu, %d>", client_.session, static_cast<int32_t>(client_.type));
      47            1 :         init_ = true;
      48            1 :     }
      49            2 :     return true;
      50              : }
      51              : 
      52            1 : void AdxDumpHdcHelper::UnInit()
      53              : {
      54            1 :     if (init_) {
      55            1 :         IDE_LOGI("dump data client close <%lu, %d>", client_.session, static_cast<int32_t>(client_.type));
      56            1 :         HdcClientDestroy(reinterpret_cast<HDC_CLIENT>(client_.session));
      57            1 :         init_ = false;
      58              :     }
      59            1 : }
      60              : 
      61              : /**
      62              :  * @brief      parse connect info
      63              :  * @param [in] connectInfo: string of connect info
      64              :  * @param [in] proto: struct of conect info
      65              :  *
      66              :  * @return
      67              :  *      IDE_DAEMON_NONE_ERROR: parse connect info success
      68              :  *      IDE_DAEMON_INVALID_PARAM_ERROR: parse connect info failed
      69              :  */
      70            8 : IdeErrorT AdxDumpHdcHelper::ParseConnectInfo(
      71              :     const std::string& connectInfo, std::map<std::string, std::string>& proto) const
      72              : {
      73            8 :     std::string hostId;
      74            8 :     std::string hostPid;
      75            8 :     bool ret = StringUtils::ParseConnectInfo(connectInfo, hostId, hostPid);
      76            8 :     IDE_CTRL_VALUE_FAILED(ret == true, return IDE_DAEMON_INVALID_PARAM_ERROR, "ParseConnectInfo failed");
      77            5 :     std::string helperHostPid;
      78            5 :     ADX_GET_ENV(MM_ENV_ASCEND_HOSTPID, helperHostPid);
      79            5 :     if (!helperHostPid.empty() && StringUtils::IsIntDigital(helperHostPid)) {
      80            1 :         hostPid = helperHostPid;
      81              :     }
      82            5 :     proto[OPT_DEVICE_KEY] = hostId;
      83            5 :     proto[OPT_PID_KEY] = hostPid;
      84            5 :     return IDE_DAEMON_NONE_ERROR;
      85            8 : }
      86              : 
      87            2 : IdeErrorT AdxDumpHdcHelper::HandShake(const std::string& info, IDE_SESSION& session) const
      88              : {
      89            2 :     uint16_t devId = 0;
      90            2 :     std::map<std::string, std::string> proto;
      91            2 :     IdeErrorT err = ParseConnectInfo(info, proto);
      92            2 :     IDE_CTRL_VALUE_FAILED(err == IDE_DAEMON_NONE_ERROR, return err, "parse connect info failed");
      93            2 :     IDE_LOGI("proto: hostId: %s, hostPid: %s", proto[OPT_DEVICE_KEY].c_str(), proto[OPT_PID_KEY].c_str());
      94            2 :     CommHandle handle = AdxCommOptManager::Instance().Connect(client_, proto);
      95            2 :     IDE_CTRL_VALUE_FAILED(
      96              :         handle.session != ADX_OPT_INVALID_HANDLE, return IDE_DAEMON_INVALID_PARAM_ERROR, "dump data connect failed");
      97            2 :     err = AdxMsgProto::SendResponse(handle, IDE_DUMP_REQ, devId, MsgStatus::MSG_STATUS_HAND_SHAKE);
      98            2 :     IDE_CTRL_VALUE_FAILED(err == IDE_DAEMON_NONE_ERROR, return err, "dump data handshake failed");
      99              : 
     100            1 :     err = AdxMsgProto::RecvResponse(handle);
     101            1 :     IDE_CTRL_VALUE_FAILED(err == IDE_DAEMON_NONE_ERROR, return err, "dump data handshake response failed");
     102              : 
     103            1 :     session = reinterpret_cast<HDC_SESSION>(handle.session);
     104            1 :     IDE_LOGD("handshake success");
     105            1 :     return IDE_DAEMON_NONE_ERROR;
     106            2 : }
     107              : 
     108            3 : IdeErrorT AdxDumpHdcHelper::DataProcess(const IDE_SESSION& session, const IdeDumpChunk& dumpChunk)
     109              : {
     110            3 :     uint32_t dataLen = 0;
     111              :     // malloc memory for save user data
     112            3 :     IDE_RETURN_IF_CHECK_ASSIGN_32U_ADD(
     113              :         sizeof(DumpChunk), dumpChunk.bufLen, dataLen, return IDE_DAEMON_INTERGER_REVERSED_ERROR);
     114            3 :     MsgProto* msg = AdxMsgProto::CreateMsgPacket(IDE_DUMP_REQ, 0, nullptr, dataLen);
     115            3 :     IDE_CTRL_VALUE_FAILED(msg != nullptr, return IDE_DAEMON_MALLOC_ERROR, "create message failed");
     116            3 :     std::unique_ptr<MsgProto, decltype(&IdeXfree)> sendDataMsgPtr(msg, IdeXfree);
     117            3 :     msg = nullptr;
     118            3 :     DumpChunk* data = reinterpret_cast<DumpChunk*>(sendDataMsgPtr->data);
     119              :     // check file name length, not longer than IDE_MAX_FILE_PATH
     120            3 :     IDE_CTRL_VALUE_FAILED(
     121              :         strlen(dumpChunk.fileName) < IDE_MAX_FILE_PATH, return IDE_DAEMON_INVALID_PATH_ERROR,
     122              :         "fileName is too long, not longer than %d length", IDE_MAX_FILE_PATH);
     123            3 :     int32_t err = strcpy_s(data->fileName, MAX_FILE_PATH_LENGTH, dumpChunk.fileName);
     124            3 :     IDE_CTRL_VALUE_FAILED(
     125              :         err == EOK, return IDE_DAEMON_INVALID_PATH_ERROR, "copy file name failed, err=%d, strerror=%s", err,
     126              :         strerror(errno));
     127            3 :     data->bufLen = dumpChunk.bufLen;
     128            3 :     data->flag = dumpChunk.flag;
     129            3 :     data->isLastChunk = dumpChunk.isLastChunk;
     130            3 :     data->offset = dumpChunk.offset;
     131            3 :     IDE_LOGI(
     132              :         "dataLen: %u, bufLen: %u, flag: %d, isLastChunk: %u, offset: %ld, fileName: %s", dataLen, data->bufLen,
     133              :         data->flag, data->isLastChunk, data->offset, data->fileName);
     134            3 :     err = memcpy_s(data->dataBuf, data->bufLen, dumpChunk.dataBuf, dumpChunk.bufLen);
     135            3 :     IDE_CTRL_VALUE_FAILED(err == EOK, return IDE_DAEMON_MEMCPY_ERROR, "memcpy_s data buffer failed, err=%d", err);
     136            3 :     IDE_LOGI("the data to be sent has been assembled");
     137              :     CommHandle handle;
     138            3 :     handle.type = client_.type;
     139            3 :     handle.session = reinterpret_cast<OptHandle>(session);
     140            3 :     IdeErrorT code = SessionIsConnected(handle);
     141            3 :     IDE_CTRL_VALUE_WARN(
     142              :         code == IDE_DAEMON_NONE_ERROR, return code, "check session status failed, err=%d", static_cast<int32_t>(code));
     143            4 :     uint32_t ret = AdxCommOptManager::Instance().Write(
     144            2 :         handle, sendDataMsgPtr.get(), sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
     145            2 :     IDE_CTRL_VALUE_WARN(
     146              :         ret != IDE_DAEMON_SOCK_CLOSE, return IDE_DAEMON_CHANNEL_ERROR,
     147              :         "write dump data error, session[%zu] has been closed, ret: %d", handle.session, ret);
     148            2 :     IDE_CTRL_VALUE_FAILED(
     149              :         ret == IDE_DAEMON_OK, return IDE_DAEMON_WRITE_ERROR, "write dump data error, session: %zu, ret: %d",
     150              :         handle.session, ret);
     151            1 :     code = AdxMsgProto::RecvResponse(handle);
     152            1 :     IDE_CTRL_VALUE_FAILED(
     153              :         (code == IDE_DAEMON_NONE_ERROR) || (code == IDE_DAEMON_DUMP_QUEUE_FULL), return code,
     154              :         "send file shake response failed, ret=%d", static_cast<int32_t>(code));
     155            1 :     IDE_LOGD("dump data process normal");
     156            1 :     return code;
     157            3 : }
     158              : 
     159            3 : IdeErrorT AdxDumpHdcHelper::SessionIsConnected(const CommHandle handle) const
     160              : {
     161            3 :     int32_t status = 0;
     162            3 :     int32_t ret = AdxGetAttrByCommHandle(&handle, HDC_SESSION_ATTR_STATUS, &status);
     163            3 :     if (ret != IDE_DAEMON_OK || status != HDC_SESSION_STATUS_CONNECT) {
     164            1 :         IDE_LOGW("session[%zu] is not connected, ret: %d, status: %d", handle.session, ret, status);
     165            1 :         return IDE_DAEMON_CHANNEL_ERROR;
     166              :     }
     167            2 :     return IDE_DAEMON_NONE_ERROR;
     168              : }
     169              : 
     170            1 : IdeErrorT AdxDumpHdcHelper::Finish(IDE_SESSION& session)
     171              : {
     172              :     CommHandle handle;
     173            1 :     handle.type = client_.type;
     174            1 :     handle.session = reinterpret_cast<OptHandle>(session);
     175              :     // 直接关闭会话,不再发送MSG_STATUS_DATA_END消息
     176            1 :     AdxCommOptManager::Instance().Close(handle);
     177            1 :     session = nullptr;
     178            1 :     return IDE_DAEMON_NONE_ERROR;
     179              : }
     180              : 
     181              : /**
     182              :  * @brief dump start api,create a HDC session for dump
     183              :  * @param [in] connectInfo: remote connect info
     184              :  *
     185              :  * @return
     186              :  *      not NULL: Handle used by hdc
     187              :  *      NULL:     dump start failed
     188              :  */
     189            2 : IDE_SESSION HdcDumpStart(const char* connectInfo)
     190              : {
     191            2 :     IDE_CTRL_VALUE_FAILED(
     192              :         connectInfo != nullptr && strlen(connectInfo) != 0, return nullptr, "dump start msg is empty");
     193            2 :     if (!Adx::AdxDumpHdcHelper::Instance().Init()) {
     194            0 :         return nullptr;
     195              :     }
     196            2 :     IDE_SESSION session = nullptr;
     197            2 :     std::string connectInfoStr = std::string(connectInfo);
     198            2 :     Adx::AdxDumpHdcHelper::Instance().HandShake(connectInfoStr, session);
     199            2 :     return session;
     200            2 : }
     201              : 
     202              : /**
     203              :  * @brief dump data to remote server
     204              :  * @param [in] session: HDC session to dump data
     205              :  * @param [in] dumpChunk: Dump information
     206              :  * @return
     207              :  *      IDE_DAEMON_INVALID_PARAM_ERROR: invalid parameter
     208              :  *      IDE_DAEMON_UNKNOW_ERROR: write data failed
     209              :  *      IDE_DAEMON_NONE_ERROR:   write data succ
     210              :  */
     211            8 : IdeErrorT HdcDumpData(const IDE_SESSION session, const IdeDumpChunk* dumpChunk)
     212              : {
     213              :     IdeErrorT ret;
     214            8 :     IDE_CTRL_VALUE_FAILED(session != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "session is nullptr");
     215            5 :     IDE_CTRL_VALUE_FAILED(dumpChunk != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "IdeDumpChunk is nullptr");
     216            3 :     const uint32_t waitInsertDumpQueueTime = 100;
     217            3 :     int32_t retryInsertDumpQueueTimes = 3000; // 5min(3000 * 100ms)
     218            3 :     IDE_LOGD("dump data process entry");
     219              :     do {
     220            3 :         ret = Adx::AdxDumpHdcHelper::Instance().DataProcess(session, *dumpChunk);
     221            3 :         if (ret == IDE_DAEMON_DUMP_QUEUE_FULL) {
     222            0 :             (void)mmSleep(waitInsertDumpQueueTime);
     223            0 :             retryInsertDumpQueueTimes--;
     224              :         }
     225            3 :     } while (ret == IDE_DAEMON_DUMP_QUEUE_FULL && retryInsertDumpQueueTimes > 0);
     226            3 :     IDE_LOGD("dump data process exit");
     227            3 :     return ret;
     228              : }
     229              : 
     230              : /**
     231              :  * @brief send dump end msg
     232              :  * @param [in] session: HDC session to dump data
     233              :  * @return
     234              :  *      IDE_DAEMON_UNKNOW_ERROR: send dump end msg failed
     235              :  *      IDE_DAEMON_NONE_ERROR:   send dump end msg success
     236              :  */
     237            1 : IdeErrorT HdcDumpEnd(IDE_SESSION session)
     238              : {
     239            1 :     IDE_CTRL_VALUE_FAILED(session != nullptr, return IDE_DAEMON_INVALID_PARAM_ERROR, "session is nullptr");
     240            1 :     IDE_LOGI("dump data finish");
     241            1 :     return Adx::AdxDumpHdcHelper::Instance().Finish(session);
     242              : }
     243              : } // namespace Adx
        

Generated by: LCOV version 2.0-1