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

Generated by: LCOV version 2.0-1