LCOV - code coverage report
Current view: top level - adcore/protocol - adx_msg_proto.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.6 % 197 147
Test Date: 2026-08-12 11:04:53 Functions: 90.9 % 11 10

            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 "adx_msg_proto.h"
      11              : #include "securec.h"
      12              : #include "mmpa_api.h"
      13              : #include "ascend_hal.h"
      14              : #include "memory_utils.h"
      15              : #include "log/adx_log.h"
      16              : #include "adx_comm_opt_manager.h"
      17              : namespace Adx {
      18              : static const uint32_t MAX_PROTO_FILE_BUFFER_SIZE = 512000; // 500kb
      19              : static const int32_t MAX_DEV_FILE_SIZE = 4096;             // 4k
      20              : 
      21           80 : MsgProto* AdxMsgProto::CreateMsgPacket(CmdClassT type, uint16_t devId, IdeSendBuffT data, uint32_t length)
      22              : {
      23           80 :     MsgProto* msg = AdxMsgProto::CreateDataMsg(data, length);
      24           80 :     IDE_CTRL_VALUE_FAILED(msg != nullptr, return nullptr, "create message failed");
      25           79 :     msg->devId = devId;
      26           79 :     msg->reqType = type;
      27           79 :     return msg;
      28              : }
      29              : 
      30           80 : MsgProto* AdxMsgProto::CreateMsgByType(MsgType type, IdeSendBuffT data, uint32_t length)
      31              : {
      32           80 :     MsgProto* msg = nullptr;
      33           80 :     if (length > UINT32_MAX - sizeof(MsgProto)) {
      34            0 :         return nullptr;
      35              :     }
      36              : 
      37           80 :     if (type == MsgType::MSG_CTRL || type == MsgType::MSG_DATA) {
      38           80 :         uint32_t mallocLen = length + sizeof(MsgProto);
      39           80 :         msg = reinterpret_cast<MsgProto*>(IdeXmalloc(mallocLen));
      40           80 :         IDE_CTRL_VALUE_FAILED(msg != nullptr, return nullptr, "malloc memory failed");
      41           80 :         if (data != nullptr) { // send buffer(data) not nullptr copy data to message
      42           31 :             int32_t ret = memcpy_s(msg->data, length, data, length);
      43           31 :             if (ret != EOK) {
      44            1 :                 IDE_LOGE("create msg mem copy failed");
      45            1 :                 IDE_XFREE_AND_SET_NULL(msg);
      46            1 :                 return nullptr;
      47              :             }
      48              :         }
      49              : 
      50           79 :         msg->msgType = type;
      51           79 :         msg->sliceLen = length;
      52           79 :         msg->totalLen = length;
      53           79 :         IDE_LOGD("adx_msg_proto CreateMsgByType length is %u bytes", length);
      54           79 :         msg->headInfo = ADX_PROTO_MAGIC_VALUE;
      55           79 :         msg->headVer = ADX_PROTO_VERSION;
      56           79 :         msg->order = 0;
      57           79 :         return msg;
      58              :     }
      59              : 
      60            0 :     return nullptr;
      61              : }
      62              : 
      63           80 : MsgProto* AdxMsgProto::CreateDataMsg(IdeSendBuffT data, uint32_t length)
      64              : {
      65           80 :     return CreateMsgByType(MsgType::MSG_DATA, data, length);
      66              : }
      67              : 
      68            4 : int32_t AdxMsgProto::CreateCtrlMsg(MsgProto& proto, MsgStatus status)
      69              : {
      70            4 :     proto.headInfo = ADX_PROTO_MAGIC_VALUE;
      71            4 :     proto.headVer = ADX_PROTO_VERSION;
      72            4 :     proto.order = 0;
      73            4 :     proto.sliceLen = 0;
      74            4 :     proto.totalLen = 0;
      75            4 :     proto.msgType = MsgType::MSG_CTRL;
      76            4 :     proto.status = status;
      77            4 :     return IDE_DAEMON_OK;
      78              : }
      79              : 
      80           11 : MsgCode AdxMsgProto::SendMsgData(
      81              :     const CommHandle& handle, CmdClassT type, MsgStatus status, IdeSendBuffT data, uint32_t length)
      82              : {
      83           11 :     MsgProto* msg = AdxMsgProto::CreateMsgPacket(type, 0, data, length);
      84           11 :     IDE_CTRL_VALUE_FAILED(msg != nullptr, return IDE_DAEMON_MALLOC_ERROR, "create message failed");
      85           10 :     std::unique_ptr<MsgProto, decltype(&IdeXfree)> sendDataMsgPtr(msg, IdeXfree);
      86           10 :     sendDataMsgPtr->status = status;
      87           10 :     msg = nullptr;
      88           20 :     int32_t ret = AdxCommOptManager::Instance().Write(
      89           10 :         handle, sendDataMsgPtr.get(), sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
      90           10 :     if (ret != IDE_DAEMON_OK) {
      91            4 :         IDE_LOGE(
      92              :             "send message failed, ret: %d, session: %zu, length: %u bytes, please check peer end is alive", ret,
      93              :             handle.session, length);
      94            4 :         return IDE_DAEMON_CHANNEL_ERROR;
      95              :     }
      96              : 
      97            6 :     return IDE_DAEMON_NONE_ERROR;
      98           10 : }
      99              : 
     100           11 : MsgCode AdxMsgProto::GetStringMsgData(const CommHandle& handle, std::string& value)
     101              : {
     102           11 :     MsgProto* req = nullptr;
     103           11 :     int32_t length = 0;
     104           11 :     int32_t blockType = COMM_OPT_NOBLOCK;
     105           11 :     if (handle.timeout == 0) {
     106            0 :         blockType = COMM_OPT_BLOCK;
     107           11 :     } else if (handle.timeout > 0) {
     108            9 :         blockType = handle.timeout;
     109              :     }
     110           11 :     int32_t ret = AdxCommOptManager::Instance().Read(handle, reinterpret_cast<IdeRecvBuffT>(&req), length, blockType);
     111           11 :     if ((ret == IDE_DAEMON_ERROR) || (req == nullptr) || (length <= 0)) {
     112            8 :         if (ret == DRV_ERROR_WAIT_TIMEOUT) {
     113            1 :             return IDE_DAEMON_HDC_TIMEOUT;
     114              :         }
     115            7 :         if (ret == IDE_DAEMON_SOCK_CLOSE) {
     116            0 :             return static_cast<MsgCode>(IDE_DAEMON_SOCK_CLOSE);
     117              :         }
     118            7 :         return IDE_DAEMON_CHANNEL_ERROR;
     119              :     }
     120              : 
     121            3 :     SharedPtr<MsgProto> msgPtr(req, IdeXfree);
     122            3 :     if (length <= static_cast<int32_t>(sizeof(MsgProto))) {
     123            1 :         IDE_LOGE("receive request length(%d bytes) exception", length);
     124            1 :         return IDE_DAEMON_INVALID_PARAM_ERROR;
     125              :     }
     126            2 :     req = nullptr;
     127            2 :     if (msgPtr->status == MsgStatus::MSG_STATUS_FILE_LOAD) {
     128            0 :         IDE_LOGE("receive request status(%d) exception", static_cast<int32_t>(MsgStatus::MSG_STATUS_FILE_LOAD));
     129            0 :         return IDE_DAEMON_UNKNOW_ERROR;
     130              :     }
     131            2 :     if (msgPtr->sliceLen + sizeof(MsgProto) != (uint32_t)length) {
     132            1 :         IDE_LOGE("receive request package(%u bytes) length(%d bytes) exception", msgPtr->sliceLen, length);
     133            1 :         return IDE_DAEMON_UNKNOW_ERROR;
     134              :     }
     135              : 
     136            1 :     value = std::string((IdeStringBuffer)msgPtr->data, msgPtr->sliceLen);
     137            1 :     return IDE_DAEMON_NONE_ERROR;
     138            3 : }
     139              : 
     140            3 : MsgCode AdxMsgProto::SendEventFile(const CommHandle& handle, CmdClassT type, uint16_t devId, int32_t fd)
     141              : {
     142            3 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_INVALID_PARAM_ERROR, "create message failed");
     143            3 :     MsgProto* msg = AdxMsgProto::CreateMsgPacket(type, devId, nullptr, MAX_PROTO_FILE_BUFFER_SIZE);
     144            3 :     IDE_CTRL_VALUE_FAILED(msg != nullptr, return IDE_DAEMON_MALLOC_ERROR, "create message failed");
     145            3 :     std::unique_ptr<MsgProto, decltype(&IdeXfree)> sendDataMsgPtr(msg, IdeXfree);
     146            3 :     msg = nullptr;
     147              : 
     148            3 :     mmSsize_t pos = mmLseek(fd, 0L, SEEK_SET);
     149            3 :     IDE_CTRL_VALUE_FAILED(pos >= 0, return IDE_DAEMON_UNKNOW_ERROR, "lseek set failed");
     150              : 
     151            3 :     mmSsize_t readLen = MAX_PROTO_FILE_BUFFER_SIZE;
     152            3 :     mmSsize_t len = mmRead(fd, sendDataMsgPtr->data, readLen);
     153            3 :     char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     154            3 :     int32_t err = mmGetErrorCode();
     155            3 :     if ((len < 0) && (err == EIO)) {
     156            1 :         IDE_LOGW("An EIO exception occurred when reading files from the event_sched directory");
     157            1 :         len = 0;
     158              :     } else {
     159            2 :         IDE_CTRL_VALUE_FAILED(
     160              :             len >= 0, return IDE_DAEMON_UNKNOW_ERROR, "Failed to read file in the event_sched directory: info [%s]",
     161              :             mmGetErrorFormatMessage(err, errBuf, MAX_ERRSTR_LEN));
     162              :     }
     163              : 
     164            2 :     if (len > MAX_DEV_FILE_SIZE) {
     165            0 :         IDE_LOGW("read file success, but the size has exceeded the maximum size of the dev file.");
     166              :     }
     167            2 :     sendDataMsgPtr->status = MsgStatus::MSG_STATUS_FILE_LOAD;
     168            2 :     sendDataMsgPtr->totalLen = len;
     169            2 :     sendDataMsgPtr->offset = 0;
     170            2 :     sendDataMsgPtr->sliceLen = (uint32_t)len;
     171            4 :     int32_t ret = AdxCommOptManager::Instance().Write(
     172            2 :         handle, sendDataMsgPtr.get(), sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
     173            2 :     IDE_CTRL_VALUE_FAILED(
     174              :         ret == IDE_DAEMON_OK, return IDE_DAEMON_CHANNEL_ERROR, "hand shake failed ret %d, please check server is alive",
     175              :         ret);
     176            0 :     RecvResponse(handle);
     177            0 :     return IDE_DAEMON_NONE_ERROR;
     178            3 : }
     179              : 
     180            1 : MsgCode AdxMsgProto::SendFile(const CommHandle& handle, CmdClassT type, uint16_t devId, int32_t fd)
     181              : {
     182            1 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_INVALID_PARAM_ERROR, "create message failed");
     183            1 :     MsgProto* msg = AdxMsgProto::CreateMsgPacket(type, devId, nullptr, MAX_PROTO_FILE_BUFFER_SIZE);
     184            1 :     IDE_CTRL_VALUE_FAILED(msg != nullptr, return IDE_DAEMON_MALLOC_ERROR, "create message failed");
     185            1 :     std::unique_ptr<MsgProto, decltype(&IdeXfree)> sendDataMsgPtr(msg, IdeXfree);
     186            1 :     msg = nullptr;
     187            1 :     mmSsize_t fileLength = mmLseek(fd, 0L, SEEK_END);
     188            1 :     IDE_CTRL_VALUE_FAILED(fileLength >= 0, return IDE_DAEMON_UNKNOW_ERROR, "lseek end failed");
     189              : 
     190            1 :     mmSsize_t pos = mmLseek(fd, 0L, SEEK_SET);
     191            1 :     IDE_CTRL_VALUE_FAILED(pos >= 0, return IDE_DAEMON_UNKNOW_ERROR, "lseek set failed");
     192            1 :     mmSsize_t resLen = fileLength;
     193            1 :     sendDataMsgPtr->status = MsgStatus::MSG_STATUS_FILE_LOAD;
     194            1 :     sendDataMsgPtr->totalLen = fileLength;
     195            1 :     sendDataMsgPtr->offset = 0;
     196              : 
     197            1 :     if (resLen == 0) {
     198            0 :         sendDataMsgPtr->sliceLen = (uint32_t)fileLength;
     199            0 :         int32_t ret = AdxCommOptManager::Instance().Write(
     200            0 :             handle, sendDataMsgPtr.get(), sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
     201            0 :         IDE_CTRL_VALUE_FAILED(
     202              :             ret == IDE_DAEMON_OK, return IDE_DAEMON_CHANNEL_ERROR,
     203              :             "send empty file failed ret %d, please check server is alive", ret);
     204              :     }
     205              : 
     206            1 :     while (resLen > 0) {
     207            1 :         mmSsize_t readLen =
     208            1 :             static_cast<uint32_t>(resLen) > MAX_PROTO_FILE_BUFFER_SIZE ? MAX_PROTO_FILE_BUFFER_SIZE : resLen;
     209            1 :         mmSsize_t len = mmRead(fd, sendDataMsgPtr->data, readLen);
     210            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     211            2 :         IDE_CTRL_VALUE_FAILED(
     212              :             len >= 0, return IDE_DAEMON_UNKNOW_ERROR, "read file failed : info [%s]",
     213              :             mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     214            1 :         if (len > 0 && len <= readLen) {
     215            1 :             sendDataMsgPtr->sliceLen = (uint32_t)len;
     216            2 :             int32_t ret = AdxCommOptManager::Instance().Write(
     217            1 :                 handle, sendDataMsgPtr.get(), sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
     218            1 :             IDE_CTRL_VALUE_FAILED(
     219              :                 ret == IDE_DAEMON_OK, return IDE_DAEMON_CHANNEL_ERROR,
     220              :                 "hand shake failed ret %d, please check server is alive", ret);
     221              :         }
     222            0 :         sendDataMsgPtr->offset += (uint32_t)len;
     223            0 :         resLen -= len;
     224              :     }
     225            0 :     RecvResponse(handle);
     226            0 :     return IDE_DAEMON_NONE_ERROR;
     227            1 : }
     228              : 
     229            0 : MsgCode AdxMsgProto::RecvFile(const CommHandle& handle, int32_t fd)
     230              : {
     231            0 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_INVALID_PARAM_ERROR, "create message failed");
     232            0 :     MsgProto* msg = nullptr;
     233            0 :     int32_t length = 0;
     234              :     while (true) {
     235            0 :         int32_t ret = AdxCommOptManager::Instance().Read(handle, (IdeRecvBuffT)&msg, length, handle.timeout);
     236            0 :         IDE_CTRL_VALUE_FAILED(
     237              :             ret == IDE_DAEMON_OK && msg != nullptr, return IDE_DAEMON_CHANNEL_ERROR,
     238              :             "hand shake failed ret %d, read failed or timeout", ret);
     239            0 :         if (msg->msgType == MsgType::MSG_CTRL) { // check the message is ctrl or not
     240            0 :             IDE_LOGW("receive ctrl msg from device, stop receiving this file");
     241            0 :             IDE_XFREE_AND_SET_NULL(msg);
     242            0 :             return IDE_DAEMON_NONE_ERROR;
     243              :         }
     244            0 :         if (msg->sliceLen != 0 && msg->sliceLen <= MAX_PROTO_FILE_BUFFER_SIZE) {
     245            0 :             mmSsize_t len = mmWrite(fd, msg->data, msg->sliceLen);
     246            0 :             if (len < 0) {
     247            0 :                 char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     248            0 :                 IDE_LOGE(
     249              :                     "write file failed : info [%s]", mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     250            0 :                 IDE_XFREE_AND_SET_NULL(msg);
     251            0 :                 return IDE_DAEMON_UNKNOW_ERROR;
     252              :             }
     253              :         }
     254              : 
     255            0 :         if (msg->totalLen == msg->sliceLen + msg->offset) {
     256            0 :             break;
     257              :         }
     258              : 
     259            0 :         IDE_XFREE_AND_SET_NULL(msg);
     260            0 :     }
     261              : 
     262            0 :     if (SendResponse(handle, msg->reqType, msg->devId, MsgStatus::MSG_STATUS_NONE_ERROR) != IDE_DAEMON_NONE_ERROR) {
     263            0 :         IDE_LOGW("send response exception");
     264            0 :         IDE_XFREE_AND_SET_NULL(msg);
     265            0 :         return IDE_DAEMON_CHANNEL_ERROR;
     266              :     }
     267              : 
     268            0 :     IDE_XFREE_AND_SET_NULL(msg);
     269            0 :     return IDE_DAEMON_NONE_ERROR;
     270              : }
     271              : 
     272            2 : MsgCode AdxMsgProto::SendResponse(const CommHandle& handle, uint16_t type, uint16_t devId, MsgStatus status)
     273              : {
     274              :     MsgProto msg;
     275            2 :     (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
     276            2 :     (void)CreateCtrlMsg(msg, status);
     277            2 :     msg.reqType = type;
     278            2 :     msg.devId = devId;
     279            2 :     int32_t ret = AdxCommOptManager::Instance().Write(handle, (IdeSendBuffT)&msg, sizeof(MsgProto), COMM_OPT_BLOCK);
     280            2 :     if (ret != IDE_DAEMON_OK) {
     281            1 :         IDE_LOGE("send response failed ret %d, please check peer is alive", ret);
     282            1 :         return IDE_DAEMON_CHANNEL_ERROR;
     283              :     }
     284              : 
     285            1 :     IDE_LOGI("device(%d) cmd(%d) response success", devId, type);
     286            1 :     return IDE_DAEMON_NONE_ERROR;
     287              : }
     288              : 
     289            2 : MsgCode AdxMsgProto::RecvResponse(const CommHandle& handle)
     290              : {
     291            2 :     MsgProto* recvBuf = nullptr;
     292            2 :     int32_t length = 0;
     293            2 :     int32_t ret = AdxCommOptManager::Instance().Read(handle, (IdeRecvBuffT)&recvBuf, length, COMM_OPT_BLOCK);
     294            2 :     if (ret != IDE_DAEMON_OK || recvBuf == nullptr) {
     295            0 :         return IDE_DAEMON_CHANNEL_ERROR;
     296              :     }
     297              : 
     298            2 :     if (recvBuf->msgType == MsgType::MSG_CTRL && recvBuf->status == MsgStatus::MSG_STATUS_NONE_ERROR) {
     299            2 :         IDE_XFREE_AND_SET_NULL(recvBuf);
     300            2 :         return IDE_DAEMON_NONE_ERROR;
     301              :     }
     302              : 
     303            0 :     if (recvBuf->msgType == MsgType::MSG_CTRL && recvBuf->status == MsgStatus::MSG_STATUS_CACHE_FULL_ERROR) {
     304            0 :         IDE_XFREE_AND_SET_NULL(recvBuf);
     305            0 :         return IDE_DAEMON_DUMP_QUEUE_FULL;
     306              :     }
     307              : 
     308            0 :     IDE_XFREE_AND_SET_NULL(recvBuf);
     309            0 :     return IDE_DAEMON_UNKNOW_ERROR;
     310              : }
     311              : } // namespace Adx
        

Generated by: LCOV version 2.0-1