LCOV - code coverage report
Current view: top level - client - ezcom_client.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 95.7 % 141 135
Test Date: 2026-08-12 11:05:07 Functions: 100.0 % 10 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              : 
      11              : #include "ezcom_client.h"
      12              : 
      13              : #include <securec.h>
      14              : #include "easy_comm.h"
      15              : 
      16              : #include "bqs_log.h"
      17              : #include "bqs_msg.h"
      18              : #include "bqs_util.h"
      19              : 
      20              : namespace {
      21              : std::mutex g_ezClientMut;
      22              : }
      23              : namespace bqs {
      24              : int32_t EzcomClient::clientFd_(0);
      25              : std::atomic<bool> EzcomClient::initFlag_(false);
      26              : 
      27              : /* *
      28              :  * Create instance of EzcomClient.
      29              :  * @return EzcomClient*: success
      30              :  */
      31           60 : EzcomClient* EzcomClient::GetInstance(const int32_t fd)
      32              : {
      33           60 :     const std::lock_guard<std::mutex> lk(g_ezClientMut);
      34           60 :     if (!initFlag_) {
      35            1 :         clientFd_ = fd;
      36            1 :         initFlag_ = true;
      37              :     }
      38              :     static EzcomClient instance;
      39           60 :     return &instance;
      40           60 : }
      41              : 
      42              : /* *
      43              :  * Assembly bind BQSMsg message
      44              :  * @return BQS_STATUS_OK: success, other: error
      45              :  */
      46            8 : BqsStatus EzcomClient::SerializeBindMsg(const std::vector<BQSBindQueueItem>& bindQueueVec, BQSMsg& bqsClientMsg) const
      47              : {
      48            8 :     BQS_LOG_INFO("Bind relation [add], stage [client], type [request], relation [size:%zu]", bindQueueVec.size());
      49            8 :     if (bindQueueVec.empty()) {
      50            3 :         BQS_LOG_WARN("The number of bind relation to be added should be greater than zero.");
      51            3 :         return BQS_STATUS_PARAM_INVALID;
      52              :     }
      53              : 
      54            5 :     bqsClientMsg.set_msg_type(BQSMsg::BIND);
      55            5 :     BQSBindQueueMsgs* const bqsBindQueueMsgBuff = bqsClientMsg.mutable_bind_queue_msgs();
      56              : 
      57          532 :     for (size_t i = 0U; i < bindQueueVec.size(); i++) {
      58          527 :         BQSBindQueueMsg* const bqsBindQueueEzMsg = bqsBindQueueMsgBuff->add_bind_queue_vec();
      59              : 
      60          527 :         bqsBindQueueEzMsg->set_src_queue_id(bindQueueVec[i].srcQueueId_);
      61          527 :         bqsBindQueueEzMsg->set_dst_queue_id(bindQueueVec[i].dstQueueId_);
      62          527 :         BQS_LOG_INFO(
      63              :             "Bind relation [add], stage [client], type [request], relation [src:%u, dst:%u]",
      64              :             bindQueueVec[i].srcQueueId_, bindQueueVec[i].dstQueueId_);
      65              :     }
      66            5 :     return BQS_STATUS_OK;
      67              : }
      68              : 
      69              : /* *
      70              :  * Send BQSMsg message to server
      71              :  * @return BQS_STATUS_OK: success, other: error
      72              :  */
      73           22 : BqsStatus EzcomClient::SendBqsMsg(const BQSMsg& bqsReqMsg, BQSMsg& bqsRespMsg) const
      74              : {
      75           22 :     const uint32_t bqsMsgLen = static_cast<uint32_t>(bqsReqMsg.ByteSizeLong());
      76           22 :     uint32_t reqLength = 0U;
      77           22 :     bool isOverflow = false;
      78           22 :     BqsCheckAssign32UAdd(bqsMsgLen, BQS_MSG_HEAD_SIZE, reqLength, isOverflow);
      79           22 :     if (isOverflow) {
      80            0 :         return BQS_STATUS_INNER_ERROR;
      81              :     }
      82              : 
      83           22 :     std::unique_ptr<char_t[]> reqData(new (std::nothrow) char_t[reqLength], std::default_delete<char_t[]>());
      84           22 :     if (reqData == nullptr) {
      85            0 :         BQS_LOG_ERROR("Malloc memory error, reqData is nullptr");
      86            0 :         return BQS_STATUS_INNER_ERROR;
      87              :     }
      88              :     // met Exceptions, no need to checks for security functions
      89           22 :     const auto ret = memset_s(reqData.get(), static_cast<size_t>(reqLength), 0, static_cast<size_t>(reqLength));
      90           22 :     if (ret != EOK) {
      91            1 :         BQS_LOG_ERROR("memset_s fail, ret is %d.", ret);
      92            1 :         return BQS_STATUS_INNER_ERROR;
      93              :     }
      94              :     // Add msg length to check
      95           21 :     *(PtrToPtr<char_t, uint32_t>(reqData.get())) = bqsMsgLen + BQS_MSG_HEAD_SIZE;
      96              : 
      97           21 :     if (!bqsReqMsg.SerializePartialToArray(reqData.get() + BQS_MSG_HEAD_SIZE, static_cast<int32_t>(bqsMsgLen))) {
      98            1 :         BQS_LOG_ERROR("serialize bqsReqMsg fail.");
      99            1 :         return BQS_STATUS_INNER_ERROR;
     100              :     }
     101              : 
     102           20 :     EzcomRequest req = {.id = 0U, .data = PtrToPtr<char_t, uint8_t>(reqData.get()), .size = reqLength};
     103           20 :     struct EzcomResponse resp = {0U};
     104              :     // Send msg and get response
     105           20 :     BQS_LOG_INFO("EzcomRPCSync begin, fd:%d, msg size:%u", clientFd_, reqLength);
     106           20 :     int32_t err = EzcomRPCSync(clientFd_, &req, &resp);
     107           20 :     if (err == -EAGAIN) {
     108            1 :         err = EzcomRPCSync(clientFd_, &req, &resp);
     109            1 :         BQS_LOG_INFO("Need to retry ezcom send, fd=%d", clientFd_);
     110              :     }
     111              : 
     112              :     // scope resp.data
     113            0 :     const ScopeGuard respDataGuard([&resp]() {
     114           20 :         if (resp.data != nullptr) {
     115           16 :             delete[] resp.data;
     116           16 :             resp.data = nullptr;
     117              :         }
     118           20 :     });
     119              : 
     120           20 :     if ((err < 0) || (resp.data == nullptr)) {
     121            4 :         BQS_LOG_ERROR("EasyRPCSync failed: %d", err);
     122            4 :         return BQS_STATUS_EASY_COMM_ERROR;
     123              :     }
     124              : 
     125           16 :     if (resp.size < BQS_MSG_HEAD_SIZE) {
     126            0 :         BQS_LOG_ERROR(
     127              :             "EasyRPCSync response size:%u error, should be not less than head size:%u.", resp.size, BQS_MSG_HEAD_SIZE);
     128            0 :         return BQS_STATUS_EASY_COMM_ERROR;
     129              :     }
     130              : 
     131           16 :     BQS_LOG_INFO("EzcomRPCSync end, response id:%u, response length:%u", resp.id, resp.size);
     132              : 
     133              :     // Check response msg
     134           16 :     const uint32_t currMsgSize = *(PtrToPtr<uint8_t, uint32_t>(resp.data));
     135           16 :     if (currMsgSize != resp.size) {
     136            4 :         BQS_LOG_ERROR("message error, head msg content:%u, response size:%u", currMsgSize, resp.size);
     137            4 :         return BQS_STATUS_EASY_COMM_ERROR;
     138              :     }
     139              : 
     140              :     // Parse response msg to BQSMsg
     141           12 :     char_t* const respData = PtrToPtr<uint8_t, char_t>(resp.data);
     142           12 :     const uint32_t parseLength = currMsgSize - BQS_MSG_HEAD_SIZE;
     143           12 :     if (!bqsRespMsg.ParseFromArray(respData + BQS_MSG_HEAD_SIZE, static_cast<int32_t>(parseLength))) {
     144            1 :         BQS_LOG_ERROR("parse bqsRespMsg fail.");
     145            1 :         return BQS_STATUS_INNER_ERROR;
     146              :     }
     147           11 :     return BQS_STATUS_OK;
     148           22 : }
     149              : 
     150              : /* *
     151              :  * Parse bind response BQSMsg message
     152              :  * @return number of bind relation success
     153              :  */
     154            9 : uint32_t EzcomClient::ParseBindRespMsg(BQSMsg& bqsRespMsg, std::vector<BQSBindQueueResult>& bindResultVec) const
     155              : {
     156            9 :     uint32_t bindNum = 0U;
     157            9 :     const BQSBindQueueRsps* const bqsBindQueueRspBuff = bqsRespMsg.mutable_resp_msgs();
     158              : 
     159            9 :     BQS_LOG_INFO(
     160              :         "Bind relation [add/del], stage [client], type [response], relation [size:%d]",
     161              :         bqsBindQueueRspBuff->bind_result_vec_size());
     162         1047 :     for (int32_t i = 0; i < bqsBindQueueRspBuff->bind_result_vec_size(); i++) {
     163         1038 :         const BQSBindQueueRsp bqsBindQueueEzRsp = bqsBindQueueRspBuff->bind_result_vec(i);
     164         1038 :         const BQSBindQueueResult bindResult = {bqsBindQueueEzRsp.bind_result()};
     165         1038 :         bindResultVec.push_back(bindResult);
     166              : 
     167         1038 :         const int32_t result = bqsBindQueueEzRsp.bind_result();
     168         1038 :         BQS_LOG_INFO(
     169              :             "Bind relation [add/del], stage [client], type [response], relation [index:%d, result:%d].", i, result);
     170         1038 :         if (result == BQS_STATUS_OK) {
     171         1033 :             bindNum++;
     172              :         }
     173         1038 :     }
     174            9 :     return bindNum;
     175              : }
     176              : 
     177              : /* *
     178              :  * Assembly unbind BQSMsg message
     179              :  * @return BQS_STATUS_OK: success, other: failed
     180              :  */
     181            7 : BqsStatus EzcomClient::SerializeUnbindMsg(const std::vector<BQSQueryPara>& bqsQueryParaVec, BQSMsg& bqsClientMsg) const
     182              : {
     183            7 :     BQS_LOG_INFO("Bind relation [del], stage [client], type [request], relation [size:%zu]", bqsQueryParaVec.size());
     184            7 :     if (bqsQueryParaVec.size() == 0U) {
     185            1 :         BQS_LOG_WARN("The number of bind relation to be deleted should be greater than zero.");
     186            1 :         return BQS_STATUS_PARAM_INVALID;
     187              :     }
     188              : 
     189            6 :     bqsClientMsg.set_msg_type(BQSMsg::UNBIND);
     190            6 :     BQSQueryMsgs* const bqsQueryMsgBuff = bqsClientMsg.mutable_query_msgs();
     191              : 
     192          519 :     for (size_t i = 0U; i < bqsQueryParaVec.size(); i++) {
     193          513 :         BQSQueryMsg* const bqsQueryEzMsg = bqsQueryMsgBuff->add_query_msg_vec();
     194              : 
     195          513 :         bqsQueryEzMsg->set_key_type(static_cast<BQSQueryMsg::QsQueryType>(bqsQueryParaVec[i].keyType_));
     196          513 :         BQSBindQueueMsg* const bqsBindQueueEzMsg = bqsQueryEzMsg->mutable_bind_queue_item();
     197              : 
     198          513 :         bqsBindQueueEzMsg->set_src_queue_id(bqsQueryParaVec[i].bqsBindQueueItem_.srcQueueId_);
     199          513 :         bqsBindQueueEzMsg->set_dst_queue_id(bqsQueryParaVec[i].bqsBindQueueItem_.dstQueueId_);
     200              : 
     201          513 :         BQS_LOG_INFO(
     202              :             "Bind relation [del], stage [client], type [request], relation [type{0:src, 1:dst, 2:src-dst}:%d, "
     203              :             "src:%u, dst:%u]",
     204              :             bqsQueryParaVec[i].keyType_, bqsQueryParaVec[i].bqsBindQueueItem_.srcQueueId_,
     205              :             bqsQueryParaVec[i].bqsBindQueueItem_.dstQueueId_);
     206              :     }
     207            6 :     return BQS_STATUS_OK;
     208              : }
     209              : 
     210              : /**
     211              :  * Assembly get bind BQSMsg message
     212              :  * @return BQS_STATUS_OK: success, other: failed
     213              :  */
     214            4 : BqsStatus EzcomClient::SerializeGetBindMsg(const BQSQueryPara& queryPara, BQSMsg& bqsClientMsg) const
     215              : {
     216            4 :     BQS_LOG_INFO("Bind relation [get], stage [client], type [request]");
     217            4 :     bqsClientMsg.set_msg_type(BQSMsg::GET_BIND);
     218            4 :     BQSQueryMsg* const bqsQueryEzMsg = bqsClientMsg.mutable_query_msg();
     219              : 
     220            4 :     bqsQueryEzMsg->set_key_type(static_cast<BQSQueryMsg::QsQueryType>(queryPara.keyType_));
     221            4 :     BQSBindQueueMsg* const bqsBindQueueEzMsg = bqsQueryEzMsg->mutable_bind_queue_item();
     222              : 
     223            4 :     bqsBindQueueEzMsg->set_src_queue_id(queryPara.bqsBindQueueItem_.srcQueueId_);
     224            4 :     bqsBindQueueEzMsg->set_dst_queue_id(queryPara.bqsBindQueueItem_.dstQueueId_);
     225            4 :     BQS_LOG_INFO(
     226              :         "Bind relation [get], stage [client], type [request], relation [type{0:src, 1:dst, 2:src-dst}:%d, "
     227              :         "src:%u, dst:%u]",
     228              :         queryPara.keyType_, queryPara.bqsBindQueueItem_.srcQueueId_, queryPara.bqsBindQueueItem_.dstQueueId_);
     229            4 :     return BQS_STATUS_OK;
     230              : }
     231              : 
     232              : /**
     233              :  * Parse get bind response BQSMsg message
     234              :  * @return number of bind relation
     235              :  */
     236            2 : uint32_t EzcomClient::ParseGetBindRespMsg(BQSMsg& bqsRespMsg, std::vector<BQSBindQueueItem>& bindQueueVec) const
     237              : {
     238            2 :     uint32_t bindNum = 0U;
     239            2 :     const BQSBindQueueMsgs* const bqsBindQueueMsgBuff = bqsRespMsg.mutable_bind_queue_msgs();
     240              : 
     241            2 :     bindNum = static_cast<uint32_t>(bqsBindQueueMsgBuff->bind_queue_vec_size());
     242            2 :     BQS_LOG_INFO("Bind relation [get], stage [client], type [response], relation [size:%u]", bindNum);
     243           12 :     for (uint32_t i = 0U; i < bindNum; i++) {
     244           10 :         const BQSBindQueueMsg bqsBindQueueEzMsg = bqsBindQueueMsgBuff->bind_queue_vec(static_cast<int32_t>(i));
     245           10 :         const BQSBindQueueItem bindItem = {bqsBindQueueEzMsg.src_queue_id(), bqsBindQueueEzMsg.dst_queue_id()};
     246           10 :         bindQueueVec.push_back(bindItem);
     247           10 :         BQS_LOG_INFO(
     248              :             "Bind relation [get], stage [client], type [response], relation [index:%u, src:%u, dst:%u]", i,
     249              :             bindItem.srcQueueId_, bindItem.dstQueueId_);
     250           10 :     }
     251            2 :     return bindNum;
     252              : }
     253              : 
     254              : /* *
     255              :  * Assembly get paged bind BQSMsg message
     256              :  * @return BQS_STATUS_OK: success, other: failed
     257              :  */
     258            5 : BqsStatus EzcomClient::SerializeGetPagedBindMsg(const uint32_t offset, const uint32_t limit, BQSMsg& bqsClientMsg) const
     259              : {
     260            5 :     BQS_LOG_INFO("Bind relation [get_paged], stage [client], type [request]");
     261            5 :     bqsClientMsg.set_msg_type(BQSMsg::GET_ALL_BIND);
     262            5 :     BQSPagedMsg* const bqsPagedEzMsg = bqsClientMsg.mutable_paged_msg();
     263            5 :     bqsPagedEzMsg->set_offset(offset);
     264            5 :     bqsPagedEzMsg->set_limit(limit);
     265            5 :     return BQS_STATUS_OK;
     266              : }
     267              : 
     268              : /**
     269              :  * Parse get paged bind response BQSMsg message
     270              :  * @return number of bind relation
     271              :  */
     272            3 : uint32_t EzcomClient::ParseGetPagedBindRespMsg(
     273              :     BQSMsg& bqsRespMsg, std::vector<BQSBindQueueItem>& bindQueueVec, uint32_t& total) const
     274              : {
     275            3 :     uint32_t bindNum = 0U;
     276            3 :     const BQSBindQueueMsgs* const bqsBindQueueMsgBuff = bqsRespMsg.mutable_bind_queue_msgs();
     277              : 
     278            3 :     const BQSPagedMsg* const bqsPagedEzMsg = bqsRespMsg.mutable_paged_msg();
     279            3 :     total = bqsPagedEzMsg->total();
     280              : 
     281            3 :     bindNum = static_cast<uint32_t>(bqsBindQueueMsgBuff->bind_queue_vec_size());
     282            3 :     BQS_LOG_INFO("Bind relation [get_paged], stage [client], type [response], relation [size:%u]", bindNum);
     283           15 :     for (uint32_t i = 0U; i < bindNum; i++) {
     284           12 :         const BQSBindQueueMsg bqsBindQueueEzMsg = bqsBindQueueMsgBuff->bind_queue_vec(static_cast<int32_t>(i));
     285           12 :         const BQSBindQueueItem bindItem = {bqsBindQueueEzMsg.src_queue_id(), bqsBindQueueEzMsg.dst_queue_id()};
     286           12 :         bindQueueVec.push_back(bindItem);
     287           12 :         BQS_LOG_INFO(
     288              :             "Bind relation [get_paged], stage [client], type [response], relation [index:%u, src:%u, dst:%u]", i,
     289              :             bindItem.srcQueueId_, bindItem.dstQueueId_);
     290           12 :     }
     291            3 :     return bindNum;
     292              : }
     293              : } // namespace bqs
        

Generated by: LCOV version 2.0-1