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

Generated by: LCOV version 2.0-1