LCOV - code coverage report
Current view: top level - adcore/protocol - adx_msg_proto.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.1 % 197 146
Test Date: 2026-07-28 10:54:24 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(const CommHandle &handle, CmdClassT type, MsgStatus status,
      81              :     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(handle, sendDataMsgPtr.get(),
      89           10 :         sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
      90           10 :     if (ret != IDE_DAEMON_OK) {
      91            4 :         IDE_LOGE("send message failed, ret: %d, session: %zu, length: %u bytes, please check peer end is alive",
      92              :             ret, handle.session, length);
      93            4 :         return IDE_DAEMON_CHANNEL_ERROR;
      94              :     }
      95              : 
      96            6 :     return IDE_DAEMON_NONE_ERROR;
      97           10 : }
      98              : 
      99           11 : MsgCode AdxMsgProto::GetStringMsgData(const CommHandle &handle, std::string &value)
     100              : {
     101           11 :     MsgProto *req = nullptr;
     102           11 :     int32_t length = 0;
     103           11 :     int32_t blockType = COMM_OPT_NOBLOCK;
     104           11 :     if (handle.timeout == 0) {
     105            0 :         blockType = COMM_OPT_BLOCK;
     106           11 :     } else if (handle.timeout > 0) {
     107            9 :         blockType = handle.timeout;
     108              :     }
     109           11 :     int32_t ret = AdxCommOptManager::Instance().Read(handle, reinterpret_cast<IdeRecvBuffT>(&req), length, blockType);
     110           11 :     if ((ret == IDE_DAEMON_ERROR) || (req == nullptr) || (length <= 0)) {
     111            8 :         if (ret == DRV_ERROR_WAIT_TIMEOUT) {
     112            1 :             return IDE_DAEMON_HDC_TIMEOUT;
     113              :         }
     114            7 :         if (ret == IDE_DAEMON_SOCK_CLOSE) {
     115            0 :             return static_cast<MsgCode>(IDE_DAEMON_SOCK_CLOSE);
     116              :         }
     117            7 :         return IDE_DAEMON_CHANNEL_ERROR;
     118              :     }
     119              : 
     120            3 :     SharedPtr<MsgProto> msgPtr(req, IdeXfree);
     121            3 :     if (length <= static_cast<int32_t>(sizeof(MsgProto))) {
     122            1 :         IDE_LOGE("receive request length(%d bytes) exception", length);
     123            1 :         return IDE_DAEMON_INVALID_PARAM_ERROR;
     124              :     }
     125            2 :     req = nullptr;
     126            2 :     if (msgPtr->status == MsgStatus::MSG_STATUS_FILE_LOAD) {
     127            0 :         IDE_LOGE("receive request status(%d) exception", static_cast<int32_t>(MsgStatus::MSG_STATUS_FILE_LOAD));
     128            0 :         return IDE_DAEMON_UNKNOW_ERROR;
     129              :     }
     130            2 :     if (msgPtr->sliceLen + sizeof(MsgProto) != (uint32_t)length) {
     131            1 :         IDE_LOGE("receive request package(%u bytes) length(%d bytes) exception", msgPtr->sliceLen, length);
     132            1 :         return IDE_DAEMON_UNKNOW_ERROR;
     133              :     }
     134              : 
     135            1 :     value = std::string((IdeStringBuffer)msgPtr->data, msgPtr->sliceLen);
     136            1 :     return IDE_DAEMON_NONE_ERROR;
     137            3 : }
     138              : 
     139            3 : MsgCode AdxMsgProto::SendEventFile(const CommHandle &handle, CmdClassT type, uint16_t devId, int32_t fd)
     140              : {
     141            3 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_INVALID_PARAM_ERROR, "create message failed");
     142            3 :     MsgProto *msg = AdxMsgProto::CreateMsgPacket(type, devId, nullptr, MAX_PROTO_FILE_BUFFER_SIZE);
     143            3 :     IDE_CTRL_VALUE_FAILED(msg != nullptr, return IDE_DAEMON_MALLOC_ERROR, "create message failed");
     144            3 :     std::unique_ptr<MsgProto, decltype(&IdeXfree)> sendDataMsgPtr(msg, IdeXfree);
     145            3 :     msg = nullptr;
     146              : 
     147            3 :     mmSsize_t pos = mmLseek(fd, 0L, SEEK_SET);
     148            3 :     IDE_CTRL_VALUE_FAILED(pos >= 0, return IDE_DAEMON_UNKNOW_ERROR, "lseek set failed");
     149              : 
     150            3 :     mmSsize_t readLen = MAX_PROTO_FILE_BUFFER_SIZE;
     151            3 :     mmSsize_t len = mmRead(fd, sendDataMsgPtr->data, readLen);
     152            3 :     char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     153            3 :     int32_t err = mmGetErrorCode();
     154            3 :     if ((len < 0) && (err == EIO)) {
     155            1 :         IDE_LOGW("An EIO exception occurred when reading files from the event_sched directory");
     156            1 :         len = 0;
     157              :     } else {
     158            2 :         IDE_CTRL_VALUE_FAILED(len >= 0, return IDE_DAEMON_UNKNOW_ERROR,
     159              :             "Failed to read file in the event_sched directory: info [%s]",
     160              :             mmGetErrorFormatMessage(err, errBuf, MAX_ERRSTR_LEN));
     161              :     }
     162              : 
     163            2 :     if (len > MAX_DEV_FILE_SIZE) {
     164            0 :         IDE_LOGW("read file success, but the size has exceeded the maximum size of the dev file.");
     165              :     }
     166            2 :     sendDataMsgPtr->status = MsgStatus::MSG_STATUS_FILE_LOAD;
     167            2 :     sendDataMsgPtr->totalLen = len;
     168            2 :     sendDataMsgPtr->offset = 0;
     169            2 :     sendDataMsgPtr->sliceLen = (uint32_t)len;
     170            4 :     int32_t ret = AdxCommOptManager::Instance().Write(handle, sendDataMsgPtr.get(),
     171            2 :     sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
     172            2 :     IDE_CTRL_VALUE_FAILED(ret == IDE_DAEMON_OK, return IDE_DAEMON_CHANNEL_ERROR,
     173              :         "hand shake failed ret %d, please check server is alive", ret);
     174            0 :     RecvResponse(handle);
     175            0 :     return IDE_DAEMON_NONE_ERROR;
     176            3 : }
     177              : 
     178            1 : MsgCode AdxMsgProto::SendFile(const CommHandle &handle, CmdClassT type, uint16_t devId, int32_t fd)
     179              : {
     180            1 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_INVALID_PARAM_ERROR, "create message failed");
     181            1 :     MsgProto *msg = AdxMsgProto::CreateMsgPacket(type, devId, nullptr, MAX_PROTO_FILE_BUFFER_SIZE);
     182            1 :     IDE_CTRL_VALUE_FAILED(msg != nullptr, return IDE_DAEMON_MALLOC_ERROR, "create message failed");
     183            1 :     std::unique_ptr<MsgProto, decltype(&IdeXfree)> sendDataMsgPtr(msg, IdeXfree);
     184            1 :     msg = nullptr;
     185            1 :     mmSsize_t fileLength = mmLseek(fd, 0L, SEEK_END);
     186            1 :     IDE_CTRL_VALUE_FAILED(fileLength >= 0, return IDE_DAEMON_UNKNOW_ERROR, "lseek end failed");
     187              : 
     188            1 :     mmSsize_t pos = mmLseek(fd, 0L, SEEK_SET);
     189            1 :     IDE_CTRL_VALUE_FAILED(pos >= 0, return IDE_DAEMON_UNKNOW_ERROR, "lseek set failed");
     190            1 :     mmSsize_t resLen = fileLength;
     191            1 :     sendDataMsgPtr->status = MsgStatus::MSG_STATUS_FILE_LOAD;
     192            1 :     sendDataMsgPtr->totalLen = fileLength;
     193            1 :     sendDataMsgPtr->offset = 0;
     194              : 
     195            1 :     if (resLen == 0) {
     196            0 :         sendDataMsgPtr->sliceLen = (uint32_t)fileLength;
     197            0 :         int32_t ret = AdxCommOptManager::Instance().Write(handle, sendDataMsgPtr.get(),
     198            0 :         sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
     199            0 :         IDE_CTRL_VALUE_FAILED(ret == IDE_DAEMON_OK, return IDE_DAEMON_CHANNEL_ERROR,
     200              :             "send empty file failed ret %d, please check server is alive", ret);
     201              :     }
     202              : 
     203            1 :     while (resLen > 0) {
     204            1 :         mmSsize_t readLen = static_cast<uint32_t>(resLen) > MAX_PROTO_FILE_BUFFER_SIZE ?
     205              :                             MAX_PROTO_FILE_BUFFER_SIZE : resLen;
     206            1 :         mmSsize_t len = mmRead(fd, sendDataMsgPtr->data, readLen);
     207            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     208            2 :         IDE_CTRL_VALUE_FAILED(len >= 0, return IDE_DAEMON_UNKNOW_ERROR,
     209              :             "read file failed : info [%s]", mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     210            1 :         if (len > 0 && len <= readLen) {
     211            1 :             sendDataMsgPtr->sliceLen = (uint32_t)len;
     212            2 :             int32_t ret = AdxCommOptManager::Instance().Write(handle, sendDataMsgPtr.get(),
     213            1 :             sendDataMsgPtr->sliceLen + sizeof(MsgProto), COMM_OPT_BLOCK);
     214            1 :             IDE_CTRL_VALUE_FAILED(ret == IDE_DAEMON_OK, return IDE_DAEMON_CHANNEL_ERROR,
     215              :                 "hand shake failed ret %d, please check server is alive", ret);
     216              :         }
     217            0 :         sendDataMsgPtr->offset += (uint32_t)len;
     218            0 :         resLen -= len;
     219              :     }
     220            0 :     RecvResponse(handle);
     221            0 :     return IDE_DAEMON_NONE_ERROR;
     222            1 : }
     223              : 
     224            0 : MsgCode AdxMsgProto::RecvFile(const CommHandle &handle, int32_t fd)
     225              : {
     226            0 :     IDE_CTRL_VALUE_FAILED(fd >= 0, return IDE_DAEMON_INVALID_PARAM_ERROR, "create message failed");
     227            0 :     MsgProto *msg = nullptr;
     228            0 :     int32_t length = 0;
     229              :     while (true) {
     230            0 :         int32_t ret = AdxCommOptManager::Instance().Read(handle, (IdeRecvBuffT)&msg,
     231            0 :             length, handle.timeout);
     232            0 :             IDE_CTRL_VALUE_FAILED(ret == IDE_DAEMON_OK && msg != nullptr, return IDE_DAEMON_CHANNEL_ERROR,
     233              :                 "hand shake failed ret %d, read failed or timeout", ret);
     234            0 :         if (msg->msgType == MsgType::MSG_CTRL) { // check the message is ctrl or not
     235            0 :             IDE_LOGW("receive ctrl msg from device, stop receiving this file");
     236            0 :             IDE_XFREE_AND_SET_NULL(msg);
     237            0 :             return IDE_DAEMON_NONE_ERROR;
     238              :         }
     239            0 :         if (msg->sliceLen != 0 && msg->sliceLen <= MAX_PROTO_FILE_BUFFER_SIZE) {
     240            0 :             mmSsize_t len = mmWrite(fd, msg->data, msg->sliceLen);
     241            0 :             if (len < 0) {
     242            0 :                 char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     243            0 :                 IDE_LOGE("write file failed : info [%s]",
     244              :                          mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     245            0 :                 IDE_XFREE_AND_SET_NULL(msg);
     246            0 :                 return IDE_DAEMON_UNKNOW_ERROR;
     247              :             }
     248              :         }
     249              : 
     250            0 :         if (msg->totalLen == msg->sliceLen + msg->offset) {
     251            0 :             break;
     252              :         }
     253              : 
     254            0 :         IDE_XFREE_AND_SET_NULL(msg);
     255            0 :     }
     256              : 
     257            0 :     if (SendResponse(handle, msg->reqType, msg->devId, MsgStatus::MSG_STATUS_NONE_ERROR) !=
     258              :         IDE_DAEMON_NONE_ERROR) {
     259            0 :         IDE_LOGW("send response exception");
     260            0 :         IDE_XFREE_AND_SET_NULL(msg);
     261            0 :         return IDE_DAEMON_CHANNEL_ERROR;
     262              :     }
     263              : 
     264            0 :     IDE_XFREE_AND_SET_NULL(msg);
     265            0 :     return IDE_DAEMON_NONE_ERROR;
     266              : }
     267              : 
     268            2 : MsgCode AdxMsgProto::SendResponse(const CommHandle &handle, uint16_t type,
     269              :     uint16_t devId, MsgStatus status)
     270              : {
     271              :     MsgProto msg;
     272            2 :     (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
     273            2 :     (void)CreateCtrlMsg(msg, status);
     274            2 :     msg.reqType = type;
     275            2 :     msg.devId = devId;
     276            2 :     int32_t ret = AdxCommOptManager::Instance().Write(handle, (IdeSendBuffT)&msg, sizeof(MsgProto), COMM_OPT_BLOCK);
     277            2 :     if (ret != IDE_DAEMON_OK) {
     278            1 :         IDE_LOGE("send response failed ret %d, please check peer is alive", ret);
     279            1 :         return IDE_DAEMON_CHANNEL_ERROR;
     280              :     }
     281              : 
     282            1 :     IDE_LOGI("device(%d) cmd(%d) response success", devId, type);
     283            1 :     return IDE_DAEMON_NONE_ERROR;
     284              : }
     285              : 
     286            2 : MsgCode AdxMsgProto::RecvResponse(const CommHandle &handle)
     287              : {
     288            2 :     MsgProto *recvBuf = nullptr;
     289            2 :     int32_t length = 0;
     290            2 :     int32_t ret = AdxCommOptManager::Instance().Read(handle, (IdeRecvBuffT)&recvBuf, length, COMM_OPT_BLOCK);
     291            2 :     if (ret != IDE_DAEMON_OK || recvBuf == nullptr) {
     292            0 :         return IDE_DAEMON_CHANNEL_ERROR;
     293              :     }
     294              : 
     295            2 :     if (recvBuf->msgType == MsgType::MSG_CTRL && recvBuf->status == MsgStatus::MSG_STATUS_NONE_ERROR) {
     296            2 :         IDE_XFREE_AND_SET_NULL(recvBuf);
     297            2 :         return IDE_DAEMON_NONE_ERROR;
     298              :     }
     299              : 
     300            0 :     if (recvBuf->msgType == MsgType::MSG_CTRL && recvBuf->status == MsgStatus::MSG_STATUS_CACHE_FULL_ERROR) {
     301            0 :         IDE_XFREE_AND_SET_NULL(recvBuf);
     302            0 :         return IDE_DAEMON_DUMP_QUEUE_FULL;
     303              :     }
     304              : 
     305            0 :     IDE_XFREE_AND_SET_NULL(recvBuf);
     306            0 :     return IDE_DAEMON_UNKNOW_ERROR;
     307              : }
     308              : }
        

Generated by: LCOV version 2.0-1