LCOV - code coverage report
Current view: top level - adcore - adx_api.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.8 % 188 182
Test Date: 2026-07-28 10:54:24 Functions: 100.0 % 8 8

            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 "adx_api.h"
      12              : #include "mmpa_api.h"
      13              : #include "ascend_hal.h"
      14              : #include "protocol/adx_msg_proto.h"
      15              : #include "log/adx_log.h"
      16              : #include "common/file_utils.h"
      17              : #include "device/adx_dsmi.h"
      18              : #include "config.h"
      19              : #include "create_func.h"
      20              : #include "adcore_api.h"
      21              : #include "memory_utils.h"
      22              : #include "adx_msg.h"
      23              : #include "adx_comm_opt_manager.h"
      24              : using namespace Adx;
      25              : static constexpr int32_t BLOCK_RETURN_CODE = 4;
      26              : static constexpr int32_t RESULT_LEN_MAX = 100;
      27              : static constexpr uint32_t DEFAULT_TIMEOUT = 10000; // 10000ms
      28              : 
      29              : /**
      30              :  * @brief        hdc connect core dump server
      31              :  * @param  [out] client     : send file communication client handle
      32              :  * @param  [in]  devId      : send file device id
      33              :  * @return       CommHandle : client handle
      34              :  */
      35           26 : static CommHandle AdxHdcConnect(CommHandle &client, uint16_t devId,
      36              :     AdxHdcServiceType hdcType = HDC_SERVICE_TYPE_IDE_FILE_TRANS)
      37              : {
      38           26 :     std::map<std::string, std::string> info;
      39           26 :     info[OPT_DEVICE_KEY] = std::to_string(devId);
      40           26 :     info[OPT_SERVICE_KEY] = std::to_string(hdcType);
      41           26 :     CommHandle session = {OptType::COMM_HDC, ADX_OPT_INVALID_HANDLE, NR_COMPONENTS, -1, nullptr};
      42           26 :     std::unique_ptr<AdxCommOpt> opt (CreateAdxCommOpt(OptType::COMM_HDC));
      43           26 :     IDE_CTRL_VALUE_FAILED(opt != nullptr, return session,
      44              :         "create hdc commopt exception");
      45           26 :     bool ret = AdxCommOptManager::Instance().CommOptsRegister(opt);
      46           26 :     IDE_CTRL_VALUE_FAILED(ret, return client, "register hdc failed");
      47           26 :     client = AdxCommOptManager::Instance().OpenClient(OptType::COMM_HDC, info);
      48           26 :     IDE_CTRL_VALUE_FAILED(client.session != ADX_OPT_INVALID_HANDLE, return client,
      49              :         "open client failed");
      50           26 :     session = AdxCommOptManager::Instance().Connect(client, info);
      51           26 :     if (session.session == ADX_OPT_INVALID_HANDLE) {
      52            0 :         (void)AdxCommOptManager::Instance().CloseClient(client);
      53              :     }
      54           26 :     return session;
      55           26 : }
      56              : 
      57              : /**
      58              :  * @brief  send file common opreate
      59              :  * @param  [in]  handle     : send file communication handle
      60              :  * @param  [in]  srcFile    : send file source file with path
      61              :  * @return IDE_DAEMON_OK(0) : send file success, IDE_DAEMON_ERROR(-1) : send file failed
      62              :  */
      63            8 : static int32_t AdxCommonGetFile(const CommHandle &handle, const std::string &srcFile)
      64              : {
      65            8 :     IDE_CTRL_VALUE_FAILED(!srcFile.empty(), return IDE_DAEMON_ERROR, "source file input invalid");
      66            8 :     IDE_CTRL_VALUE_FAILED(FileUtils::CheckNonCrossPath(srcFile), return IDE_DAEMON_ERROR, 
      67              :         "Cross-path access may exist on the path: %s", srcFile.c_str());
      68              :     // create dir if not exist
      69            2 :     std::string saveDirName = FileUtils::GetFileDir(srcFile);
      70            2 :     if (!FileUtils::IsFileExist(saveDirName)) {
      71            1 :         if (FileUtils::CreateDir(saveDirName) != IDE_DAEMON_NONE_ERROR) {
      72            1 :             IDE_LOGE("create dir failed path: %s", saveDirName.c_str());
      73            1 :             return IDE_DAEMON_ERROR;
      74              :         }
      75              :     }
      76              :     // get file
      77            1 :     int32_t fd = mmOpen2(srcFile.c_str(), M_RDWR | M_CREAT | M_BINARY | M_TRUNC, M_IRUSR | M_IWRITE);
      78            1 :     char errBuf[MAX_ERRSTR_LEN + 1] = {0};
      79            1 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_ERROR, "open file exception, info : %s",
      80              :                           mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
      81              : 
      82            1 :     int32_t err = AdxMsgProto::RecvFile(handle, fd);
      83            1 :     if (err != IDE_DAEMON_NONE_ERROR && err != IDE_DAEMON_CHANNEL_ERROR) {
      84            0 :         mmClose(fd);
      85            0 :         fd = -1;
      86            0 :         IDE_LOGE("receive file failed, info : %s", srcFile.c_str());
      87            0 :         (void)remove(srcFile.c_str());
      88            0 :         return IDE_DAEMON_ERROR;
      89              :     }
      90              : 
      91            1 :     mmClose(fd);
      92            1 :     fd = -1;
      93              : 
      94            1 :     if (err == IDE_DAEMON_CHANNEL_ERROR) {
      95            1 :         IDE_LOGE("send file receive response failed, " \
      96              :             "maybe multiple msnpureports executed at the same time, which is not supported, " \
      97              :             "please execute msnpureport only once per time later if needed");
      98              :     }
      99            1 :     return IDE_DAEMON_OK;
     100            2 : }
     101              : 
     102              : /**
     103              :  * @brief  get device file
     104              :  * @param  [in]  devId      : physical device id
     105              :  * @param  [in]  desPath    : send file to destination path
     106              :  * @param  [in]  logType    : file type, stackcore, slog, bbox, message
     107              :  * @param  [in]  timeout    : 0 wait_always, > 0 wait_timeout; unit: ms
     108              :  * @return IDE_DAEMON_OK(0) : get file success, IDE_DAEMON_ERROR(-1) : get file failed
     109              :  */
     110           14 : int32_t AdxGetDeviceFileTimeout(uint16_t devId, IdeString desPath, IdeString logType, uint32_t timeout)
     111              : {
     112           14 :     int32_t err = IDE_DAEMON_ERROR;
     113           14 :     IDE_CTRL_VALUE_FAILED(desPath != nullptr && logType != nullptr, return err,
     114              :         "send file input parameter invalid");
     115           14 :     IDE_RUN_LOGI("get device file to %s", desPath);
     116           14 :     CommHandle client = {OptType::COMM_HDC, ADX_OPT_INVALID_HANDLE, NR_COMPONENTS, -1, nullptr};
     117           14 :     uint32_t logId = 0;
     118           14 :     err = AdxGetLogIdByPhyId(devId, &logId);
     119           14 :     IDE_CTRL_VALUE_FAILED(err == IDE_DAEMON_OK, return err, "get device logic id failed");
     120           14 :     CommHandle handle = AdxHdcConnect(client, logId);
     121           14 :     IDE_CTRL_VALUE_FAILED(handle.session != ADX_OPT_INVALID_HANDLE, return IDE_DAEMON_ERROR,
     122              :         "send file hdc client connect failed");
     123           14 :     handle.timeout = timeout;
     124           14 :     std::string basePath = desPath;
     125           14 :     std::string value;
     126           14 :     int32_t result = IDE_DAEMON_OK;
     127           28 :     MsgCode code = AdxMsgProto::SendMsgData(handle, IDE_FILE_GETD_REQ, MsgStatus::MSG_STATUS_NONE_ERROR,
     128           14 :                                             logType, strlen(logType) + 1);
     129           14 :     IDE_CTRL_VALUE_FAILED(code == IDE_DAEMON_NONE_ERROR, goto GET_ERROR, "send file hand shake failed");
     130              :     do {
     131              :         // recv file name
     132           15 :         code = AdxMsgProto::GetStringMsgData(handle, value);
     133           15 :         IDE_CTRL_VALUE_FAILED(code == IDE_DAEMON_NONE_ERROR, goto GET_ERROR, "get file shake response failed, ret=%d",
     134              :             static_cast<int32_t>(code));
     135           10 :         size_t msgSize = IdeDaemon::Common::Config::CONTAINER_NO_SUPPORT_MESSAGE.length();
     136           10 :         if (value.compare(0, msgSize, IdeDaemon::Common::Config::CONTAINER_NO_SUPPORT_MESSAGE) == 0) {
     137            1 :             result = BLOCK_RETURN_CODE;
     138            1 :             break;
     139              :         }
     140            9 :         msgSize = IdeDaemon::Common::Config::SEND_END_MSG.length();
     141            9 :         if (value.compare(0, msgSize, IdeDaemon::Common::Config::SEND_END_MSG) == 0) {
     142            1 :             break;
     143              :         }
     144            8 :         IDE_LOGD("receive file relative path and name is %s", value.c_str());
     145            8 :         value = basePath + OS_SPLIT_STR + value;
     146              : #if (OS_TYPE != LINUX)
     147              :         value = FileUtils::ReplaceAll(value, "/", "\\");
     148              : #endif
     149            8 :         err = AdxCommonGetFile(handle, value);
     150            8 :         if (err != IDE_DAEMON_OK) {
     151            7 :             IDE_LOGE("get file process failed");
     152            7 :             break;
     153              :         }
     154            1 :         IDE_LOGI("receive file file data successfully");
     155            1 :         (void)mmChmod(value.c_str(), M_IRUSR); // readonly, 400
     156            1 :     } while (true);
     157              : 
     158           14 : GET_ERROR:
     159           14 :     (void)AdxCommOptManager::Instance().Close(handle);
     160           14 :     (void)AdxCommOptManager::Instance().CloseClient(client);
     161           14 :     return result;
     162           14 : }
     163              : 
     164              : /**
     165              :  * @brief  get file value from the peer end and write to file
     166              :  * @param  [in]  handle  :    handle for communicating with the peer end
     167              :  * @param  [in]  fd      :    file descriptor
     168              :  * @return IDE_DAEMON_OK(0) : recv file success, IDE_DAEMON_ERROR(-1) : recv file failed
     169              :  */
     170           13 : static int32_t AdxRecvFile(const CommHandle &handle, int32_t fd)
     171              : {
     172           13 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_ERROR, "file fd input failed");
     173           13 :     MsgProto *msg = nullptr;
     174           13 :     int32_t length = 0;
     175              :     while (true) {
     176           14 :         int32_t ret = AdxCommOptManager::Instance().Read(handle, reinterpret_cast<IdeRecvBuffT>(&msg),
     177              :             length, DEFAULT_TIMEOUT);
     178           14 :         IDE_CTRL_VALUE_FAILED((ret == IDE_DAEMON_OK) && (msg != nullptr), return IDE_DAEMON_ERROR,
     179              :             "receive file failed, ret: %d", ret);
     180           13 :         if (msg->msgType == MsgType::MSG_CTRL) { // check the message is ctrl or not
     181            1 :             IDE_LOGW("receive control message from device, stop receiving");
     182            1 :             IDE_XFREE_AND_SET_NULL(msg);
     183            1 :             return IDE_DAEMON_ERROR;
     184              :         }
     185           12 :         if (msg->sliceLen != 0) {
     186           12 :             mmSsize_t len = mmWrite(fd, msg->data, msg->sliceLen);
     187           12 :             if (len < 0) {
     188            1 :                 char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     189            1 :                 IDE_LOGE("write file failed, error info: [%s]",
     190              :                          mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     191            1 :                 IDE_XFREE_AND_SET_NULL(msg);
     192            1 :                 return IDE_DAEMON_ERROR;
     193              :             }
     194              :         }
     195              : 
     196           11 :         if (msg->totalLen == msg->sliceLen + msg->offset) {
     197           10 :             break;
     198              :         }
     199              : 
     200            1 :         IDE_XFREE_AND_SET_NULL(msg);
     201            1 :     }
     202           10 :     if (AdxSendMsg(&handle, HDC_END_MSG, strlen(HDC_END_MSG)) != IDE_DAEMON_OK) {
     203            2 :         IDE_LOGW("send file response message exception");
     204              :     }
     205              : 
     206           10 :     IDE_XFREE_AND_SET_NULL(msg);
     207           10 :     return IDE_DAEMON_OK;
     208              : }
     209              : 
     210              : /**
     211              :  * @brief  get device file
     212              :  * @param  [in]  devId      : physical device id
     213              :  * @param  [in]  desPath    : send file to destination path
     214              :  * @param  [in]  logType    : file type, stackcore, slog, bbox, message
     215              :  * @return IDE_DAEMON_OK(0) : get file success, IDE_DAEMON_ERROR(-1) : get file failed
     216              :  */
     217           14 : int32_t AdxGetDeviceFile(uint16_t devId, IdeString desPath, IdeString logType)
     218              : {
     219           14 :     return AdxGetDeviceFileTimeout(devId, desPath, logType, DEFAULT_TIMEOUT);
     220              : }
     221              : 
     222              : /**
     223              :  * @brief  create file and receive value
     224              :  * @param  [in]  handle  :    handle for communicating with the peer end
     225              :  * @param  [in]  file    :    the file name
     226              :  * @return IDE_DAEMON_OK(0) : recv file success, IDE_DAEMON_ERROR(-1) : recv file failed
     227              :  */
     228           17 : static int32_t AdxCreateFileAndRecvValue(const CommHandle &handle, std::string &file)
     229              : {
     230           17 :     IDE_CTRL_VALUE_FAILED(FileUtils::CheckNonCrossPath(file), return IDE_DAEMON_ERROR, 
     231              :         "Cross-path access may exist on the path: %s", file.c_str());
     232              :     // create dir if not exist
     233           16 :     std::string saveDirName = FileUtils::GetFileDir(file);
     234           16 :     if (!FileUtils::IsFileExist(saveDirName)) {
     235           14 :         if (FileUtils::CreateDir(saveDirName) != IDE_DAEMON_NONE_ERROR) {
     236            1 :             IDE_LOGE("create dir failed path: %s", saveDirName.c_str());
     237            1 :             return IDE_DAEMON_ERROR;
     238              :         }
     239              :     }
     240              :     // get file
     241           15 :     int32_t fd = mmOpen2(file.c_str(), M_RDWR | M_CREAT | M_BINARY | M_TRUNC, M_IRUSR | M_IWRITE);
     242           15 :     char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     243           15 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_ERROR, "open file exception, info : %s",
     244              :                         mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     245              : 
     246           13 :     int32_t err = AdxRecvFile(handle, fd);
     247           13 :     if (err == IDE_DAEMON_ERROR) {
     248            3 :         mmClose(fd);
     249            3 :         fd = -1;
     250            3 :         IDE_LOGE("receive file failed, info : %s", file.c_str());
     251            3 :         (void)remove(file.c_str());
     252            3 :         return IDE_DAEMON_ERROR;
     253              :     }
     254           10 :     mmClose(fd);
     255           10 :     fd = -1;
     256           10 :     (void)mmChmod(file.c_str(), M_IRUSR); // readonly, 400
     257           10 :     return IDE_DAEMON_OK;
     258           16 : }
     259              : 
     260              : /**
     261              :  * @brief  get device file from specified hdc server and component
     262              :  * @param  [in]  devId      : physical device id
     263              :  * @param  [in]  desPath    : send file to destination path
     264              :  * @param  [in]  logType    : file type
     265              :  * @param  [in]  hdcType    : hdc server type
     266              :  * @param  [in]  compType   : component type
     267              :  * @return IDE_DAEMON_OK(0) : get file success, IDE_DAEMON_ERROR(-1) : get file failed
     268              :  */
     269           14 : int32_t AdxGetSpecifiedFile(uint16_t devId, IdeString desPath, IdeString logType, int32_t hdcType, int32_t compType)
     270              : {
     271           14 :     int32_t err = IDE_DAEMON_ERROR;
     272           14 :     IDE_CTRL_VALUE_FAILED((desPath != nullptr) && (logType != nullptr), return err,
     273              :         "send file input parameter invalid");
     274           13 :     IDE_RUN_LOGI("get device file to %s", desPath);
     275           13 :     CommHandle client = {OptType::COMM_HDC, ADX_OPT_INVALID_HANDLE, NR_COMPONENTS, -1, nullptr};
     276           13 :     uint32_t logId = 0;
     277           13 :     err = AdxGetLogIdByPhyId(devId, &logId);
     278           13 :     IDE_CTRL_VALUE_FAILED(err == IDE_DAEMON_OK, return err, "get device logic id failed");
     279           12 :     CommHandle handle = AdxHdcConnect(client, logId, static_cast<AdxHdcServiceType>(hdcType));
     280           12 :     IDE_CTRL_VALUE_FAILED(handle.session != ADX_OPT_INVALID_HANDLE, return IDE_DAEMON_ERROR,
     281              :         "send file hdc client connect failed");
     282           12 :     handle.comp = static_cast<ComponentType>(compType);
     283           12 :     err = AdxSendMsg(static_cast<AdxCommConHandle>(&handle), logType, strlen(logType));
     284           12 :     IDE_CTRL_VALUE_FAILED(err == IDE_DAEMON_OK, return err, "send data message failed");
     285           22 :     std::string basePath = desPath;
     286              :     do {
     287           20 :         uint32_t len = RESULT_LEN_MAX;
     288           20 :         IdeStringBuffer ptr = static_cast<IdeStringBuffer>(IdeXmalloc(len));
     289           20 :         err = AdxRecvMsg(&handle, &ptr, &len, DEFAULT_TIMEOUT);
     290           20 :         if (err != IDE_DAEMON_OK) {
     291            1 :             IDE_XFREE_AND_SET_NULL(ptr);
     292            1 :             IDE_LOGE("receive message failed, ret: %d", err);
     293            1 :             break;
     294              :         }
     295           19 :         std::string value(ptr);
     296           19 :         IDE_XFREE_AND_SET_NULL(ptr);
     297           19 :         size_t msgSize = IdeDaemon::Common::Config::CONTAINER_NO_SUPPORT_MESSAGE.length();
     298           19 :         if (value.compare(0, msgSize, IdeDaemon::Common::Config::CONTAINER_NO_SUPPORT_MESSAGE) == 0) {
     299            1 :             err = BLOCK_RETURN_CODE;
     300            1 :             break;
     301              :         }
     302           18 :         msgSize = sizeof(HDC_END_MSG);
     303           18 :         if (value.compare(0, msgSize, HDC_END_MSG) == 0) {
     304            4 :             break;
     305              :         }
     306           14 :         err = AdxSendMsg(&handle, HDC_END_MSG, strlen(HDC_END_MSG));
     307           14 :         if (err != IDE_DAEMON_OK) {
     308            1 :             IDE_LOGW("send name response message exception");
     309              :         }
     310           14 :         IDE_LOGD("receive file relative path and name is %s", value.c_str());
     311           14 :         value = basePath + OS_SPLIT_STR + value;
     312              : 
     313           14 :         if (AdxCreateFileAndRecvValue(handle, value) != IDE_DAEMON_OK) {
     314            5 :             err = IDE_DAEMON_ERROR;
     315            5 :             break;
     316              :         }
     317           28 :     } while (true);
     318              : 
     319           11 :     (void)AdxCommOptManager::Instance().Close(handle);
     320           11 :     (void)AdxCommOptManager::Instance().CloseClient(client);
     321           11 :     return err;
     322           11 : }
     323              : 
     324            5 : int32_t AdxRecvDevFileTimeout(AdxCommHandle handle, AdxString desPath, uint32_t timeout, AdxStringBuffer fileName,
     325              :     uint32_t fileNameLen)
     326              : {
     327            5 :     IDE_CTRL_VALUE_FAILED(handle != nullptr, return IDE_DAEMON_ERROR, "handle is NULL.");
     328            5 :     IDE_CTRL_VALUE_FAILED(desPath != nullptr, return IDE_DAEMON_ERROR, "desPath is NULL.");
     329            5 :     IDE_CTRL_VALUE_FAILED(fileName != nullptr, return IDE_DAEMON_ERROR, "fileName is NULL.");
     330              : 
     331            5 :     uint32_t len = fileNameLen;
     332            5 :     int32_t ret = AdxRecvMsg(handle, &fileName, &len, timeout);
     333            5 :     if (ret != IDE_DAEMON_OK) {
     334            1 :         return ret;
     335              :     }
     336            4 :     std::string value(fileName);
     337            4 :     if (value.compare(HDC_END_MSG) == 0) {
     338            1 :         return IDE_DAEMON_ERROR;
     339              :     }
     340            3 :     value = std::string(desPath) + OS_SPLIT_STR + value;
     341            3 :     if (AdxCreateFileAndRecvValue(*handle, value) != IDE_DAEMON_OK) {
     342            2 :         return IDE_DAEMON_ERROR;
     343              :     }
     344            1 :     return IDE_DAEMON_OK;
     345            4 : }
        

Generated by: LCOV version 2.0-1