LCOV - code coverage report
Current view: top level - adump/host - adx_dump_receive.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 80 80
Test Date: 2026-08-31 10:09:28 Functions: 100.0 % 7 7

            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_dump_receive.h"
      12              : #include <algorithm>
      13              : #include "mmpa_api.h"
      14              : #include "memory_utils.h"
      15              : #include "adx_dump_record.h"
      16              : #include "log/adx_log.h"
      17              : namespace Adx {
      18            6 : int32_t AdxDumpReceive::Init()
      19              : {
      20            6 :     init_ = true;
      21            6 :     return IDE_DAEMON_OK;
      22              : }
      23              : 
      24           14 : int32_t AdxDumpReceive::Process(const CommHandle& handle, const SharedPtr<MsgProto>& proto)
      25              : {
      26              :     // hand shake control(sent by IdeDumpStart)
      27           14 :     if (proto->msgType == MsgType::MSG_CTRL && proto->status == MsgStatus::MSG_STATUS_HAND_SHAKE) {
      28           36 :         IdeErrorT err = AdxMsgProto::SendResponse(
      29           12 :             handle, (CmdClassT)proto->reqType, proto->devId, MsgStatus::MSG_STATUS_NONE_ERROR);
      30           12 :         if (err != IDE_DAEMON_NONE_ERROR) {
      31            1 :             IDE_LOGE(
      32              :                 "send dump handshake response failed! device(id:%u,session:%zu), err: %d", proto->devId, handle.session,
      33              :                 err);
      34            1 :             return err;
      35              :         }
      36              :     } else {
      37            2 :         IDE_LOGW(
      38              :             "receive invalid ctrl msg! device(id:%u,session:%zu), type: %d, status: %d", proto->devId, handle.session,
      39              :             proto->msgType, proto->status);
      40            2 :         return IDE_DAEMON_OK;
      41              :     }
      42              :     // store client session(persistent session. must be closed before close server)
      43           11 :     AdxCommHandle adxHandle = const_cast<AdxCommHandle>(&handle);
      44           11 :     StoreSession(proto->devId, adxHandle);
      45              :     // read dump data(sent by IdeDumpData) and end dump control(sent by IdeDumpEnd)
      46           11 :     int32_t ret = Receive(handle, proto);
      47           11 :     ReleaseSession(proto->devId, adxHandle);
      48           11 :     return ret;
      49              : }
      50              : 
      51           11 : int32_t AdxDumpReceive::Receive(const CommHandle& handle, const SharedPtr<MsgProto>& proto)
      52              : {
      53           11 :     int32_t length = 0;
      54           11 :     uint32_t protoHeaderLen = static_cast<uint32_t>(sizeof(MsgProto));
      55           11 :     uint32_t chunkHeaderLen = static_cast<uint32_t>(sizeof(DumpChunk));
      56           11 :     MsgProto* msg = nullptr;
      57           14 :     while (init_) {
      58           13 :         IDE_LOGI("receiving new dump data from device(id:%u,session:%zu)", proto->devId, handle.session);
      59           13 :         int ret = AdxCommOptManager::Instance().Read(handle, (IdeRecvBuffT)&msg, length, COMM_OPT_BLOCK);
      60           22 :         IDE_CTRL_VALUE_WARN(
      61              :             ret == IDE_DAEMON_OK, return ret, "read dump data error. device(id:%u,session:%zu), err:%d", proto->devId,
      62              :             handle.session, ret);
      63           12 :         IDE_CTRL_VALUE_WARN(
      64              :             msg != nullptr && length >= 0,
      65              :             {
      66              :                 IdeXfree(msg);
      67              :                 return IDE_DAEMON_ERROR;
      68              :             },
      69              :             "dump data is invalid. device(id:%u,session:%zu)", proto->devId, handle.session);
      70              : 
      71           11 :         uint32_t protoEntryLen = static_cast<uint32_t>(length);
      72           11 :         IDE_CTRL_VALUE_WARN(
      73              :             protoEntryLen >= protoHeaderLen,
      74              :             {
      75              :                 IdeXfree(msg);
      76              :                 return IDE_DAEMON_ERROR;
      77              :             },
      78              :             "recvLen(%u) too small for MsgProto header(%u bytes)", protoEntryLen, protoHeaderLen);
      79              : 
      80           10 :         SharedPtr<MsgProto> msgPtr(msg, IdeXfree);
      81           10 :         msg = nullptr;
      82           10 :         if (msgPtr->msgType == MsgType::MSG_CTRL) {
      83            4 :             if (msgPtr->status == MsgStatus::MSG_STATUS_DATA_END) {
      84            3 :                 IDE_LOGI(
      85              :                     "received dump ctrl msg from device(id:%u,session:%zu), end transfer dump data", proto->devId,
      86              :                     handle.session);
      87            3 :                 return IDE_DAEMON_OK;
      88              :             } else {
      89            1 :                 continue;
      90              :             }
      91              :         }
      92            6 :         uint32_t protoDataLen = protoEntryLen - protoHeaderLen;
      93            6 :         IDE_CTRL_VALUE_WARN(
      94              :             msgPtr->sliceLen == protoDataLen, return IDE_DAEMON_ERROR,
      95              :             "msg sliceLen(%u) not equal actual msg data buffer size(%u)", msgPtr->sliceLen, protoDataLen);
      96              : 
      97            5 :         IDE_CTRL_VALUE_WARN(
      98              :             protoDataLen >= chunkHeaderLen, return IDE_DAEMON_ERROR,
      99              :             "msg dataLen(%u) too small for DumpChunk header(%u)", protoDataLen, chunkHeaderLen);
     100              : 
     101            4 :         DumpChunk* dumpChunk = reinterpret_cast<DumpChunk*>(msgPtr->data);
     102            4 :         uint32_t chunkDataLen = protoDataLen - chunkHeaderLen;
     103            4 :         IDE_CTRL_VALUE_WARN(
     104              :             dumpChunk->bufLen <= chunkDataLen, return IDE_DAEMON_ERROR,
     105              :             "chunk bufLen(%u) exceeds actual chunk data buffer size(%u)", dumpChunk->bufLen, chunkDataLen);
     106              : 
     107            3 :         IDE_LOGI(
     108              :             "fileName: %s, bufLen: %u, isLastChunk: %u, offset: %ld, flag: %d", dumpChunk->fileName, dumpChunk->bufLen,
     109              :             dumpChunk->isLastChunk, dumpChunk->offset, dumpChunk->flag);
     110              : 
     111            3 :         HostDumpDataInfo data = {msgPtr, protoDataLen};
     112            3 :         MsgStatus status = MsgStatus::MSG_STATUS_NONE_ERROR;
     113            3 :         if (!AdxDumpRecord::Instance().RecordDumpDataToQueue(data)) {
     114            1 :             status = MsgStatus::MSG_STATUS_CACHE_FULL_ERROR;
     115              :         }
     116              : 
     117              :         // send respone msg to device
     118            3 :         IdeErrorT err = AdxMsgProto::SendResponse(handle, proto->reqType, proto->devId, status);
     119            3 :         IDE_CTRL_VALUE_FAILED(
     120              :             err == IDE_DAEMON_NONE_ERROR, return IDE_DAEMON_ERROR,
     121              :             "send dump handshake response failed! device(id:%u,session:%zu), err: %d", proto->devId, handle.session,
     122              :             err);
     123           11 :     }
     124            1 :     return IDE_DAEMON_OK;
     125              : }
     126              : 
     127            7 : int32_t AdxDumpReceive::UnInit()
     128              : {
     129            7 :     init_ = false;
     130            7 :     return IDE_DAEMON_OK;
     131              : }
     132              : 
     133           12 : void AdxDumpReceive::StoreSession(uint32_t deviceId, AdxCommHandle handle)
     134              : {
     135           12 :     if (handle != nullptr) {
     136           12 :         std::lock_guard<std::mutex> lock{mutex_};
     137           12 :         handles_[deviceId].push_back(handle);
     138           12 :     }
     139           12 : }
     140              : 
     141           11 : void AdxDumpReceive::ReleaseSession(uint32_t deviceId, AdxCommHandle handle)
     142              : {
     143           11 :     if (handle != nullptr) {
     144           11 :         std::lock_guard<std::mutex> lock{mutex_};
     145           11 :         auto map_it = handles_.find(deviceId);
     146           11 :         if (map_it != handles_.end()) {
     147           11 :             auto& vec = map_it->second;
     148           11 :             auto vec_it = std::find(vec.begin(), vec.end(), handle);
     149           22 :             if (vec_it != vec.end()) {
     150           11 :                 vec.erase(vec_it);
     151              :             }
     152              :         }
     153           11 :     }
     154           11 : }
     155              : 
     156            4 : int32_t AdxDumpReceive::Terminate()
     157              : {
     158            4 :     std::lock_guard<std::mutex> lock{mutex_};
     159            5 :     for (auto& map_it : handles_) {
     160            3 :         for (auto& handle : map_it.second) {
     161            1 :             IDE_LOGW("close alive client session. device: %u, session: %zu", map_it.first, handle->session);
     162            1 :             (void)AdxCommOptManager::Instance().Close(*handle);
     163              :         }
     164              :     }
     165            4 :     handles_.clear();
     166            4 :     return IDE_DAEMON_OK;
     167            4 : }
     168              : } // namespace Adx
        

Generated by: LCOV version 2.0-1