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

Generated by: LCOV version 2.0-1