LCOV - code coverage report
Current view: top level - dgwclient - dgw_client.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.2 % 934 852
Test Date: 2026-07-28 10:54:05 Functions: 97.9 % 48 47

            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 "dgw_client.h"
      12              : #include <algorithm>
      13              : #include <map>
      14              : #include <mutex>
      15              : #include <string>
      16              : #include <sys/types.h>
      17              : #include <unistd.h>
      18              : #include <securec.h>
      19              : #include "driver/ascend_hal.h"
      20              : #include "driver/ascend_hal_define.h"
      21              : #include "common/bqs_status.h"
      22              : #include "bqs_log.h"
      23              : #include "bqs_util.h"
      24              : #include "common/type_def.h"
      25              : #include "queue_schedule_feature_ctrl.h"
      26              : #define AICPU_PLAT_GET_CHIP(type)           (((type) >> 8U) & 0xffU)
      27              : 
      28              : namespace {
      29              : std::mutex g_dgwClientMut;
      30              : std::map<std::tuple<uint32_t, pid_t, bool>, std::shared_ptr<bqs::DgwClient>> g_dgwClientInstanceMap;
      31              : // allowed max routes number
      32              : constexpr uint32_t MAX_ROUTES_NUM = 8000U;
      33              : // allowed max endpoints number in one group
      34              : constexpr uint32_t MAX_ENDPOINTS_NUM_IN_SINGLE_GROUP = 1000U;
      35              : // default qsPid when create client
      36              : constexpr pid_t DEFAULT_QS_PID = -1;
      37              : constexpr uint16_t MAJOR_VERSION = 3U;
      38              : constexpr uint32_t QUERY_LINK_STATUS_INTERVAL = 100000U;  // 100ms
      39              : constexpr uint32_t QUERY_LINK_STATUS_UNIT = 1000000U;  // 1s
      40              : constexpr uint32_t RESOURCE_ID_HOST_DEVICE_BIT_NUM = 14;
      41              : constexpr uint32_t ROUCE_ID_DEVICE_ID_DATA_MASK = 0x3FFFU;
      42              : constexpr uint32_t ROUCE_ID_FRONT_PART_DATA_MASK = 0xC000U;
      43              : 
      44              : std::vector<uint32_t> g_userDeviceInfo;
      45              : bool g_hadGetVisibleDevices = false;
      46              : int64_t g_chipType = 18;
      47              : bool g_hadGetChipType = false;
      48              : } // namespace
      49              : 
      50              : namespace bqs {
      51              : 
      52            1 : DgwClient::DgwClient(const uint32_t deviceId) : deviceId_(deviceId), qsPid_(DEFAULT_QS_PID), procSign_(), curPid_(-1),
      53            2 :                                                 curGroupId_(0U), piplineQueueId_(0U), initFlag_(false), isProxy_(false),
      54            1 :                                                 isServerOldVersion_(false)
      55              : {
      56            1 : }
      57              : 
      58            0 : DgwClient::DgwClient(const uint32_t deviceId, const pid_t qsPid) : deviceId_(deviceId), qsPid_(qsPid), procSign_(),
      59            0 :     curPid_(-1), curGroupId_(0U), piplineQueueId_(0U), initFlag_(false), isProxy_(false), isServerOldVersion_(false)
      60              : {
      61            0 : }
      62              : 
      63           16 : DgwClient::DgwClient(const uint32_t deviceId, const pid_t qsPid, const bool proxy) : deviceId_(deviceId),
      64           16 :     qsPid_(qsPid), procSign_(), curPid_(-1), curGroupId_(0U), piplineQueueId_(0U), initFlag_(false), isProxy_(proxy), isServerOldVersion_(false)
      65              : {
      66           16 : }
      67              : 
      68           70 : std::shared_ptr<DgwClient> DgwClient::GetInstance(const uint32_t deviceId)
      69              : {
      70           70 :     return GetInstance(deviceId, DEFAULT_QS_PID, false);
      71              : }
      72              : 
      73            2 : std::shared_ptr<DgwClient> DgwClient::GetInstance(const uint32_t deviceId, const pid_t qsPid)
      74              : {
      75            2 :     return GetInstance(deviceId, qsPid, false);
      76              : }
      77              : 
      78           77 : std::shared_ptr<DgwClient> DgwClient::GetInstance(const uint32_t deviceId, const pid_t qsPid, const bool proxy)
      79              : {
      80           77 :     BQS_LOG_INFO("[DgwClient] begin to get instance, deviceId=%u, proxy=%d", deviceId, proxy);
      81           77 :     uint32_t logicDeviceId = deviceId;
      82           77 :     if (proxy) {
      83            5 :         if (!g_hadGetChipType && (GetPlatformInfo(deviceId) != static_cast<int32_t>(BQS_STATUS_OK))) {
      84            0 :             return nullptr;
      85              :         }
      86           10 :         if (QSFeatureCtrl::IsSupportSetVisibleDevices(g_chipType) && 
      87            5 :             (ChangeUserDeviceIdToLogicDeviceId(deviceId, logicDeviceId) != static_cast<int32_t>(BQS_STATUS_OK))) {
      88            1 :             return nullptr;
      89              :         }
      90            4 :         BQS_LOG_INFO("[DgwClient] after change deviceId, logicDeviceId=%u", logicDeviceId);
      91              :     }
      92              : 
      93           76 :     std::lock_guard<std::mutex> lk(g_dgwClientMut);
      94           76 :     const auto iter = g_dgwClientInstanceMap.find({logicDeviceId, qsPid, proxy});
      95           76 :     if (iter != g_dgwClientInstanceMap.end()) {
      96           60 :         return iter->second;
      97              :     } else {
      98           16 :         std::shared_ptr<DgwClient> clientImplPtr = nullptr;
      99              :         try {
     100           16 :             clientImplPtr = std::make_shared<DgwClient>(logicDeviceId, qsPid, proxy);
     101            0 :         } catch (std::bad_alloc &error) {
     102            0 :             BQS_LOG_ERROR("[DgwClient] fail to create client(%u-%d-%d) for %s", logicDeviceId, qsPid, proxy, error.what());
     103            0 :         }
     104           16 :         if (clientImplPtr != nullptr) {
     105           16 :             (void)g_dgwClientInstanceMap.insert({{logicDeviceId, qsPid, proxy}, clientImplPtr});
     106              :         }
     107           16 :         return clientImplPtr;
     108           16 :     }
     109           76 : }
     110              : 
     111            7 : int32_t DgwClient::Initialize(const uint32_t dgwPid, const std::string procSign, const bool isProxy,
     112              :                               const int32_t timeout)
     113              : {
     114            7 :     BQS_LOG_INFO("[DgwClient] Initialize Begin, change qsPid from %d to %d, isproxy: %d",
     115              :         qsPid_, static_cast<pid_t>(dgwPid), isProxy);
     116            7 :     qsPid_ = static_cast<pid_t>(dgwPid);
     117            7 :     procSign_ = procSign;
     118            7 :     curPid_ = getpid();
     119            7 :     isProxy_ = isProxy;
     120            7 :     isServerOldVersion_ = false;
     121              : 
     122            7 :     auto drvRet = halEschedAttachDevice(deviceId_);
     123            7 :     if ((drvRet != DRV_ERROR_NONE) && (drvRet != DRV_ERROR_PROCESS_REPEAT_ADD)) {
     124            1 :         BQS_LOG_ERROR("Failed to attach device[%u], result[%d].", deviceId_, static_cast<int32_t>(drvRet));
     125            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     126              :     }
     127              : 
     128              :     // send init event to qs
     129            6 :     QsBindInit qsBindInit = {};
     130            6 :     qsBindInit.pid = curPid_;
     131            6 :     qsBindInit.grpId = curGroupId_;
     132            6 :     qsBindInit.majorVersion = MAJOR_VERSION;
     133              : 
     134            6 :     QsProcMsgRsp qsProcMsgRsp = {};
     135            6 :     int32_t ret = SendEventToQsSync(&qsBindInit, sizeof(QsBindInit), ACL_BIND_QUEUE_INIT, qsProcMsgRsp, timeout);
     136            6 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     137            0 :         return ret;
     138              :     }
     139            6 :     if (qsProcMsgRsp.retCode != static_cast<int32_t>(BQS_STATUS_OK)) {
     140            0 :         BQS_LOG_WARN("[DgwClient] Initialize event_reply retCode is[%u]", qsProcMsgRsp.retCode);
     141            0 :         return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     142              :     }
     143              : 
     144            6 :     if (qsProcMsgRsp.majorVersion != qsBindInit.majorVersion &&
     145            6 :         qsProcMsgRsp.majorVersion < MAJOR_VERSION) {
     146            6 :         BQS_LOG_INFO("[DgwClient] server majorVersion is[%u] client majorVersion is[%u], set isServerOldVersion",
     147              :             qsProcMsgRsp.majorVersion, qsBindInit.majorVersion);
     148            6 :         isServerOldVersion_ = true;
     149              :     }
     150              : 
     151            6 :     piplineQueueId_ = qsProcMsgRsp.retValue;
     152            6 :     BQS_LOG_DEBUG("[DgwClient] Success to get queue id[%u].", piplineQueueId_);
     153              : 
     154              :     // host FlowGW LOCAL_Q need set this before use these queues
     155            6 :     if (!isProxy_) {
     156              :         QueueSetInputPara inPutParam;
     157            6 :         (void)halQueueSet(deviceId_, QUEUE_ENABLE_LOCAL_QUEUE, &inPutParam);
     158              :     }
     159              : 
     160              :     // Before attach queue, process should call halQueueInit.
     161            6 :     drvRet = halQueueInit(deviceId_);
     162            6 :     if ((drvRet != DRV_ERROR_NONE) && (drvRet != DRV_ERROR_REPEATED_INIT)) {
     163            1 :         BQS_LOG_ERROR("[DgwClient] halQueueInit error, ret=%d", static_cast<int32_t>(drvRet));
     164            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     165              :     }
     166              : 
     167            5 :     drvRet = halQueueAttach(deviceId_, piplineQueueId_, -1);
     168            5 :     if (drvRet != DRV_ERROR_NONE) {
     169            1 :         BQS_LOG_ERROR("[DgwClient] Attach queue failed, queue id[%u], drvRet [%d].", piplineQueueId_,
     170              :                       static_cast<int32_t>(drvRet));
     171            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     172              :     }
     173              : 
     174            4 :     BuffCfg buffCfg = {};
     175            4 :     ret = halBuffInit(&buffCfg);
     176            4 :     if ((ret != static_cast<int32_t>(DRV_ERROR_NONE)) && (ret != static_cast<int32_t>(DRV_ERROR_REPEATED_INIT))) {
     177            1 :         BQS_LOG_ERROR("[DgwClient] Failed to halBuffInit, ret=[%d].", ret);
     178            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     179              :     }
     180              : 
     181            3 :     initFlag_ = true;
     182            3 :     BQS_LOG_INFO("[DgwClient] Success to Initialize deviceId=[%u], pid=[%u].", deviceId_, curPid_);
     183            3 :     return static_cast<int32_t>(BQS_STATUS_OK);
     184              : }
     185              : 
     186            1 : int32_t DgwClient::Finalize()
     187              : {
     188            1 :     return static_cast<int32_t>(BQS_STATUS_OK);
     189              : }
     190              : 
     191           12 : int32_t DgwClient::CreateHcomHandle(const std::string &rankTable, const int32_t rankId,
     192              :                                     const void * const reserve, uint64_t &handle, const int32_t timeout)
     193              : {
     194              :     (void)reserve;
     195           12 :     BQS_LOG_INFO("[DgwClient] Begin to create hcom handle.");
     196           12 :     if (!initFlag_) {
     197            1 :         BQS_LOG_ERROR("[DgwClient] Please check whether datagw client has been initialized.");
     198            1 :         return static_cast<int32_t>(BQS_STATUS_NOT_INIT);
     199              :     }
     200           11 :     if (rankTable.empty()) {
     201            1 :         BQS_LOG_ERROR("[DgwClient] Rank table is empty!");
     202            1 :         return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
     203              :     }
     204              : 
     205              :     // calculate mbuf len: 1. HcomHandleInfo 2. rank table 3. CfgRetInfo
     206           10 :     const size_t cfgLen = sizeof(HcomHandleInfo) + rankTable.length();
     207              :     // check two uint32 integer adding whether overflow and execute adding when not overflow.
     208           10 :     uint32_t mbufLen = 0U;
     209           10 :     bool isOverflow = false;
     210           10 :     BqsCheckAssign32UAdd(cfgLen, sizeof(CfgRetInfo), mbufLen, isOverflow);
     211           10 :     if (isOverflow) {
     212            1 :         BQS_LOG_ERROR("mbufLen[%u] is invalid.", mbufLen);
     213            1 :         return BQS_STATUS_PARAM_INVALID;
     214              :     }
     215              :     // create hcom handle info
     216              :     HcomHandleInfo info;
     217            9 :     info.rankId = rankId;
     218            9 :     info.rankTableLen = rankTable.length();
     219            9 :     info.rankTableOffset = sizeof(HcomHandleInfo);
     220              : 
     221            9 :     std::list<std::pair<uintptr_t, size_t>> dataList;
     222            9 :     (void)dataList.emplace_back(std::make_pair(PtrToValue(&info), sizeof(HcomHandleInfo)));
     223            9 :     (void)dataList.emplace_back(std::make_pair(PtrToValue(rankTable.c_str()), rankTable.length()));
     224              : 
     225              :     // operate config to server
     226            9 :     std::vector<int32_t> emptyVec;
     227            9 :     const ConfigParams cfgParams = {
     228              :         .info = &info,
     229              :         .query = nullptr,
     230              :         .cfgInfo = nullptr,
     231              :         .cfgLen = cfgLen,
     232            9 :         .totalLen = static_cast<size_t>(mbufLen),
     233            9 :     };
     234            9 :     const auto ret = OperateConfigToServer(QueueSubEventType::DGW_CREATE_HCOM_HANDLE, cfgParams, dataList, emptyVec,
     235              :         timeout);
     236            9 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     237            1 :         BQS_LOG_ERROR("[DgwClient] Failed to create hcom handle.");
     238            1 :         return ret;
     239              :     }
     240              :     // get hcom handle
     241            8 :     handle = info.hcomHandle;
     242            8 :     BQS_LOG_INFO("[DgwClient] Success to create hcom handle[%lu].", handle);
     243            8 :     return static_cast<int32_t>(BQS_STATUS_OK);
     244            9 : }
     245              : 
     246            9 : int32_t DgwClient::DestroyHcomHandle(const uint64_t handle, const int32_t timeout)
     247              : {
     248            9 :     BQS_LOG_INFO("[DgwClient] Begin to Destroy hcom handle[%lu].", handle);
     249            9 :     if (!initFlag_) {
     250            1 :         BQS_LOG_ERROR("[DgwClient] Please check whether datagw client has been initialized.");
     251            1 :         return static_cast<int32_t>(BQS_STATUS_NOT_INIT);
     252              :     }
     253              : 
     254              :     // calculate mbuf len: 1. HcomHandleInfo; 2. CfgRetInfo
     255            8 :     const size_t cfgLen = sizeof(HcomHandleInfo);
     256            8 :     const size_t mbufLen = cfgLen + sizeof(CfgRetInfo);
     257              :     // hcom handle info
     258              :     HcomHandleInfo info;
     259            8 :     info.rankTableLen = 0UL;
     260            8 :     info.rankTableOffset = 0UL;
     261            8 :     info.hcomHandle = handle;
     262              : 
     263            8 :     std::list<std::pair<uintptr_t, size_t>> dataList;
     264            8 :     (void)dataList.emplace_back(std::make_pair(PtrToValue(&info), sizeof(HcomHandleInfo)));
     265              : 
     266              :     // operate config to server
     267            8 :     std::vector<int32_t> emptyVec;
     268            8 :     const ConfigParams cfgParams = {
     269              :         .info = &info,
     270              :         .query = nullptr,
     271              :         .cfgInfo = nullptr,
     272              :         .cfgLen = cfgLen,
     273              :         .totalLen = mbufLen,
     274            8 :     };
     275            8 :     const auto ret = OperateConfigToServer(QueueSubEventType::DGW_DESTORY_HCOM_HANDLE, cfgParams, dataList, emptyVec,
     276              :         timeout);
     277            8 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     278            1 :         BQS_LOG_ERROR("[DgwClient] Failed to destroy hcom handle[%lu].", handle);
     279            1 :         return ret;
     280              :     }
     281            7 :     BQS_LOG_INFO("[DgwClient] Success to destroy hcom handle[%lu].", handle);
     282            7 :     return static_cast<int32_t>(BQS_STATUS_OK);
     283            8 : }
     284              : 
     285           51 : static bool IsQueueOperationCmd(ConfigInfo &cfgInfo)
     286              : {
     287           93 :     return ((cfgInfo.cmd == ConfigCmd::DGW_CFG_CMD_BIND_ROUTE) ||
     288           87 :             (cfgInfo.cmd == ConfigCmd::DGW_CFG_CMD_UNBIND_ROUTE) ||
     289           87 :             (cfgInfo.cmd == ConfigCmd::DGW_CFG_CMD_QRY_ROUTE));
     290              : }
     291              : 
     292           31 : static bool IsGroupOperationCmd(ConfigInfo &cfgInfo)
     293              : {
     294           51 :     return ((cfgInfo.cmd == ConfigCmd::DGW_CFG_CMD_ADD_GROUP) ||
     295           51 :             (cfgInfo.cmd == ConfigCmd::DGW_CFG_CMD_QRY_GROUP));
     296              : }
     297              : 
     298           44 : int32_t DgwClient::UpdateConfig(ConfigInfo &cfgInfo, std::vector<int32_t> &cfgRets, const int32_t timeout)
     299              : {
     300           44 :     BQS_LOG_INFO("[DgwClient] Begin to update config.");
     301              :     // check dgw client initialized
     302           44 :     if (!initFlag_) {
     303            1 :         BQS_LOG_ERROR("[DgwClient] please check whether datagw client has initialized successfully.");
     304            1 :         return static_cast<int32_t>(BQS_STATUS_NOT_INIT);
     305              :     }
     306              : 
     307           43 :     if (isServerOldVersion_ && IsGroupOperationCmd(cfgInfo)) {
     308            1 :         Endpoint *endpoints = cfgInfo.cfg.groupCfg.endpoints;
     309            1 :         if (endpoints != nullptr) {
     310            1 :             const bqs::EndpointType type = endpoints->type;
     311            1 :             if (type == bqs::EndpointType::MEM_QUEUE &&
     312            1 :                 endpoints->attr.memQueueAttr.queueType == bqs::CLIENT_Q) {
     313            1 :                 BQS_LOG_ERROR("[DgwClient] isServerOldVersion CLIENT_Q function interception");
     314            1 :                 return static_cast<int32_t>(BQS_STATUS_ENDPOINT_MEM_TYPE_NOT_SUPPORT);
     315              :             }
     316              :         }
     317              :     }
     318              : 
     319              :     // mbuf memory layout: 1.config info / 2.Routes or Endpoints / 3.config results
     320              :     // calculate config length: 1.config info + 2.Routes or Endpoints
     321           42 :     size_t cfgLen = 0UL;
     322           42 :     std::list<std::pair<uintptr_t, size_t>> dataList;
     323              :     // here is to consider compatibility between client and server different versions
     324           42 :     std::unique_ptr<Route[]> spareRoutes = nullptr;
     325           42 :     std::unique_ptr<Endpoint[]> spareEndpoints = nullptr;
     326           42 :     if (IsQueueOperationCmd(cfgInfo)) {
     327           15 :         const uint32_t routeNum = cfgInfo.cfg.routesCfg.routeNum;
     328           15 :         spareRoutes.reset(new (std::nothrow) Route[routeNum]);
     329           15 :         if (spareRoutes == nullptr) {
     330            0 :             BQS_LOG_ERROR("[DgwClient] malloc failed on spareRoutes.");
     331            0 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     332              :         }
     333           27 :     } else if (IsGroupOperationCmd(cfgInfo)) {
     334           10 :         const uint32_t endpointNum = cfgInfo.cfg.groupCfg.endpointNum;
     335           10 :         spareEndpoints.reset(new (std::nothrow) Endpoint[endpointNum]);
     336           10 :         if (spareEndpoints == nullptr) {
     337            0 :             BQS_LOG_ERROR("[DgwClient] malloc failed on spareEndpoints.");
     338            0 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     339              :         }
     340              :     } else {
     341           17 :         BQS_LOG_INFO("[DgwClient] config cmd is %d.", static_cast<int32_t>(cfgInfo.cmd));
     342              :     }
     343           42 :     auto ret = CalcConfigInfoLen(cfgInfo, cfgLen, dataList, spareRoutes, spareEndpoints);
     344           42 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     345            1 :         BQS_LOG_ERROR("[DgwClient] check and calculate length of config info failed.");
     346            1 :         return ret;
     347              :     }
     348              :     // calculate result length: 3.config results
     349           41 :     size_t retLen = 0UL;
     350           41 :     ret = CalcResultLen(cfgInfo, retLen);
     351           41 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     352            1 :         BQS_LOG_ERROR("[DgwClient] calculate length of result failed.");
     353            1 :         return ret;
     354              :     }
     355              : 
     356              :     ConfigQuery unusedParam;
     357           40 :     const ConfigParams cfgParams = {
     358              :         .info = nullptr,
     359              :         .query = &unusedParam,
     360              :         .cfgInfo = &cfgInfo,
     361              :         .cfgLen = cfgLen,
     362           40 :         .totalLen = cfgLen + retLen,
     363           40 :     };
     364           40 :     ret = OperateConfigToServer(QueueSubEventType::UPDATE_CONFIG, cfgParams, dataList, cfgRets, timeout);
     365           40 :     BQS_LOG_INFO("[DgwClient] Finish to update config, cmd is %d, ret is [%d].",
     366              :                  static_cast<int32_t>(cfgInfo.cmd), ret);
     367           40 :     return ret;
     368           42 : }
     369              : 
     370           13 : int32_t DgwClient::QueryConfig(const ConfigQuery &query, ConfigInfo &cfgInfo, const int32_t timeout)
     371              : {
     372           13 :     BQS_LOG_INFO("[DgwClient] Begin to query config.");
     373              :     // check dgw client initialized
     374           13 :     if (!initFlag_) {
     375            1 :         BQS_LOG_ERROR("[DgwClient] please check whether datagw client has initialized successfully.");
     376            1 :         return static_cast<int32_t>(BQS_STATUS_NOT_INIT);
     377              :     }
     378              :     // check route num/group num
     379           12 :     auto ret = CheckConfigNum(query, cfgInfo);
     380           12 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     381            3 :         BQS_LOG_ERROR("[DgwClient] calculate and check config num failed. Please check config num!");
     382            3 :         return ret;
     383              :     }
     384              : 
     385              :     // mbuf memory layout: 1. config query / 2.config info / 3.Routes or Endpoints / 4.config result
     386            9 :     std::list<std::pair<uintptr_t, size_t>> dataList;
     387              :     // calculate query length: 1. config query
     388            9 :     const size_t qryLen = sizeof(ConfigQuery);
     389            9 :     (void)dataList.emplace_back(std::make_pair(PtrToValue(&query), sizeof(ConfigQuery)));
     390              :     // here is to consider compatibility between client and server different versions
     391            9 :     std::unique_ptr<Route[]> spareRoutes = nullptr;
     392            9 :     std::unique_ptr<Endpoint[]> spareEndpoints = nullptr;
     393            9 :     if (IsQueueOperationCmd(cfgInfo)) {
     394            6 :         const uint32_t routeNum = cfgInfo.cfg.routesCfg.routeNum;
     395            6 :         spareRoutes.reset(new (std::nothrow) Route[routeNum]);
     396            6 :         if (spareRoutes == nullptr) {
     397            0 :             BQS_LOG_ERROR("[DgwClient] malloc failed on spareRoutes.");
     398            0 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     399              :         }
     400            3 :     } else if (IsGroupOperationCmd(cfgInfo)) {
     401            3 :         const uint32_t endpointNum = cfgInfo.cfg.groupCfg.endpointNum;
     402            3 :         spareEndpoints.reset(new (std::nothrow) Endpoint[endpointNum]);
     403            3 :         if (spareEndpoints == nullptr) {
     404            0 :             BQS_LOG_ERROR("[DgwClient] malloc failed on spareEndpoints.");
     405            0 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     406              :         }
     407              :     } else {
     408            0 :         BQS_LOG_INFO("[DgwClient] config cmd is %d.", static_cast<int32_t>(cfgInfo.cmd));
     409              :     }
     410              :     
     411              :     // calculate config length: 2.config info + 3.Routes or Endpoints
     412            9 :     size_t cfgLen = 0UL;
     413            9 :     ret = CalcConfigInfoLen(cfgInfo, cfgLen, dataList, spareRoutes, spareEndpoints);
     414            9 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     415            0 :         BQS_LOG_ERROR("[DgwClient] check and calculate length of config info failed.");
     416            0 :         return ret;
     417              :     }
     418              :     // calculate result length: 3.config results
     419            9 :     size_t retLen = 0UL;
     420            9 :     ret = CalcResultLen(cfgInfo, retLen);
     421            9 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     422            0 :         BQS_LOG_ERROR("[DgwClient] calculate length of result failed.");
     423            0 :         return ret;
     424              :     }
     425              : 
     426              :     // opereate config to server
     427            9 :     std::vector<int32_t> emptyVec;
     428            9 :     const ConfigParams cfgParams = {
     429              :         .info = nullptr,
     430              :         .query = const_cast<ConfigQuery *>(&query),
     431              :         .cfgInfo = &cfgInfo,
     432              :         .cfgLen = cfgLen,
     433            9 :         .totalLen = qryLen + cfgLen + retLen,
     434            9 :     };
     435            9 :     ret = OperateConfigToServer(QueueSubEventType::QUERY_CONFIG, cfgParams, dataList, emptyVec, timeout);
     436            9 :     BQS_LOG_INFO("[DgwClient] Finish to update config, ret is [%d].", ret);
     437            9 :     return ret;
     438            9 : }
     439              : 
     440           24 : int32_t DgwClient::QueryConfigNum(ConfigQuery &query, const int32_t timeout)
     441              : {
     442           24 :     BQS_LOG_INFO("[DgwClient] Begin to query config number.");
     443              :     // check dgw client initialized
     444           24 :     if (!initFlag_) {
     445            1 :         BQS_LOG_ERROR("[DgwClient] please check whether datagw client has initialized successfully.");
     446            1 :         return static_cast<int32_t>(BQS_STATUS_NOT_INIT);
     447              :     }
     448              : 
     449              :     // mbuf memory layout: 1. config query / 2.config result
     450           23 :     std::list<std::pair<uintptr_t, size_t>> dataList;
     451              :     // calculate query length: 1. config query
     452           23 :     const size_t qryLen = sizeof(ConfigQuery);
     453           23 :     (void)dataList.emplace_back(std::make_pair(PtrToValue(&query), sizeof(ConfigQuery)));
     454              :     // calculate result length: 2.config results
     455           23 :     constexpr size_t retLen = sizeof(CfgRetInfo);
     456              : 
     457              :     // operate config to server
     458           23 :     std::vector<int32_t> emptyVec;
     459              :     ConfigInfo unusedParam;
     460           23 :     const ConfigParams cfgParams = {
     461              :         .info = nullptr,
     462              :         .query = &query,
     463              :         .cfgInfo = &unusedParam,
     464              :         .cfgLen = 0UL,
     465              :         .totalLen = qryLen + retLen,
     466           23 :     };
     467           23 :     const auto ret = OperateConfigToServer(QueueSubEventType::QUERY_CONFIG_NUM, cfgParams, dataList, emptyVec, timeout);
     468           23 :     BQS_LOG_INFO("[DgwClient] Finish to query config number, ret is [%d].", ret);
     469           23 :     return ret;
     470           23 : }
     471              : 
     472           88 : int32_t DgwClient::OperateConfigToServer(const QueueSubEventType subEventId, const ConfigParams &cfgParams,
     473              :                                          std::list<std::pair<uintptr_t, size_t>> &dataList,
     474              :                                          std::vector<int32_t> &cfgRets, const int32_t timeout)
     475              : {
     476           88 :     if (isProxy_) {
     477            2 :         return OperateToServerOnOtherSide(subEventId, cfgParams, dataList, cfgRets, timeout);
     478              :     } else {
     479           86 :         return OperateToServerOnSameSide(subEventId, cfgParams, dataList, cfgRets, timeout);
     480              :     }
     481              : }
     482              : 
     483           91 : static int32_t SetDataAndEnqueueForMbuf(const std::list<std::pair<uintptr_t, size_t>> &dataList,
     484              :                                         Mbuf * const mbuf, const size_t mbufLen, uint32_t deviceId,
     485              :                                         uint32_t piplineQueueId)
     486              : {
     487              :     // check mbuf and mbufLen
     488           91 :     if ((mbuf == nullptr) || (mbufLen == 0UL) || (dataList.empty())) {
     489            1 :         BQS_LOG_ERROR("[DgwClient] mbuf nullptr or mbufLen equal zero or dataList empty:%d.", dataList.empty());
     490            1 :         return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
     491              :     }
     492              : 
     493              :     // get mbuf data addr
     494           90 :     void *mbufData = nullptr;
     495           90 :     auto drvRet = halMbufGetBuffAddr(mbuf, &mbufData);
     496           90 :     if ((drvRet != static_cast<int32_t>(DRV_ERROR_NONE)) || (mbufData == nullptr)) {
     497            1 :         BQS_LOG_ERROR("[DgwClient] Failed to get mbuf data, ret=[%d]", drvRet);
     498            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     499              :     }
     500              : 
     501              :     // copy data to mbuf
     502           89 :     size_t offset = 0UL;
     503          231 :     for (auto &data : dataList) {
     504          143 :         const size_t restMbufLen = mbufLen - offset;
     505          143 :         if (data.second > restMbufLen) {
     506            1 :             BQS_LOG_ERROR("[DgwClient] dataLen[%zu] is invalid. mbufLen is [%zu], offset is [%zu].",
     507              :                 data.second, mbufLen, offset);
     508            1 :             return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
     509              :         }
     510          142 :         const auto cpyRet = memcpy_s(ValueToPtr(PtrToValue(mbufData) + offset), restMbufLen,
     511          142 :                                      ValueToPtr(data.first), data.second);
     512          142 :         if (cpyRet != EOK) {
     513            0 :             BQS_LOG_ERROR("[DgwClient] Memcpy failed, dataSize[%zu], mbufLen[%zu] ret=[%d]",
     514              :                 data.second, restMbufLen, cpyRet);
     515            0 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     516              :         }
     517          142 :         offset += data.second;
     518              :     }
     519              :     // set mbuf len
     520           88 :     drvRet = halMbufSetDataLen(mbuf, mbufLen);
     521           88 :     if (drvRet != static_cast<int32_t>(DRV_ERROR_NONE)) {
     522            1 :         BQS_LOG_ERROR("[DgwClient] Failed to set data len[%zu] for mbuf, ret=[%d]", mbufLen, drvRet);
     523            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     524              :     }
     525              :     // mbuf enqueue
     526           87 :     const auto enqueueRet = halQueueEnQueue(deviceId, piplineQueueId, mbuf);
     527           87 :     if (enqueueRet != DRV_ERROR_NONE) {
     528            1 :         BQS_LOG_ERROR("[DgwClient] Call halQueueEnQueue error, queue id[%u], ret=[%d]", piplineQueueId,
     529              :                       static_cast<int32_t>(enqueueRet));
     530            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     531              :     }
     532           86 :     BQS_LOG_INFO("[DgwClient] Call halQueueEnQueue success, queue id[%u], ret=[%d]", piplineQueueId,
     533              :                  static_cast<int32_t>(enqueueRet));
     534           86 :     return static_cast<int32_t>(BQS_STATUS_OK);
     535              : }
     536              : 
     537           92 : int32_t DgwClient::OperateToServerOnSameSide(const QueueSubEventType subEventId, const ConfigParams &cfgParams,
     538              :                                              std::list<std::pair<uintptr_t, size_t>> &dataList,
     539              :                                              std::vector<int32_t> &cfgRets, const int32_t timeout)
     540              : {
     541              :     // alloc mbuf
     542           92 :     Mbuf *mbuf = nullptr;
     543           92 :     const size_t mbufLen = cfgParams.totalLen;
     544           92 :     auto drvRet = halMbufAlloc(mbufLen, &mbuf);
     545           92 :     if ((drvRet != static_cast<int32_t>(DRV_ERROR_NONE)) || (mbuf == nullptr)) {
     546            1 :         BQS_LOG_ERROR("[DgwClient] failed to alloc mbuf, size[%zu], ret=[%d].", mbufLen, drvRet);
     547            1 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     548              :     }
     549              :     // copy data to mbuf and mbuf enqueue
     550           91 :     Mbuf *dequeMbuf = nullptr;
     551           91 :     int32_t cmdRet = static_cast<int32_t>(BQS_STATUS_OK);
     552              :     {
     553           91 :         const std::unique_lock<std::mutex> eventLock(eventMutex_);
     554           91 :         auto ret = SetDataAndEnqueueForMbuf(dataList, mbuf, mbufLen, deviceId_, piplineQueueId_);
     555           91 :         if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     556              :             // reaching here means mbuf was not enqueued, so we should free
     557            5 :             (void)halMbufFree(mbuf);
     558            5 :             mbuf = nullptr;
     559            5 :             return ret;
     560              :         }
     561              : 
     562           86 :         ret = InformServer(subEventId, cmdRet, timeout);
     563           86 :         if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     564            0 :             return ret;
     565              :         }
     566              : 
     567           86 :         drvRet = halQueueDeQueue(deviceId_, piplineQueueId_, reinterpret_cast<void**>(&dequeMbuf));
     568           86 :         if ((drvRet != DRV_ERROR_NONE) || (dequeMbuf == nullptr)) {
     569            0 :             BQS_LOG_ERROR("halQueueDeQueue from queue[%u] in device[%u] failed, error[%d]", piplineQueueId_,
     570              :                 deviceId_, static_cast<int32_t>(drvRet));
     571            0 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     572              :         }
     573           91 :     }
     574              : 
     575           86 :     void *dequeMbufData = nullptr;
     576           86 :     drvRet = halMbufGetBuffAddr(dequeMbuf, &dequeMbufData);
     577           86 :     if ((drvRet != static_cast<int32_t>(DRV_ERROR_NONE)) || (dequeMbufData == nullptr)) {
     578            0 :         BQS_LOG_ERROR("[DgwClient] Failed to get mbuf data, ret=[%d]", drvRet);
     579            0 :         (void)halMbufFree(dequeMbuf);
     580            0 :         dequeMbuf = nullptr;
     581            0 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     582              :     }
     583              : 
     584           86 :     const uintptr_t dequeMbufDataAddr = PtrToValue(dequeMbufData);
     585           86 :     ExtractRetCode(subEventId, cfgParams, dequeMbufDataAddr, cfgRets, cmdRet);
     586              : 
     587           86 :     (void)halMbufFree(dequeMbuf);
     588           86 :     dequeMbuf = nullptr;
     589           86 :     return cmdRet;
     590              : }
     591              : 
     592            6 : int32_t DgwClient::OperateToServerOnOtherSide(const QueueSubEventType subEventId, const ConfigParams &cfgParams,
     593              :                                               std::list<std::pair<uintptr_t, size_t>> &dataList,
     594              :                                               std::vector<int32_t> &cfgRets, const int32_t timeout)
     595              : {
     596              :     // alloc memory
     597            6 :     const size_t mbufLen = cfgParams.totalLen;
     598            6 :     std::unique_ptr<char_t[]> body(new (std::nothrow) char_t[mbufLen], std::default_delete<char_t[]>());
     599            6 :     if (body == nullptr) {
     600            0 :         BQS_LOG_ERROR("[DgwClient] failed to alloc memory for data, size[%zu].", mbufLen);
     601            0 :         return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     602              :     }
     603              :     // copy data to mbuf
     604            6 :     size_t offset = 0UL;
     605           13 :     for (auto &data : dataList) {
     606            8 :         const size_t restMbufLen = mbufLen - offset;
     607            8 :         if (data.second > restMbufLen) {
     608            0 :             BQS_LOG_ERROR("[DgwClient] dataLen[%zu] is invalid. mbufLen is [%zu], offset is [%zu].",
     609              :                 data.second, mbufLen, offset);
     610            1 :             return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
     611              :         }
     612            8 :         const auto cpyRet = memcpy_s(ValueToPtr(PtrToValue(body.get()) + offset), restMbufLen,
     613            8 :                                      ValueToPtr(data.first), data.second);
     614            8 :         if (cpyRet != EOK) {
     615            1 :             BQS_LOG_ERROR("[DgwClient] Memcpy failed, dataSize[%zu], mbufLen[%zu] ret=[%d]",
     616              :                 data.second, restMbufLen, cpyRet);
     617            1 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     618              :         }
     619            7 :         offset += data.second;
     620              :     }
     621            5 :     const size_t totalLen = sizeof(struct buff_iovec) + sizeof(struct iovec_info);
     622            5 :     std::unique_ptr<char_t[]> vecUniquePtr(new (std::nothrow) char_t[totalLen], std::default_delete<char_t[]>());
     623            5 :     if (vecUniquePtr == nullptr) {
     624            0 :         BQS_LOG_ERROR("[DgwClient] failed to alloc memory for buffIovec, size[%zu].", totalLen);
     625            0 :         return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     626              :     }
     627            5 :     buff_iovec * const buffIovec = reinterpret_cast<buff_iovec *>(vecUniquePtr.get());
     628            5 :     buffIovec->context_base = nullptr;
     629            5 :     buffIovec->context_len = 0U;
     630            5 :     buffIovec->count = 1U;
     631            5 :     buffIovec->ptr[0U].iovec_base = body.get();
     632            5 :     buffIovec->ptr[0U].len = mbufLen;
     633              : 
     634            5 :     int32_t cmdRet = static_cast<int32_t>(BQS_STATUS_OK);
     635              :     {
     636            5 :         const std::unique_lock<std::mutex> eventLock(eventMutex_);
     637            5 :         auto drvRet = halQueueEnQueueBuff(deviceId_, piplineQueueId_, buffIovec, timeout);
     638            5 :         if (drvRet != DRV_ERROR_NONE) {
     639            1 :             BQS_LOG_ERROR("halQueueEnQueueBuff to queue[%u] in device[%u] failed, error[%d]",
     640              :                 piplineQueueId_, deviceId_, static_cast<int32_t>(drvRet));
     641            1 :             return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     642              :         }
     643              : 
     644            4 :         const auto ret = InformServer(subEventId, cmdRet, timeout);
     645            4 :         if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     646            1 :             return ret;
     647              :         }
     648              : 
     649            3 :         uint64_t respLen = 0U;
     650            3 :         drvRet = halQueuePeek(deviceId_, piplineQueueId_, &respLen, timeout);
     651            3 :         if ((drvRet != DRV_ERROR_NONE) || (respLen == 0U)) {
     652            2 :             BQS_LOG_ERROR("halQueuePeek from queue[%u] in device[%u] failed, ret[%d], respLen[%lu]",
     653              :                 piplineQueueId_, deviceId_, static_cast<int32_t>(drvRet), respLen);
     654            2 :             return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     655              :         }
     656              : 
     657            1 :         std::unique_ptr<char_t[]> respBody(new (std::nothrow) char_t[respLen], std::default_delete<char_t[]>());
     658            1 :         if (respBody == nullptr) {
     659            0 :             BQS_LOG_ERROR("[DgwClient] failed to alloc memory for response data, size[%lu].", respLen);
     660            0 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     661              :         }
     662            1 :         buffIovec->context_base = nullptr;
     663            1 :         buffIovec->context_len = 0U;
     664            1 :         buffIovec->count = 1U;
     665            1 :         buffIovec->ptr[0U].iovec_base = respBody.get();
     666            1 :         buffIovec->ptr[0U].len = respLen;
     667            1 :         drvRet = halQueueDeQueueBuff(deviceId_, piplineQueueId_, buffIovec, timeout);
     668            1 :         if (drvRet != DRV_ERROR_NONE) {
     669            0 :             BQS_LOG_ERROR("halQueueDeQueueBuff from queue[%u] in device[%u] failed, ret[%d]",
     670              :                 piplineQueueId_, deviceId_, static_cast<int32_t>(drvRet));
     671            0 :             return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     672              :         }
     673              : 
     674            1 :         const uintptr_t dequeMbufDataAddr = PtrToValue(respBody.get());
     675            1 :         ExtractRetCode(subEventId, cfgParams, dequeMbufDataAddr, cfgRets, cmdRet);
     676            5 :     }
     677            1 :     return cmdRet;
     678            6 : }
     679              : 
     680           87 : void DgwClient::ExtractRetCode(const QueueSubEventType subEventId, const ConfigParams &cfgParams,
     681              :     const uintptr_t respPtr, std::vector<int32_t> &cfgRets, int32_t &cmdRet) const
     682              : {
     683              :     // create or destroy handle
     684           87 :     if ((subEventId == QueueSubEventType::DGW_CREATE_HCOM_HANDLE) ||
     685              :         (subEventId == QueueSubEventType::DGW_DESTORY_HCOM_HANDLE)) {
     686           16 :         if (cfgParams.info == nullptr) {
     687            0 :             cmdRet = static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     688              :         } else {
     689           16 :             (void)GetOperateHcomHandleRet(subEventId, *cfgParams.info, respPtr, cfgParams.cfgLen, cmdRet);
     690              :         }
     691           71 :     } else if (subEventId == QueueSubEventType::QUERY_CONFIG_NUM) { // qry config num get result outside
     692           23 :         if (cfgParams.query == nullptr) {
     693            0 :             cmdRet = static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     694              :         } else {
     695           23 :             (void)GetQryConfigNumRet(*cfgParams.query, respPtr, cmdRet);
     696              :         }
     697              :     } else {
     698           48 :         if (cfgParams.cfgInfo == nullptr) {
     699            0 :             cmdRet = static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     700              :         } else {
     701           48 :             (void)GetOperateConfigRet(*cfgParams.cfgInfo, respPtr, cfgParams.cfgLen, cfgRets, cmdRet);
     702              :         }
     703              :     }
     704           87 : }
     705              : 
     706           88 : int32_t DgwClient::InformServer(const QueueSubEventType subEventId, int32_t &cmdRet, const int32_t timeout)
     707              : {
     708              :     // send event to datagw server
     709           88 :     event_sync_msg syncMsg = {};
     710           88 :     QsProcMsgRsp procMsgRsp = {};
     711           88 :     const auto ret = SendEventToQsSync(&syncMsg, sizeof(event_sync_msg), subEventId, procMsgRsp, timeout);
     712           88 :     if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
     713            0 :         return ret;
     714              :     }
     715           88 :     cmdRet = procMsgRsp.retCode;
     716           88 :     return static_cast<int32_t>(BQS_STATUS_OK);
     717              : }
     718              : 
     719          114 : int32_t DgwClient::SendEventToQsSync(const void *const msg, const size_t msgLen,
     720              :                                      const QueueSubEventType subEventId,
     721              :                                      QsProcMsgRsp &qsProcMsgRsp, const int32_t timeout) const
     722              : {
     723          114 :     BQS_LOG_INFO("[DgwClient]SendEventToQsSync QsProcMsgRsp begin, timeout: %ds, deviceId: %u", timeout, deviceId_);
     724              :     event_reply drvAck;
     725          114 :     drvAck.buf = PtrToPtr<QsProcMsgRsp, char>(&qsProcMsgRsp);
     726          114 :     drvAck.buf_len = sizeof(QsProcMsgRsp);
     727              : 
     728          114 :     event_summary drvEventInfo = {};
     729          114 :     if (isProxy_) {
     730            2 :         drvEventInfo.dst_engine = static_cast<uint32_t>(CCPU_DEVICE);
     731              :     } else {
     732              :         // FlowGW host deployer client -- server used
     733          112 :         drvEventInfo.dst_engine = static_cast<uint32_t>(CCPU_LOCAL);
     734              :     }
     735          114 :     drvEventInfo.policy = ONLY;
     736          114 :     drvEventInfo.pid = qsPid_;
     737          114 :     drvEventInfo.grp_id = static_cast<uint32_t>(BIND_QUEUE_GROUP_ID);
     738          114 :     drvEventInfo.event_id = EVENT_QS_MSG;
     739          114 :     drvEventInfo.subevent_id = static_cast<uint32_t>(subEventId);
     740          114 :     drvEventInfo.msg_len = static_cast<uint32_t>(msgLen);
     741          114 :     drvEventInfo.msg = const_cast<char *>(static_cast<const char *>(msg));
     742              : 
     743          114 :     const int32_t timeOutMs = timeout > 0 ? timeout * 1000 : timeout;
     744          114 :     const auto drvRet = halEschedSubmitEventSync(deviceId_, &drvEventInfo, timeOutMs, &drvAck);
     745          114 :     if (drvRet != DRV_ERROR_NONE) {
     746            4 :         BQS_LOG_WARN("[DgwClient] Failed to submit event to qs, ret=[%d].", static_cast<int32_t>(drvRet));
     747            4 :         if (drvRet == DRV_ERROR_SCHED_WAIT_TIMEOUT) {
     748            2 :             return static_cast<int32_t>(BQS_STATUS_TIMEOUT);
     749              :         }
     750            2 :         return static_cast<int32_t>(BQS_STATUS_DRIVER_ERROR);
     751              :     }
     752          110 :     if (static_cast<size_t>(drvAck.reply_len) != sizeof(QsProcMsgRsp)) {
     753            0 :         BQS_LOG_ERROR("[DgwClient] QsProcMsgRsp event_reply event message invalid, bufLen[%u], subEventId[%u]",
     754              :             drvAck.reply_len, static_cast<uint32_t>(subEventId));
     755            0 :         return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     756              :     }
     757          110 :     return static_cast<int32_t>(BQS_STATUS_OK);
     758              : }
     759              : 
     760           24 : int32_t DgwClient::GetQryConfigNumRet(ConfigQuery &query, const uintptr_t mbufData, int32_t &cmdRet) const
     761              : {
     762           24 :     if (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) {
     763              :         // return API operate result, not query config num ret
     764            1 :         return static_cast<int32_t>(BQS_STATUS_OK);
     765              :     }
     766              : 
     767           23 :     const uintptr_t retAddr = mbufData + sizeof(ConfigQuery);
     768           23 :     cmdRet = (PtrToPtr<void, CfgRetInfo>(ValueToPtr(retAddr)))->retCode;
     769              : 
     770           23 :     const ConfigQuery *cfgQry = PtrToPtr<void, ConfigQuery>(ValueToPtr(mbufData));
     771           23 :     if (query.mode == QueryMode::DGW_QUERY_MODE_GROUP) {
     772            8 :         query.qry.groupQry.endpointNum = cfgQry->qry.groupQry.endpointNum;
     773              :     } else {
     774           15 :         query.qry.routeQry.routeNum = cfgQry->qry.routeQry.routeNum;
     775              :     }
     776           23 :     return static_cast<int32_t>(BQS_STATUS_OK);
     777              : }
     778              : 
     779           49 : int32_t DgwClient::GetOperateConfigRet(ConfigInfo &cfgInfo, const uintptr_t mbufData, const size_t cfgLen,
     780              :                                        std::vector<int32_t> &cfgRets, int32_t &cmdRet) const
     781              : {
     782           49 :     int32_t ret = static_cast<int32_t>(BQS_STATUS_OK);
     783           49 :     switch (cfgInfo.cmd) {
     784           13 :         case ConfigCmd::DGW_CFG_CMD_BIND_ROUTE:
     785              :         case ConfigCmd::DGW_CFG_CMD_UNBIND_ROUTE: {
     786           13 :             ret = GetUpdateRouteRet(cfgInfo, mbufData, cfgLen, cfgRets, cmdRet);
     787           13 :             break;
     788              :         }
     789           18 :         case ConfigCmd::DGW_CFG_CMD_ADD_GROUP:
     790              :         case ConfigCmd::DGW_CFG_CMD_DEL_GROUP: {
     791           18 :             ret = GetUpdateGroupRet(cfgInfo, mbufData, cfgLen, cfgRets, cmdRet);
     792           18 :             break;
     793              :         }
     794            3 :         case ConfigCmd::DGW_CFG_CMD_QRY_GROUP: {
     795            3 :             ret = GetQryGroupRet(cfgInfo, mbufData, cfgLen, cfgRets, cmdRet);
     796            3 :             break;
     797              :         }
     798            6 :         case ConfigCmd::DGW_CFG_CMD_QRY_ROUTE: {
     799            6 :             ret = GetQryRouteRet(cfgInfo, mbufData, cfgLen, cfgRets, cmdRet);
     800            6 :             break;
     801              :         }
     802            8 :         case ConfigCmd::DGW_CFG_CMD_UPDATE_PROFILING:
     803              :         case ConfigCmd::DGW_CFG_CMD_SET_HCCL_PROTOCOL:
     804              :         case ConfigCmd::DGW_CFG_CMD_INIT_DYNAMIC_SCHEDULE:
     805              :         case ConfigCmd::DGW_CFG_CMD_STOP_SCHEDULE:
     806              :         case ConfigCmd::DGW_CFG_CMD_CLEAR_AND_RESTART_SCHEDULE: {
     807            8 :             const uintptr_t retAddr = mbufData + cfgLen;
     808           14 :             cmdRet = (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) ?
     809            6 :                     cmdRet : PtrToPtr<void, CfgRetInfo>(ValueToPtr(retAddr))->retCode;
     810            8 :             cfgRets.push_back(cmdRet);
     811            8 :             break;
     812              :         }
     813            1 :         default: {
     814            1 :             BQS_LOG_WARN("[DgwClient] cmd[%d] is invalid.", static_cast<int32_t>(cfgInfo.cmd));
     815            1 :             cmdRet = static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
     816            1 :             ret = static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
     817            1 :             break;
     818              :         }
     819              :     }
     820           49 :     return ret;
     821              : }
     822              : 
     823           17 : int32_t DgwClient::GetOperateHcomHandleRet(const QueueSubEventType subEventId, HcomHandleInfo &info,
     824              :                                            const uintptr_t mbufData, const size_t cfgLen, int32_t &cmdRet) const
     825              : {
     826           17 :     constexpr int32_t ret = static_cast<int32_t>(BQS_STATUS_OK);
     827           17 :     const uintptr_t retAddr = mbufData + cfgLen;
     828           33 :     cmdRet = (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) ?
     829           16 :             cmdRet : PtrToPtr<void, CfgRetInfo>(ValueToPtr(retAddr))->retCode;
     830           17 :     if (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) {
     831            2 :         return static_cast<int32_t>(BQS_STATUS_OK);
     832              :     }
     833              : 
     834           15 :     if (subEventId == QueueSubEventType::DGW_CREATE_HCOM_HANDLE) {
     835            8 :         info.hcomHandle = PtrToPtr<void, HcomHandleInfo>(ValueToPtr(mbufData))->hcomHandle;
     836              :     }
     837           15 :     return ret;
     838              : }
     839              : 
     840           50 : int32_t DgwClient::CalcResultLen(const ConfigInfo &cfgInfo, size_t &retLen) const
     841              : {
     842           50 :     retLen = 0UL;
     843           50 :     switch (cfgInfo.cmd) {
     844           13 :         case ConfigCmd::DGW_CFG_CMD_BIND_ROUTE:
     845              :         case ConfigCmd::DGW_CFG_CMD_UNBIND_ROUTE: {
     846           13 :             retLen += cfgInfo.cfg.routesCfg.routeNum * sizeof(CfgRetInfo);
     847           13 :             break;
     848              :         }
     849           36 :         case ConfigCmd::DGW_CFG_CMD_QRY_ROUTE:
     850              :         case ConfigCmd::DGW_CFG_CMD_QRY_GROUP:
     851              :         case ConfigCmd::DGW_CFG_CMD_ADD_GROUP:
     852              :         case ConfigCmd::DGW_CFG_CMD_DEL_GROUP:
     853              :         case ConfigCmd::DGW_CFG_CMD_UPDATE_PROFILING:
     854              :         case ConfigCmd::DGW_CFG_CMD_SET_HCCL_PROTOCOL:
     855              :         case ConfigCmd::DGW_CFG_CMD_INIT_DYNAMIC_SCHEDULE:
     856              :         case ConfigCmd::DGW_CFG_CMD_STOP_SCHEDULE:
     857              :         case ConfigCmd::DGW_CFG_CMD_CLEAR_AND_RESTART_SCHEDULE: {
     858           36 :             retLen += sizeof(CfgRetInfo);
     859           36 :             break;
     860              :         }
     861            1 :         default: {
     862            1 :             break;
     863              :         }
     864              :     }
     865           50 :     return static_cast<int32_t>(BQS_STATUS_OK);
     866              : }
     867              : 
     868              : // Create a handler for each EndpointType
     869            8 : static uint32_t HandleMemQueue(Endpoint &dstEndPoint, const Endpoint &srcEndPoint)
     870              : {
     871            8 :     dstEndPoint.type = bqs::EndpointType::QUEUE;
     872            8 :     dstEndPoint.attr.queueAttr.queueId = srcEndPoint.attr.memQueueAttr.queueId;
     873            8 :     return static_cast<int32_t>(BQS_STATUS_OK);
     874              : }
     875              : 
     876            1 : static uint32_t HandleGroup(Endpoint &dstEndPoint, const Endpoint &srcEndPoint)
     877              : {
     878            1 :     const size_t groupAttrSize = sizeof(srcEndPoint.attr.groupAttr);
     879            2 :     const auto cpyRet = memcpy_s(
     880            1 :         (void *)(&dstEndPoint.attr.groupAttr), groupAttrSize, (void *)(&srcEndPoint.attr.groupAttr), groupAttrSize);
     881            1 :     if (cpyRet != EOK) {
     882            0 :         BQS_LOG_ERROR("[HandleGroup] Memcpy failed, cpyLen[%zu], ret=[%d]", groupAttrSize, cpyRet);
     883            0 :         return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     884              :     }
     885            1 :     return static_cast<int32_t>(BQS_STATUS_OK);
     886              : }
     887              : 
     888            1 : static uint32_t HandleCommChannel(Endpoint &dstEndPoint, const Endpoint &srcEndPoint)
     889              : {
     890            1 :     const size_t channelAttrSize = sizeof(srcEndPoint.attr.channelAttr);
     891            2 :     const auto cpyRet = memcpy_s((void *)(&dstEndPoint.attr.channelAttr), channelAttrSize,
     892            1 :         (void *)(&srcEndPoint.attr.channelAttr), channelAttrSize);
     893            1 :     if (cpyRet != EOK) {
     894            0 :         BQS_LOG_ERROR("[HandleCommChannel] Memcpy failed, cpyLen[%zu], ret=[%d]", channelAttrSize, cpyRet);
     895            0 :         return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     896              :     }
     897            1 :     return static_cast<int32_t>(BQS_STATUS_OK);
     898              : }
     899              : 
     900              : // Define the function pointer type
     901              : using EndpointHandler = uint32_t (*)(Endpoint&, const Endpoint&);
     902              : 
     903              : // Creating Table Mappings
     904              : std::map<bqs::EndpointType, EndpointHandler> g_endpointHandlers = {
     905              :     {bqs::EndpointType::MEM_QUEUE, &HandleMemQueue},
     906              :     {bqs::EndpointType::GROUP, &HandleGroup},
     907              :     {bqs::EndpointType::COMM_CHANNEL, &HandleCommChannel},
     908              : };
     909              : 
     910           11 : static uint32_t EndpointTransformMemQ2Q(Endpoint &dstEndPoint, Endpoint &srcEndPoint)
     911              : {
     912           11 :     if (srcEndPoint.type == bqs::EndpointType::MEM_QUEUE &&
     913            9 :         srcEndPoint.attr.memQueueAttr.queueType == bqs::CLIENT_Q) {
     914            1 :         BQS_LOG_ERROR("[EndpointTransformMemQ2Q] CLIENT_Q interception");
     915            1 :         return static_cast<int32_t>(BQS_STATUS_ENDPOINT_MEM_TYPE_NOT_SUPPORT);
     916              :     }
     917           10 :     dstEndPoint.type = srcEndPoint.type;
     918           10 :     dstEndPoint.status = srcEndPoint.status;
     919           10 :     dstEndPoint.peerNum = srcEndPoint.peerNum;
     920           10 :     dstEndPoint.localId = srcEndPoint.localId;
     921           10 :     dstEndPoint.globalId = srcEndPoint.globalId;
     922           10 :     dstEndPoint.modelId = srcEndPoint.modelId;
     923              :     // localQ need transform
     924           10 :     auto it = g_endpointHandlers.find(srcEndPoint.type);
     925           10 :     if (it != g_endpointHandlers.end()) {
     926           10 :         return it->second(dstEndPoint, srcEndPoint);
     927              :     } else {
     928            0 :         BQS_LOG_ERROR("[EndpointTransformMemQ2Q] should not reach here");
     929            0 :         return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
     930              :     }
     931              : }
     932              : 
     933            1 : static int32_t EndpointTransformQ2MemQ(std::unique_ptr<Endpoint[]> &endpoints, uint32_t endpointNum)
     934              : {
     935            3 :     for (uint32_t rdx = 0; rdx < endpointNum; rdx++) {
     936            2 :         if (endpoints[rdx].type == bqs::EndpointType::QUEUE) {
     937            1 :             BQS_LOG_INFO("[EndpointTransformQ2MemQ] transfer q to memq");
     938            1 :             endpoints[rdx].type = bqs::EndpointType::MEM_QUEUE;
     939            1 :             endpoints[rdx].attr.memQueueAttr.queueId = endpoints[rdx].attr.queueAttr.queueId;
     940            1 :             endpoints[rdx].attr.memQueueAttr.queueType = 0U;
     941              :         }
     942              :     }
     943            1 :     return static_cast<int32_t>(BQS_STATUS_OK);
     944              : }
     945              : 
     946            2 : static int32_t GroupQueueTransform(Endpoint *endpoints, uint32_t endpointNum, std::unique_ptr<Endpoint[]> &spareEndpoints)
     947              : {
     948            2 :     bool isNeedTransform = false;
     949            6 :     for (uint32_t rdx = 0; rdx < endpointNum; rdx++) {
     950            4 :         if (endpoints[rdx].type == bqs::EndpointType::MEM_QUEUE) {
     951            3 :             isNeedTransform = true;
     952              :         }
     953              :     }
     954              : 
     955            2 :     if (!isNeedTransform) {
     956            0 :         BQS_LOG_INFO("[GroupQueueTransform] group no mem queue do not to transfer");
     957            0 :         return static_cast<int32_t>(BQS_STATUS_NO_NEED_MEM_QUEUE_TRANSFORM);
     958              :     }
     959              : 
     960            6 :     for (uint32_t rdx = 0; rdx < endpointNum; rdx++) {
     961            4 :         const uint32_t ret = EndpointTransformMemQ2Q(spareEndpoints[rdx], endpoints[rdx]);
     962            4 :         if (ret != static_cast<uint32_t>(BQS_STATUS_OK)) {
     963            0 :             BQS_LOG_ERROR("[GroupQueueTransform] transfer error ret=%u", ret);
     964            0 :             return static_cast<int32_t>(ret);
     965              :         }
     966              :     }
     967            2 :     return static_cast<int32_t>(BQS_STATUS_OK);
     968              : }
     969              : 
     970            5 : static int32_t MemQueueAttr2queueAttrTransform(Route *routes, uint32_t routeNum, std::unique_ptr<Route[]> &spareRoutes)
     971              : {
     972            5 :     bool isNeedTransform = false;
     973           10 :     for (uint32_t rdx = 0; rdx < routeNum; rdx++) {
     974            5 :         if (routes[rdx].src.type == bqs::EndpointType::MEM_QUEUE ||
     975            1 :             routes[rdx].dst.type == bqs::EndpointType::MEM_QUEUE) {
     976            4 :             isNeedTransform = true;
     977              :         }
     978              :     }
     979              : 
     980            5 :     if (!isNeedTransform) {
     981            1 :         BQS_LOG_INFO("[MemQueueAttr2queueAttrTransform] no mem queue do not to transfer");
     982            1 :         return static_cast<int32_t>(BQS_STATUS_NO_NEED_MEM_QUEUE_TRANSFORM);
     983              :     }
     984              : 
     985            7 :     for (uint32_t rdx = 0; rdx < routeNum; rdx++) {
     986            4 :         spareRoutes[rdx].status = routes[rdx].status;
     987              :         // src copy
     988            4 :         uint32_t ret = EndpointTransformMemQ2Q(spareRoutes[rdx].src, routes[rdx].src);
     989            4 :         if (ret != static_cast<uint32_t>(BQS_STATUS_OK)) {
     990            1 :             BQS_LOG_ERROR("[MemQueueAttr2queueAttrTransform] transfer error ret=%u", ret);
     991            1 :             return static_cast<int32_t>(ret);
     992              :         }
     993              : 
     994              :         // dst copy
     995            3 :         ret = EndpointTransformMemQ2Q(spareRoutes[rdx].dst, routes[rdx].dst);
     996            3 :         if (ret != static_cast<uint32_t>(BQS_STATUS_OK)) {
     997            0 :             BQS_LOG_ERROR("[MemQueueAttr2queueAttrTransform] transfer error ret=%u", ret);
     998            0 :             return static_cast<int32_t>(ret);
     999              :         }
    1000              :     }
    1001            3 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1002              : }
    1003              : 
    1004            1 : int32_t DgwClient::ChangeDynamicScheduleDeviceId(const ConfigInfo &cfgInfo)
    1005              : {
    1006            1 :     BQS_LOG_INFO("[DgwClient] begin to process dynamic schedule device id.");
    1007            1 :     if (cfgInfo.cfg.dynamicSchedCfgV2->requestQ.deviceType == 0) {
    1008            1 :         uint32_t logicDeviceId = cfgInfo.cfg.dynamicSchedCfgV2->requestQ.deviceId;
    1009            1 :         const auto cRet = ChangeUserDeviceIdToLogicDeviceId(cfgInfo.cfg.dynamicSchedCfgV2->requestQ.deviceId, logicDeviceId);
    1010            1 :         if (cRet != static_cast<int32_t>(BQS_STATUS_OK)) {
    1011            0 :             BQS_LOG_ERROR("[DgwClient] ChangeUserDeviceIdToLogicDeviceId failed ret [%d]", cRet);
    1012            0 :             return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1013              :         }
    1014            1 :         cfgInfo.cfg.dynamicSchedCfgV2->requestQ.deviceId = logicDeviceId;
    1015              :     }
    1016            1 :     if (cfgInfo.cfg.dynamicSchedCfgV2->responseQ.deviceType == 0) {
    1017            1 :         uint32_t logicDeviceId = cfgInfo.cfg.dynamicSchedCfgV2->responseQ.deviceId;
    1018            1 :         const auto cRet = ChangeUserDeviceIdToLogicDeviceId(cfgInfo.cfg.dynamicSchedCfgV2->responseQ.deviceId, logicDeviceId);
    1019            1 :         if (cRet != static_cast<int32_t>(BQS_STATUS_OK)) {
    1020            0 :             BQS_LOG_ERROR("[DgwClient] ChangeUserDeviceIdToLogicDeviceId failed ret [%d]", cRet);
    1021            0 :             return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1022              :         }
    1023            1 :         cfgInfo.cfg.dynamicSchedCfgV2->responseQ.deviceId = logicDeviceId;
    1024              :     }
    1025            1 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1026              : }
    1027              : 
    1028          122 : int32_t DgwClient::ProcessEndpointDeviceId(Endpoint &endpoint) const
    1029              : {
    1030          122 :     BQS_LOG_INFO("[DgwClient] begin to process endpoint deviceId %u.", endpoint.resId);
    1031          122 :     if (isProxy_ && QSFeatureCtrl::IsSupportSetVisibleDevices(g_chipType)) {
    1032            2 :         const bool isHostQueue = ((endpoint.resId >> RESOURCE_ID_HOST_DEVICE_BIT_NUM) & 1U) ? true : false;
    1033            2 :         if (!isHostQueue) {
    1034            2 :             const uint32_t frontPart = endpoint.resId & ROUCE_ID_FRONT_PART_DATA_MASK;
    1035            2 :             const uint32_t rearPart = endpoint.resId & ROUCE_ID_DEVICE_ID_DATA_MASK;
    1036            2 :             uint32_t tmpRearPart = rearPart;
    1037            2 :             const auto cRet = ChangeUserDeviceIdToLogicDeviceId(rearPart, tmpRearPart);
    1038            2 :             if (cRet != static_cast<int32_t>(BQS_STATUS_OK)) {
    1039            1 :                 BQS_LOG_ERROR("[DgwClient] ChangeUserDeviceIdToLogicDeviceId failed ret [%d]", cRet);
    1040            1 :                 return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1041              :             }
    1042            1 :             endpoint.resId = static_cast<uint16_t>(frontPart) | static_cast<uint16_t>(tmpRearPart);
    1043              :         }
    1044              :     }
    1045          121 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1046              : }
    1047              : 
    1048           63 : int32_t DgwClient::CalcConfigInfoLen(const ConfigInfo &cfgInfo, size_t &cfgLen,
    1049              :                                      std::list<std::pair<uintptr_t, size_t>> &dataList,
    1050              :                                      std::unique_ptr<Route[]> &spareRoutes,
    1051              :                                      std::unique_ptr<Endpoint[]> &spareEndpoints) const
    1052              : {
    1053           63 :     switch (cfgInfo.cmd) {
    1054           27 :         case ConfigCmd::DGW_CFG_CMD_BIND_ROUTE:
    1055              :         case ConfigCmd::DGW_CFG_CMD_UNBIND_ROUTE:
    1056              :         case ConfigCmd::DGW_CFG_CMD_QRY_ROUTE: {
    1057           27 :             Route *routes = cfgInfo.cfg.routesCfg.routes;
    1058           27 :             if (routes == nullptr) {
    1059            1 :                 BQS_LOG_ERROR("routes is nullptr.");
    1060            1 :                 return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1061              :             }
    1062           26 :             const uint32_t routeNum = cfgInfo.cfg.routesCfg.routeNum;
    1063           26 :             if ((routeNum == 0U) || (routeNum > MAX_ROUTES_NUM)) {
    1064            1 :                 BQS_LOG_ERROR("route num[%u] is invalid, max allowed value is [%u].", routeNum, MAX_ROUTES_NUM);
    1065            1 :                 return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1066              :             }
    1067              : 
    1068           68 :             for (uint32_t rdx = 0; rdx < routeNum; rdx++) {
    1069           44 :                 const auto pRet = ProcessEndpointDeviceId(routes[rdx].src) + ProcessEndpointDeviceId(routes[rdx].dst);
    1070           44 :                 if (pRet != static_cast<int32_t>(BQS_STATUS_OK)) {
    1071            1 :                     return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1072              :                 }
    1073              :             }
    1074              : 
    1075           24 :             cfgLen += (sizeof(cfgInfo) + static_cast<size_t>(routeNum) * sizeof(Route));
    1076           24 :             (void)dataList.emplace_back(std::make_pair(PtrToValue(&cfgInfo), sizeof(ConfigInfo)));
    1077           24 :             if (!isServerOldVersion_) {
    1078           19 :                 (void)dataList.emplace_back(std::make_pair(PtrToValue(routes), routeNum * sizeof(Route)));
    1079              :             } else {
    1080            5 :                 BQS_LOG_INFO("[CalcConfigInfoLen] old version try to transfer mem queue");
    1081            5 :                 const auto cpyRet = memcpy_s(static_cast<void *>(spareRoutes.get()), routeNum * sizeof(Route),
    1082            5 :                                              routes, routeNum * sizeof(Route));
    1083            5 :                 if (cpyRet != EOK) {
    1084            0 :                     BQS_LOG_ERROR("[CalcConfigInfoLen] Memcpy failed, cpyLen[%zu], ret=[%d]",
    1085              :                         routeNum * sizeof(Route), cpyRet);
    1086            0 :                     return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1087              :                 }
    1088            5 :                 const int32_t ret = MemQueueAttr2queueAttrTransform(routes, routeNum, spareRoutes);
    1089            5 :                 if (ret != static_cast<int32_t>(BQS_STATUS_OK) &&
    1090              :                     ret != static_cast<int32_t>(BQS_STATUS_NO_NEED_MEM_QUEUE_TRANSFORM)) {
    1091            1 :                     BQS_LOG_ERROR("[CalcConfigInfoLen] ret is not okay or routes client is nullptr");
    1092            1 :                     return ret;
    1093              :                 }
    1094            4 :                 if (ret == static_cast<int32_t>(BQS_STATUS_NO_NEED_MEM_QUEUE_TRANSFORM)) {
    1095            1 :                     (void)dataList.emplace_back(std::make_pair(PtrToValue(routes), routeNum * sizeof(Route)));
    1096              :                 } else {
    1097            3 :                     (void)dataList.emplace_back(std::make_pair(PtrToValue(spareRoutes.get()), routeNum * sizeof(Route)));
    1098              :                 }
    1099              :             }
    1100           23 :             break;
    1101              :         }
    1102           18 :         case ConfigCmd::DGW_CFG_CMD_ADD_GROUP:
    1103              :         case ConfigCmd::DGW_CFG_CMD_QRY_GROUP: {
    1104           18 :             Endpoint *endpoints = cfgInfo.cfg.groupCfg.endpoints;
    1105           18 :             if (endpoints == nullptr) {
    1106            1 :                 BQS_LOG_ERROR("endpoints is nullptr.");
    1107            3 :                 return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1108              :             }
    1109              :             
    1110           51 :             for (uint32_t rdx = 0; rdx < cfgInfo.cfg.groupCfg.endpointNum; rdx++) {
    1111           35 :                 const auto pRet = ProcessEndpointDeviceId(endpoints[rdx]);
    1112           35 :                 if (pRet != static_cast<int32_t>(BQS_STATUS_OK)) {
    1113            1 :                     return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1114              :                 }
    1115              :             }
    1116              : 
    1117           16 :             const uint32_t endpointNum = cfgInfo.cfg.groupCfg.endpointNum;
    1118           16 :             if ((endpointNum == 0U) || (endpointNum > MAX_ENDPOINTS_NUM_IN_SINGLE_GROUP)) {
    1119            1 :                 BQS_LOG_ERROR("route num[%u] is invalid.", endpointNum);
    1120            1 :                 return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1121              :             }
    1122           15 :             const size_t endpointsLen = endpointNum * sizeof(Endpoint);
    1123           15 :             cfgLen += (sizeof(cfgInfo) + endpointsLen);
    1124           15 :             (void)dataList.emplace_back(std::make_pair(PtrToValue(&cfgInfo), sizeof(ConfigInfo)));
    1125           15 :             if (!isServerOldVersion_) {
    1126           13 :                 (void)dataList.emplace_back(std::make_pair(PtrToValue(endpoints), endpointsLen));
    1127              :             } else {
    1128            2 :                 BQS_LOG_INFO("[CalcConfigInfoLen] old version group try to transfer mem queue");
    1129            2 :                 const auto cpyRet = memcpy_s(static_cast<void *>(spareEndpoints.get()), endpointNum * sizeof(Endpoint),
    1130            2 :                                              endpoints, endpointNum * sizeof(Endpoint));
    1131            2 :                 if (cpyRet != EOK) {
    1132            0 :                     BQS_LOG_ERROR("[CalcConfigInfoLen] Memcpy failed, cpyLen[%zu], ret=[%d]",
    1133              :                         endpointsLen, cpyRet);
    1134            0 :                     return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1135              :                 }
    1136            2 :                 const int32_t ret = GroupQueueTransform(endpoints, endpointNum, spareEndpoints);
    1137            2 :                 if (ret != static_cast<int32_t>(BQS_STATUS_OK) &&
    1138              :                     ret != static_cast<int32_t>(BQS_STATUS_NO_NEED_MEM_QUEUE_TRANSFORM)) {
    1139            0 :                     BQS_LOG_ERROR("[CalcConfigInfoLen] ret is not okay or routes client is nullptr");
    1140            0 :                     return ret;
    1141              :                 }
    1142            2 :                 if (ret == static_cast<int32_t>(BQS_STATUS_NO_NEED_MEM_QUEUE_TRANSFORM)) {
    1143            0 :                     (void)dataList.emplace_back(std::make_pair(PtrToValue(endpoints), endpointsLen));
    1144              :                 } else {
    1145            2 :                     (void)dataList.emplace_back(std::make_pair(PtrToValue(spareEndpoints.get()), endpointsLen));
    1146              :                 }
    1147              :             }
    1148           15 :             break;
    1149              :         }
    1150           11 :         case ConfigCmd::DGW_CFG_CMD_UPDATE_PROFILING:
    1151              :         case ConfigCmd::DGW_CFG_CMD_DEL_GROUP:
    1152              :         case ConfigCmd::DGW_CFG_CMD_SET_HCCL_PROTOCOL: {
    1153           11 :             cfgLen += sizeof(cfgInfo);
    1154           11 :             (void)dataList.emplace_back(std::make_pair(PtrToValue(&cfgInfo), sizeof(ConfigInfo)));
    1155           11 :             break;
    1156              :         }
    1157            4 :         case ConfigCmd::DGW_CFG_CMD_INIT_DYNAMIC_SCHEDULE: {
    1158            4 :             if (isProxy_ && QSFeatureCtrl::IsSupportSetVisibleDevices(g_chipType) && cfgInfo.cfg.dynamicSchedCfgV2 != nullptr) {
    1159            1 :                 const auto cRet = ChangeDynamicScheduleDeviceId(cfgInfo);
    1160            1 :                 if (cRet != static_cast<int32_t>(BQS_STATUS_OK)) {
    1161            0 :                     return cRet;
    1162              :                 }
    1163              :             }
    1164              : 
    1165            4 :             cfgLen += sizeof(cfgInfo) + sizeof(DynamicSchedConfigV2);
    1166            4 :             (void)dataList.emplace_back(std::make_pair(PtrToValue(&cfgInfo), sizeof(ConfigInfo)));
    1167            4 :             (void)dataList.emplace_back(std::make_pair(PtrToValue(cfgInfo.cfg.dynamicSchedCfgV2),
    1168            4 :                 sizeof(DynamicSchedConfigV2)));
    1169            4 :             break;
    1170              :         }
    1171            2 :         case ConfigCmd::DGW_CFG_CMD_STOP_SCHEDULE:
    1172              :         case ConfigCmd::DGW_CFG_CMD_CLEAR_AND_RESTART_SCHEDULE: {
    1173            2 :             const size_t rootModelIdsLen = cfgInfo.cfg.reDeployCfg.rootModelNum * sizeof(uint32_t);
    1174            2 :             cfgLen += sizeof(cfgInfo) + rootModelIdsLen;
    1175            2 :             (void)dataList.emplace_back(std::make_pair(PtrToValue(&cfgInfo), sizeof(ConfigInfo)));
    1176            2 :             (void)dataList.emplace_back(std::make_pair(cfgInfo.cfg.reDeployCfg.rootModelIdsAddr, rootModelIdsLen));
    1177            2 :             break;
    1178              :         }
    1179            1 :         default: {
    1180            1 :             BQS_LOG_ERROR("calculate config info len failed, cmd[%d] is invalid.", static_cast<int32_t>(cfgInfo.cmd));
    1181            1 :             return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1182              :         }
    1183              :     }
    1184           55 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1185              : }
    1186              : 
    1187           12 : int32_t DgwClient::CheckConfigNum(const ConfigQuery &query, ConfigInfo &cfgInfo)
    1188              : {
    1189           12 :     int32_t ret = static_cast<int32_t>(BQS_STATUS_OK);
    1190           12 :     switch (query.mode) {
    1191            4 :         case QueryMode::DGW_QUERY_MODE_GROUP: {
    1192            4 :             const uint32_t endpointNum = query.qry.groupQry.endpointNum;
    1193              :             // query config num
    1194            4 :             ConfigQuery tmpQry = query;
    1195            4 :             ret = QueryConfigNum(tmpQry);
    1196            4 :             if (ret == static_cast<int32_t>(BQS_STATUS_OK)) {
    1197              :                 // check endpointNum
    1198            4 :                 if ((endpointNum != tmpQry.qry.groupQry.endpointNum) || (endpointNum == 0U)) {
    1199            1 :                     BQS_LOG_ERROR("[DgwClient] Param error! endpointNum in query is [%u], "
    1200              :                         "but endpointNum searched from dgw server is [%u].",
    1201              :                         endpointNum, tmpQry.qry.groupQry.endpointNum);
    1202            1 :                     ret = static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1203              :                 } else {
    1204              :                     // set to cfgInfo
    1205            3 :                     cfgInfo.cmd = ConfigCmd::DGW_CFG_CMD_QRY_GROUP;
    1206            3 :                     cfgInfo.cfg.groupCfg.endpointNum = endpointNum;
    1207              :                 }
    1208              :             }
    1209            4 :             break;
    1210              :         }
    1211            7 :         case QueryMode::DGW_QUERY_MODE_SRC_ROUTE:
    1212              :         case QueryMode::DGW_QUERY_MODE_DST_ROUTE:
    1213              :         case QueryMode::DGW_QUERY_MODE_SRC_DST_ROUTE:
    1214              :         case QueryMode::DGW_QUERY_MODE_ALL_ROUTE: {
    1215            7 :             uint32_t routeNum = query.qry.routeQry.routeNum;
    1216              :             // query config num
    1217            7 :             ConfigQuery tmpQry = query;
    1218            7 :             ret = QueryConfigNum(tmpQry);
    1219            7 :             if (ret == static_cast<int32_t>(BQS_STATUS_OK)) {
    1220              :                 // check routeNum
    1221            7 :                 if ((routeNum != tmpQry.qry.routeQry.routeNum) || (routeNum == 0U)) {
    1222            1 :                     BQS_LOG_ERROR("[DgwClient] Param error! routeNum in query is [%u], "
    1223              :                         "but routeNum searched from dgw server is [%u].",
    1224              :                         routeNum, tmpQry.qry.routeQry.routeNum);
    1225            1 :                     ret = static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1226              :                 } else {
    1227              :                     // set to cfgInfo
    1228            6 :                     cfgInfo.cmd = ConfigCmd::DGW_CFG_CMD_QRY_ROUTE;
    1229            6 :                     cfgInfo.cfg.routesCfg.routeNum = routeNum;
    1230              :                 }
    1231              :             }
    1232            7 :             break;
    1233              :         }
    1234            1 :         default: {
    1235            1 :             ret = static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1236            1 :             BQS_LOG_ERROR("[DgwClient] query mode[%d] is invalid.", static_cast<int32_t>(query.mode));
    1237            1 :             break;
    1238              :         }
    1239              :     }
    1240           12 :     return ret;
    1241              : }
    1242              : 
    1243           13 : int32_t DgwClient::GetUpdateRouteRet(const ConfigInfo &cfgInfo, const uintptr_t mbufData, const size_t cfgLen,
    1244              :                                      std::vector<int32_t> &cfgRets, int32_t &cmdRet) const
    1245              : {
    1246           13 :     bool failFlag = false;
    1247           13 :     const uintptr_t retAddr = mbufData + cfgLen;
    1248           13 :     CfgRetInfo * const results = PtrToPtr<void, CfgRetInfo>(ValueToPtr(retAddr));
    1249           13 :     const size_t routeNum = static_cast<size_t>(cfgInfo.cfg.routesCfg.routeNum);
    1250           40 :     for (size_t i = 0UL; i < routeNum; i++) {
    1251           53 :         const int32_t retCode = (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) ?
    1252           26 :             cmdRet : PtrAdd<CfgRetInfo>(results, routeNum, i)->retCode;
    1253           27 :         cfgRets.push_back(retCode);
    1254           53 :         failFlag = ((!failFlag) && (retCode != static_cast<int32_t>(BQS_STATUS_OK))) ? true : failFlag;
    1255              :     }
    1256           13 :     cmdRet = (failFlag) ? static_cast<int32_t>(BQS_STATUS_FAILED) : cmdRet;
    1257           13 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1258           26 : }
    1259              : 
    1260           18 : int32_t DgwClient::GetUpdateGroupRet(ConfigInfo &cfgInfo, const uintptr_t mbufData, const size_t cfgLen,
    1261              :                                      std::vector<int32_t> &cfgRets, int32_t &cmdRet) const
    1262              : {
    1263           18 :     const uintptr_t retAddr = mbufData + cfgLen;
    1264           32 :     cmdRet = (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) ?
    1265           14 :             cmdRet : PtrToPtr<void, CfgRetInfo>(ValueToPtr(retAddr))->retCode;
    1266           18 :     cfgRets.push_back(cmdRet);
    1267           18 :     if (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) {
    1268            4 :         return static_cast<int32_t>(BQS_STATUS_OK);
    1269              :     }
    1270           14 :     cfgInfo.cfg.groupCfg.groupId = PtrToPtr<void, ConfigInfo>(ValueToPtr(mbufData))->cfg.groupCfg.groupId;
    1271           14 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1272              : }
    1273              : 
    1274            5 : int32_t DgwClient::GetQryGroupRet(const ConfigInfo &cfgInfo, const uintptr_t mbufData, const size_t cfgLen,
    1275              :                                   std::vector<int32_t> &cfgRets, int32_t &cmdRet) const
    1276              : {
    1277              :     (void)cfgRets;
    1278            5 :     const uintptr_t retAddr = mbufData + sizeof(ConfigQuery) + cfgLen;
    1279           10 :     cmdRet = (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) ?
    1280            5 :             cmdRet : PtrToPtr<void, CfgRetInfo>(ValueToPtr(retAddr))->retCode;
    1281              :     // cpy result to user memory
    1282            5 :     if (cmdRet == static_cast<int32_t>(BQS_STATUS_OK)) {
    1283            5 :         if (!isServerOldVersion_) {
    1284            3 :             Endpoint *endpoints = cfgInfo.cfg.groupCfg.endpoints;
    1285            3 :             const size_t endpointsLen =  cfgInfo.cfg.groupCfg.endpointNum * sizeof(Endpoint);
    1286            3 :             const uintptr_t srcAddr = mbufData + sizeof(ConfigQuery) + sizeof(ConfigInfo);
    1287            3 :             const size_t srcLen = cfgLen - sizeof(ConfigInfo);
    1288            3 :             const auto cpyRet = memcpy_s(static_cast<void *>(endpoints), endpointsLen,
    1289            3 :                                          ValueToPtr(srcAddr), srcLen);
    1290            3 :             if (cpyRet != EOK) {
    1291            0 :                 cmdRet = static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1292            0 :                 BQS_LOG_ERROR("Memcpy failed, srcLen[%zu], dstLen[%zu] ret=[%d]", srcLen, endpointsLen, cpyRet);
    1293            0 :                 return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1294              :             }
    1295              :         } else {
    1296            2 :             BQS_LOG_INFO("[GetQryGroupRet] old version need to transfer queue 2 mem queue");
    1297            2 :             std::unique_ptr<Endpoint[]> spareEndpoints(new (std::nothrow) Endpoint[cfgInfo.cfg.groupCfg.endpointNum]);
    1298            2 :             if (spareEndpoints == nullptr) {
    1299            0 :                 BQS_LOG_ERROR("[DgwClient] malloc failed on spareEndpoints.");
    1300            0 :                 return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1301              :             }
    1302              : 
    1303            2 :             const size_t endpointsLen =  cfgInfo.cfg.groupCfg.endpointNum * sizeof(Endpoint);
    1304            2 :             const uintptr_t srcAddr = mbufData + sizeof(ConfigQuery) + sizeof(ConfigInfo);
    1305            2 :             const size_t srcLen = cfgLen - sizeof(ConfigInfo);
    1306            2 :             auto cpyRet = memcpy_s(static_cast<void *>(spareEndpoints.get()), endpointsLen,
    1307            2 :                                    ValueToPtr(srcAddr), srcLen);
    1308            2 :             if (cpyRet != EOK) {
    1309            1 :                 cmdRet = static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1310            1 :                 BQS_LOG_ERROR("Memcpy failed, srcLen[%zu], dstLen[%zu] ret=[%d]", srcLen, endpointsLen, cpyRet);
    1311            1 :                 return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1312              :             }
    1313            1 :             const int32_t ret = EndpointTransformQ2MemQ(spareEndpoints, cfgInfo.cfg.groupCfg.endpointNum);
    1314            1 :             if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
    1315            0 :                 BQS_LOG_ERROR("ret is not okay or routes client is nullptr");
    1316            0 :                 return ret;
    1317              :             }
    1318            1 :             Endpoint *endpoints = cfgInfo.cfg.groupCfg.endpoints;
    1319            1 :             cpyRet = memcpy_s(static_cast<void *>(endpoints), endpointsLen,
    1320            1 :                               static_cast<void *>(spareEndpoints.get()), srcLen);
    1321            1 :             if (cpyRet != EOK) {
    1322            0 :                 cmdRet = static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1323            0 :                 BQS_LOG_ERROR("Memcpy failed, srcLen[%zu], dstLen[%zu] ret=[%d]", srcLen, endpointsLen, cpyRet);
    1324            0 :                 return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1325              :             }
    1326            2 :         }
    1327              :     }
    1328            4 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1329              : }
    1330              : 
    1331            7 : int32_t DgwClient::GetQryRouteRet(const ConfigInfo &cfgInfo, const uintptr_t mbufData, const size_t cfgLen,
    1332              :                                   std::vector<int32_t> &cfgRets, int32_t &cmdRet) const
    1333              : {
    1334              :     (void)cfgRets;
    1335            7 :     const uintptr_t retAddr = mbufData + sizeof(ConfigQuery) + cfgLen;
    1336           14 :     cmdRet = (cmdRet != static_cast<int32_t>(BQS_STATUS_OK)) ?
    1337            7 :             cmdRet : PtrToPtr<void, CfgRetInfo>(ValueToPtr(retAddr))->retCode;
    1338              :     // cpy result to user memory
    1339            7 :     if (cmdRet == static_cast<int32_t>(BQS_STATUS_OK)) {
    1340            7 :         Route *routes = cfgInfo.cfg.routesCfg.routes;
    1341            7 :         const size_t routesLen = cfgInfo.cfg.routesCfg.routeNum * sizeof(Route);
    1342            7 :         const uintptr_t srcAddr = mbufData + sizeof(ConfigQuery) + sizeof(ConfigInfo);
    1343            7 :         const size_t srcLen = cfgLen - sizeof(ConfigInfo);
    1344            7 :         const auto cpyRet = memcpy_s(static_cast<void *>(routes), routesLen, ValueToPtr(srcAddr), srcLen);
    1345            7 :         if (cpyRet != EOK) {
    1346            1 :             cmdRet = static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1347            1 :             BQS_LOG_ERROR("Memcpy failed, srcLen[%zu], dstLen[%zu] ret=[%d]", srcLen, routesLen, cpyRet);
    1348            1 :             return static_cast<int32_t>(BQS_STATUS_INNER_ERROR);
    1349              :         }
    1350              :     }
    1351            6 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1352              : }
    1353              : 
    1354              : // 由于兼容性问题,该接口废弃
    1355            5 : int32_t DgwClient::WaitConfigEffect(const uint64_t timeout)
    1356              : {
    1357            5 :     BQS_LOG_INFO("[DgwClient] Begin to waitConfigEffect.");
    1358            5 :     const std::lock_guard<std::mutex> lk(mutexForWaitConfig);
    1359              :     // check dgw client initialized
    1360            5 :     if (!initFlag_) {
    1361            1 :         BQS_LOG_ERROR("[DgwClient] please check whether datagw client has initialized successfully.");
    1362            1 :         return static_cast<int32_t>(BQS_STATUS_NOT_INIT);
    1363              :     }
    1364              : 
    1365              :     // 隔1S发送一次事件到SERVER端检测建链是否成功
    1366            4 :     int32_t cmdRet = static_cast<int32_t>(BQS_STATUS_FAILED);
    1367            6 :     for (uint64_t index = 0; index <= timeout; index++) {
    1368            5 :         event_sync_msg syncMsg = {};
    1369            5 :         QsProcMsgRsp procMsgRsp = {};
    1370            5 :         const int32_t ret = SendEventToQsSync(&syncMsg, sizeof(event_sync_msg), QueueSubEventType::QUERY_LINKSTATUS,
    1371              :                                               procMsgRsp, static_cast<int32_t>(timeout));
    1372            5 :         if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
    1373            2 :             BQS_LOG_ERROR("[DgwClient] SendEventToQsSync failed ret[%d]", ret);
    1374            3 :             return ret;
    1375              :         }
    1376            3 :         cmdRet = procMsgRsp.retCode;
    1377            3 :         if (cmdRet == static_cast<int32_t>(BQS_STATUS_OK)) {
    1378            1 :             BQS_LOG_INFO("[DgwClient] WaitConfigEffect Success");
    1379            1 :             return static_cast<int32_t>(BQS_STATUS_OK);
    1380              :         } else {
    1381            2 :             (void)sleep(1);
    1382              :         }
    1383              :     }
    1384            1 :     BQS_LOG_ERROR("[DgwClient] WaitConfigEffect Failed");
    1385            1 :     return static_cast<int32_t>(BQS_STATUS_FAILED);
    1386            5 : }
    1387              : 
    1388            8 : int32_t DgwClient::WaitConfigEffect(const int32_t rsv, const int32_t timeout)
    1389              : {
    1390            8 :     BQS_LOG_INFO("[DgwClient] Begin to waitConfigEffect rsv value:%d, timeout:%ds", rsv, timeout);
    1391            8 :     if (rsv != 0) {
    1392            1 :         BQS_LOG_ERROR("[DgwClient] please check rsv value:%d", rsv);
    1393            1 :         return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1394              :     }
    1395            7 :     if (timeout <= 0) {
    1396            1 :         BQS_LOG_ERROR("[DgwClient] please check timeout value:%ds", timeout);
    1397            1 :         return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1398              :     }
    1399            6 :     const std::lock_guard<std::mutex> lk(mutexForWaitConfig);
    1400              :     // check dgw client initialized
    1401            6 :     if (!initFlag_) {
    1402            1 :         BQS_LOG_ERROR("[DgwClient] please check whether datagw client has initialized successfully.");
    1403            1 :         return static_cast<int32_t>(BQS_STATUS_NOT_INIT);
    1404              :     }
    1405              : 
    1406              :     // 隔1S发送一次事件到SERVER端检测建链是否成功
    1407            5 :     int32_t cmdRet = static_cast<int32_t>(BQS_STATUS_FAILED);
    1408           16 :     for (int32_t index = 0; index <= (QUERY_LINK_STATUS_UNIT / QUERY_LINK_STATUS_INTERVAL * timeout);
    1409              :          index++) {
    1410           15 :         event_sync_msg syncMsg = {};
    1411           15 :         QsProcMsgRsp procMsgRsp = {};
    1412           15 :         const int32_t ret = SendEventToQsSync(&syncMsg, sizeof(event_sync_msg),
    1413              :                                               QueueSubEventType::QUERY_LINKSTATUS_V2,
    1414              :                                               procMsgRsp, static_cast<int32_t>(timeout));
    1415           15 :         if (ret != static_cast<int32_t>(BQS_STATUS_OK)) {
    1416            2 :             BQS_LOG_ERROR("[DgwClient] SendEventToQsSync failed ret[%d]", ret);
    1417            4 :             return ret;
    1418              :         }
    1419           13 :         cmdRet = procMsgRsp.retCode;
    1420           13 :         if (cmdRet == static_cast<int32_t>(BQS_STATUS_OK)) {
    1421            1 :             BQS_LOG_INFO("[DgwClient] WaitConfigEffect Success");
    1422            1 :             return static_cast<int32_t>(BQS_STATUS_OK);
    1423           12 :         } else if (cmdRet == static_cast<int32_t>(BQS_STATUS_PARAM_INVALID)) {
    1424            1 :             BQS_LOG_INFO("[DgwClient] WaitConfigEffect is not supported");
    1425            1 :             return static_cast<int32_t>(BQS_STATUS_NOT_SUPPORT);
    1426              :         } else {
    1427           11 :             (void)usleep(QUERY_LINK_STATUS_INTERVAL);
    1428              :         }
    1429              :     }
    1430            1 :     BQS_LOG_ERROR("[DgwClient] WaitConfigEffect Failed");
    1431            1 :     return static_cast<int32_t>(BQS_STATUS_FAILED);
    1432            6 : }
    1433              : 
    1434            4 : int32_t DgwClient::GetPlatformInfo(const uint32_t deviceId)
    1435              : {
    1436            4 :     BQS_LOG_INFO("[DgwClient] begin to GetPlatformInfo, deviceId=%u", deviceId);
    1437            4 :     int64_t hardwareVersion = 0;
    1438            4 :     const auto drvRet = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
    1439            4 :     if (drvRet != DRV_ERROR_NONE) {
    1440            1 :         BQS_LOG_ERROR("get device info by halGetDeviceInfo failed, errorCode[%d] deviceId[%u]", drvRet, deviceId);
    1441            1 :         return static_cast<int32_t>(BQS_STATUS_FAILED);
    1442              :     }
    1443            3 :     g_chipType = AICPU_PLAT_GET_CHIP(static_cast<uint64_t>(hardwareVersion));
    1444            3 :     g_hadGetChipType = true;
    1445            3 :     BQS_LOG_INFO("[DgwClient] Get chip type [%u]", static_cast<uint32_t>(g_chipType));
    1446            3 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1447              : }
    1448              : 
    1449           27 : bool DgwClient::IsNumeric(const std::string& str) {
    1450           27 :     if (str.empty()) {
    1451            2 :         return false;
    1452              :     }
    1453           59 :     for (const char c : str) {
    1454           35 :         if (!static_cast<bool>(isdigit(static_cast<unsigned char>(c)))) {
    1455            1 :             return false;
    1456              :         }
    1457              :     }
    1458           24 :     return true;
    1459              : }
    1460              : 
    1461            8 : void DgwClient::SplitString(const std::string &str, std::vector<std::string> &result)
    1462              : {
    1463            8 :     size_t start = 0;
    1464            8 :     size_t end = str.find(',');
    1465              : 
    1466           27 :     while (end != std::string::npos) {
    1467           21 :         std::string substr = str.substr(start, end - start);
    1468           21 :         if (!IsNumeric(substr)) {
    1469            2 :             BQS_LOG_WARN("[DgwClient] invalid device id [%s]", substr.c_str());
    1470            2 :             return;
    1471              :         }
    1472           19 :         result.push_back(substr);
    1473           19 :         start = end + 1U;
    1474           19 :         end = str.find(',', start);
    1475           21 :     }
    1476              : 
    1477            6 :     std::string substr = str.substr(start);
    1478            6 :     if (!IsNumeric(substr)) {
    1479            1 :         BQS_LOG_WARN("[DgwClient] invalid device id [%s]", substr.c_str());
    1480            1 :         return;
    1481              :     }
    1482            5 :     result.push_back(substr);
    1483            6 : }
    1484              : 
    1485           11 : bool DgwClient::GetVisibleDevices()
    1486              : {
    1487              :     // 标记hadGetVisibleDevices表示即将完成ASCEND_RT_VISIBLE_DEVICES解析
    1488           11 :     g_hadGetVisibleDevices = true;
    1489              :     // 获取并校验ASCEND_RT_VISIBLE_DEVICES环境变量配置
    1490           11 :     std::string inputStr;
    1491           11 :     bqs::GetEnvVal("ASCEND_RT_VISIBLE_DEVICES", inputStr);
    1492           11 :     BQS_LOG_INFO("[DgwClient] Get env ASCEND_RT_VISIBLE_DEVICES [%s].", inputStr.c_str());
    1493           11 :     if (inputStr.empty()) {
    1494            2 :         return false;
    1495              :     }
    1496              :     // 清空userDeviceInfo中的内容
    1497            9 :     g_userDeviceInfo.clear();
    1498              :     // 配置解析并校验
    1499            9 :     uint32_t deviceCnt = 0U;
    1500            9 :     const drvError_t drvRet = drvGetDevNum(&deviceCnt);
    1501            9 :     if (drvRet != DRV_ERROR_NONE) {
    1502            1 :         BQS_LOG_ERROR("[DgwClient] get device count failed, errorCode [%d]", drvRet);
    1503            1 :         return true;
    1504              :     }
    1505            8 :     std::vector<std::string> splitInputStr;
    1506            8 :     SplitString(inputStr, splitInputStr);
    1507            8 :     BQS_LOG_INFO("[DgwClient] splitInputStr size [%zu]", splitInputStr.size());
    1508           27 :     for (size_t i = 0U; i < splitInputStr.size(); i++) {
    1509           22 :         uint32_t tmpValue = 0U;
    1510              :         try {
    1511           22 :             tmpValue = static_cast<uint32_t>(std::stoi(splitInputStr[i]));
    1512            1 :         } catch (std::exception &e) {
    1513            1 :             BQS_LOG_ERROR("[DgwClient] splitInputStr [%s] is invalid, error: %s", splitInputStr[i].c_str(), e.what());
    1514            1 :             break;
    1515            1 :         }
    1516           21 :         if (tmpValue >= deviceCnt) {
    1517            1 :             BQS_LOG_ERROR("[DgwClient] splitInputStr [%s] is exceed device count [%u]", splitInputStr[i].c_str(), deviceCnt);
    1518            1 :             break;
    1519              :         }
    1520           20 :         if (std::find(g_userDeviceInfo.begin(), g_userDeviceInfo.end(), tmpValue) != g_userDeviceInfo.end()) {
    1521            1 :             BQS_LOG_ERROR("[DgwClient] splitInputStr [%s] is repeat", splitInputStr[i].c_str());
    1522            1 :             break;
    1523              :         }
    1524           19 :         g_userDeviceInfo.push_back(tmpValue);
    1525              :     }
    1526            8 :     BQS_LOG_INFO("[DgwClient] g_userDeviceInfo size [%zu]", g_userDeviceInfo.size());
    1527            8 :     return true;
    1528           11 : }
    1529              : 
    1530            9 : int32_t DgwClient::ChangeUserDeviceIdToLogicDeviceId(const uint32_t userDevId, uint32_t &logicDevId)
    1531              : {
    1532            9 :     BQS_LOG_INFO("[DgwClient] begin to change user deviceId to logic deviceId, user deviceId=%u", userDevId);
    1533              :     // 先判断是不是有内容,避免重复解析,再获取环境变量、解析和校验
    1534            9 :     if (!g_hadGetVisibleDevices && !GetVisibleDevices()) {
    1535            0 :         return static_cast<int32_t>(BQS_STATUS_OK);
    1536              :     }
    1537              : 
    1538              :     // user device id匹配logic id
    1539            9 :     if (g_userDeviceInfo.empty()) {
    1540            4 :         return static_cast<int32_t>(BQS_STATUS_OK);
    1541            5 :     } else if (userDevId >= g_userDeviceInfo.size()) {
    1542            1 :         BQS_LOG_ERROR("[DgwClient] userDevId [%u] is exceed g_userDeviceInfo size [%zu]", userDevId, g_userDeviceInfo.size());
    1543            1 :         return static_cast<int32_t>(BQS_STATUS_PARAM_INVALID);
    1544              :     } else {
    1545            4 :         logicDevId = g_userDeviceInfo[userDevId];
    1546            4 :         BQS_LOG_INFO("[DgwClient] userDevId [%u] to logicDevId [%u]", userDevId, logicDevId);
    1547              :     }
    1548            4 :     return static_cast<int32_t>(BQS_STATUS_OK);
    1549              : }
    1550              : } // namespace bqs
        

Generated by: LCOV version 2.0-1