LCOV - code coverage report
Current view: top level - adcore - adcore_api.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.2 % 236 220
Test Date: 2026-07-28 10:54:24 Functions: 100.0 % 15 15

            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 "adcore_api.h"
      12              : #include "hdc_api.h"
      13              : #include "memory_utils.h"
      14              : #include "log/adx_log.h"
      15              : #include "adx_msg_proto.h"
      16              : #include "file_utils.h"
      17              : #include "create_func.h"
      18              : #include "adx_component.h"
      19              : #include "adx_comm_opt_manager.h"
      20              : using namespace Adx;
      21              : constexpr int32_t TIME_ONE_THOUSAND = 1000;
      22              : /**
      23              :  * @brief       : watch hdc session to get result
      24              :  * @param [in]  : session        hdc session
      25              :  * @param [in]  : resultBuf      request info
      26              :  * @param [in]  : timeout        0 : wait_always, > 0 wait_timeout, < 0 wait_default; unit: ms
      27              :  * @return      : IDE_DAEMON_OK succeed; others failed
      28              :  */
      29            2 : static int32_t ReadSettingResult(const HDC_SESSION session, const AdxStringBuffer resultBuf, uint32_t resultLen,
      30              :     int32_t timeout)
      31              : {
      32            2 :     int32_t err = IDE_DAEMON_ERROR;
      33            2 :     if ((session == nullptr) || (resultBuf == nullptr)) {
      34            0 :         return err;
      35              :     }
      36              : 
      37              :     do {
      38            2 :         CommHandle handle{COMM_HDC, reinterpret_cast<OptHandle>(session), NR_COMPONENTS, timeout, nullptr};
      39            2 :         std::string value;
      40            2 :         err = AdxMsgProto::GetStringMsgData(handle, value);
      41            2 :         if (err == IDE_DAEMON_OK) {
      42            2 :             if (value.empty()) {
      43            0 :                 (void)usleep(TIME_ONE_THOUSAND); // sleep 1ms, avoid frequent read hdc
      44            0 :                 continue;
      45              :             }
      46              : 
      47            2 :             if (value.compare(0, strlen(HDC_END_MSG), HDC_END_MSG, strlen(HDC_END_MSG)) == 0) {
      48            2 :                 break;
      49              :             }
      50              : 
      51            0 :             err = memcpy_s(resultBuf, resultLen, value.c_str(), value.length());
      52            0 :             if (err != EOK) {
      53            0 :                 IDE_LOGE("memcpy_s failed, result = %d.", err);
      54            0 :                 err = IDE_DAEMON_ERROR;
      55            0 :                 break;
      56              :             }
      57              :         }
      58            2 :     } while (err == IDE_DAEMON_OK);
      59              : 
      60            2 :     return err;
      61              : }
      62              : 
      63            9 : static int32_t AdxSendMsgToServerByType(AdxHdcServiceType type, IdeTlvConReq req, const AdxStringBuffer result,
      64              :     uint32_t resultLen, int32_t timeout = -1)
      65              : {
      66            9 :     int32_t err = IDE_DAEMON_ERROR;
      67            9 :     std::unique_ptr<AdxCommOpt> opt (CreateAdxCommOpt(OptType::COMM_HDC));
      68            9 :     IDE_CTRL_VALUE_FAILED(opt != nullptr, return err, "create hdc commopt exception");
      69            9 :     bool ret = AdxCommOptManager::Instance().CommOptsRegister(opt);
      70            9 :     IDE_CTRL_VALUE_FAILED(ret, return err, "register hdc failed");
      71              : 
      72            9 :     HDC_CLIENT client = Adx::HdcClientCreate(type);
      73            9 :     if (client == nullptr) {
      74            2 :         IDE_LOGW("Hdc client create exception");
      75            2 :         return err;
      76              :     }
      77              : 
      78            7 :     HDC_SESSION session = nullptr;
      79            7 :     err = Adx::HdcSessionConnect(0, req->dev_id, client, &session);
      80            7 :     if (err != IDE_DAEMON_OK) {
      81            2 :         IDE_LOGW("Connect to device exception, please make sure device id is valid, device id = %d.", req->dev_id);
      82            2 :         (void)Adx::HdcClientDestroy(client);
      83            2 :         return err;
      84              :     }
      85              : 
      86            5 :     CommHandle handle{COMM_HDC, reinterpret_cast<OptHandle>(session), NR_COMPONENTS, -1, nullptr};
      87           10 :     err = Adx::AdxMsgProto::SendMsgData(handle, req->type, MsgStatus::MSG_STATUS_NONE_ERROR,
      88            5 :         static_cast<IdeSendBuffT>(req->value), req->len);
      89            5 :     if (err != EN_OK) {
      90            1 :         IDE_LOGE("Write level info to device failed by hdc, result=%d.", err);
      91            4 :     } else if (result != nullptr) {
      92            2 :         err = ReadSettingResult(session, result, resultLen, timeout);
      93              :     }
      94              : 
      95            5 :     (void)Adx::HdcSessionDestroy(session);
      96            5 :     (void)Adx::HdcClientDestroy(client);
      97            5 :     return err;
      98            9 : }
      99              : 
     100            5 : int32_t AdxSendMsgAndGetResultByType(AdxHdcServiceType type, IdeTlvConReq req, const AdxStringBuffer result,
     101              :     uint32_t resultLen)
     102              : {
     103            5 :     if ((req == nullptr) || (result == nullptr)) {
     104            1 :         return IDE_DAEMON_ERROR;
     105              :     }
     106            4 :     return AdxSendMsgToServerByType(type, req, result, resultLen);
     107              : }
     108              : 
     109            5 : int32_t AdxSendMsgAndNoResultByType(AdxHdcServiceType type, IdeTlvConReq req)
     110              : {
     111            5 :     if (req == nullptr) {
     112            1 :         return IDE_DAEMON_ERROR;
     113              :     }
     114            4 :     return AdxSendMsgToServerByType(type, req, nullptr, 0);
     115              : }
     116              : 
     117            2 : int32_t AdxSendMsgByHandle(AdxCommConHandle handle, CmdClassT type, AdxString data, uint32_t len)
     118              : {
     119            2 :     if ((handle == nullptr) || (data == nullptr)) {
     120            0 :         return IDE_DAEMON_ERROR;
     121              :     }
     122              : 
     123            2 :     std::unique_ptr<AdxCommOpt> opt (CreateAdxCommOpt(handle->type));
     124            2 :     IDE_CTRL_VALUE_FAILED(opt != nullptr, return IDE_DAEMON_ERROR, "create hdc commopt exception");
     125            2 :     bool ret = AdxCommOptManager::Instance().CommOptsRegister(opt);
     126            2 :     IDE_CTRL_VALUE_FAILED(ret, return IDE_DAEMON_ERROR, "register hdc failed");
     127              : 
     128            2 :     return (Adx::AdxMsgProto::SendMsgData(*handle, type, MsgStatus::MSG_STATUS_NONE_ERROR,
     129            2 :         static_cast<IdeSendBuffT>(data), len) == IDE_DAEMON_NONE_ERROR) ? IDE_DAEMON_OK : IDE_DAEMON_ERROR;
     130            2 : }
     131              : 
     132            5 : int32_t AdxSendFileByHandle(AdxCommConHandle handle, CmdClassT type, AdxString srcPath, AdxString desPath,
     133              :     SendFileType flag)
     134              : {
     135            5 :     if ((handle == nullptr) || (srcPath == nullptr) || (desPath == nullptr)) {
     136            0 :         return IDE_DAEMON_ERROR;
     137              :     }
     138           10 :     if (!Adx::FileUtils::IsFileExist(std::string(srcPath))) {
     139            1 :         IDE_LOGE("File %s does not exist.", srcPath);
     140            1 :         return IDE_DAEMON_ERROR;
     141              :     }
     142              : 
     143            4 :     std::unique_ptr<AdxCommOpt> opt (CreateAdxCommOpt(handle->type));
     144            4 :     IDE_CTRL_VALUE_FAILED(opt != nullptr, return IDE_DAEMON_ERROR, "create hdc commopt exception");
     145            4 :     bool err = AdxCommOptManager::Instance().CommOptsRegister(opt);
     146            4 :     IDE_CTRL_VALUE_FAILED(err, return IDE_DAEMON_ERROR, "register hdc failed");
     147              : 
     148            4 :     int32_t fd = mmOpen2(srcPath, M_RDONLY | M_BINARY, S_IREAD);
     149            4 :     if (fd < 0) {
     150            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     151            1 :         IDE_LOGE("open send file failed, info : %s, open file is %s",
     152              :             mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN), srcPath);
     153            1 :         return IDE_DAEMON_ERROR;
     154              :     }
     155              : 
     156              :     // send file name
     157            6 :     int32_t ret = Adx::AdxMsgProto::SendMsgData(*handle, type, MsgStatus::MSG_STATUS_NONE_ERROR,
     158            3 :         static_cast<IdeSendBuffT>(desPath), strlen(desPath) + 1U);
     159            3 :     if (ret != IDE_DAEMON_NONE_ERROR) {
     160            1 :         if (fd >= 0) {
     161            1 :             mmClose(fd);
     162            1 :             fd = -1;
     163              :         }
     164            1 :         IDE_LOGE("send file path failed, file path name is %s", srcPath);
     165            1 :         return IDE_DAEMON_ERROR;
     166              :     }
     167              : 
     168              :     // send file data
     169            2 :     if (flag == SEND_FILE_TYPE_REAL_FILE) {
     170            2 :         ret = Adx::AdxMsgProto::SendEventFile(*handle, type, 0, fd);
     171              :     } else {
     172            0 :         ret = Adx::AdxMsgProto::SendFile(*handle, type, 0, fd);
     173              :     }
     174            2 :     if (fd >= 0) {
     175            2 :         mmClose(fd);
     176            2 :         fd = -1;
     177              :     }
     178              : 
     179            2 :     if (ret != IDE_DAEMON_NONE_ERROR) {
     180            1 :         IDE_LOGE("read or send file failed, start to send ctrl msg to notice host, ret=%d", ret);
     181            1 :         ret = IDE_DAEMON_ERROR;
     182              :     }
     183            2 :     return ret;
     184            4 : }
     185              : 
     186              : /**
     187              :  * @brief       : convert component type to CmdClassT
     188              :  * @param  [in] : cmptType     component type
     189              :  * @return      : NR_IDE_CMD_CLASS failed; others succeed
     190              :  */
     191           35 : static CmdClassT GetReqTypeByComponentType(ComponentType cmptType)
     192              : {
     193           35 :     CmdClassT cmdType = NR_IDE_CMD_CLASS;
     194          335 :     for (uint32_t i = 0; i < ARRAY_LEN(g_componentsInfo, AdxComponentMap); i++) {
     195          312 :         if (cmptType == g_componentsInfo[i].cmptType) {
     196           12 :             cmdType = g_componentsInfo[i].cmdType;
     197           12 :             break;
     198              :         }
     199              :     }
     200           35 :     return cmdType;
     201              : }
     202              : 
     203              : /**
     204              :  * @brief       : get attribute value by communication handle
     205              :  * @param [in]  : handle    hdc session
     206              :  * @param [in]  : attr      attribute type
     207              :  * @param [out] : value     attribute value
     208              :  * @return      : IDE_DAEMON_OK succeed; IDE_DAEMON_ERROR failed
     209              :  */
     210            8 : int32_t AdxGetAttrByCommHandle(AdxCommConHandle handle, int32_t attr, int32_t *value)
     211              : {
     212            8 :     if (handle == nullptr || value == nullptr) {
     213            2 :         IDE_LOGE("get attribute failed, invalid input");
     214            2 :         return IDE_DAEMON_ERROR;
     215              :     }
     216            6 :     return IdeGetAttrBySession(reinterpret_cast<HDC_SESSION>(handle->session), attr, value);
     217              : }
     218              : 
     219              : /**
     220              :  * @brief       : create long link communication handle
     221              :  * @param [in]  : type         server type
     222              :  * @param [in]  : devId        device id
     223              :  * @param [in]  : compType     component type
     224              :  * @return      : nullptr failed; others succeed
     225              :  */
     226            8 : AdxCommHandle AdxCreateCommHandle(AdxHdcServiceType type, int32_t devId, ComponentType compType)
     227              : {
     228            8 :     std::unique_ptr<AdxCommOpt> opt (CreateAdxCommOpt(OptType::COMM_HDC));
     229            8 :     IDE_CTRL_VALUE_FAILED(opt != nullptr, return nullptr, "create hdc commopt exception");
     230            8 :     bool ret = AdxCommOptManager::Instance().CommOptsRegister(opt);
     231            8 :     IDE_CTRL_VALUE_FAILED(ret, return nullptr, "register hdc failed");
     232              : 
     233            8 :     HDC_CLIENT client = Adx::HdcClientCreate(type);
     234            8 :     IDE_CTRL_VALUE_FAILED(client != nullptr, return nullptr, "Hdc client create exception");
     235              : 
     236            7 :     HDC_SESSION session = nullptr;
     237            7 :     int32_t err = Adx::HdcSessionConnect(0, devId, client, &session);
     238            7 :     if (err != IDE_DAEMON_OK) {
     239            1 :         IDE_LOGW("Connect to device exception, please make sure device id is valid, device id = %d.", devId);
     240            1 :         (void)Adx::HdcClientDestroy(client);
     241            1 :         return nullptr;
     242              :     }
     243              : 
     244            6 :     AdxCommHandle handle = static_cast<AdxCommHandle>(IdeXmalloc(sizeof(CommHandle)));
     245            6 :     IDE_CTRL_VALUE_FAILED(handle != nullptr, return handle, "Malloc handle failed.");
     246            6 :     handle->type = OptType::COMM_HDC;
     247            6 :     handle->session = reinterpret_cast<OptHandle>(session);
     248            6 :     handle->client = client;
     249            6 :     handle->comp = compType;
     250            6 :     handle->timeout = 0;
     251              : 
     252            6 :     const std::string defaultMessage = "LONG_LINK_DEFAULT";
     253            6 :     err = Adx::AdxMsgProto::SendMsgData(*handle, GetReqTypeByComponentType(compType), MsgStatus::MSG_STATUS_LONG_LINK,
     254            6 :         static_cast<IdeSendBuffT>(defaultMessage.c_str()), defaultMessage.size());
     255            6 :     if (err != IDE_DAEMON_OK) {
     256            3 :         IDE_LOGE("Write default info to device failed by hdc, result=%d.", err);
     257            3 :         (void)Adx::HdcSessionDestroy(session);
     258            3 :         (void)Adx::HdcClientDestroy(client);
     259            3 :         handle->session = 0;
     260            3 :         handle->client = nullptr;
     261            3 :         IDE_XFREE_AND_SET_NULL(handle);
     262              :     }
     263            6 :     return handle;
     264            8 : }
     265              : 
     266              : /**
     267              :  * @brief       : check if handle is valid
     268              :  * @param [in]  : handle         checked handle
     269              :  * @return      : IDE_DAEMON_OK valid; IDE_DAEMON_ERROR invalid
     270              :  */
     271            8 : int32_t AdxIsCommHandleValid(AdxCommConHandle handle)
     272              : {
     273            8 :     if ((handle == nullptr) || (handle->session == 0)) {
     274            6 :         IDE_LOGE("the handle is invalid");
     275            6 :         return IDE_DAEMON_ERROR;
     276              :     }
     277            2 :     return IDE_DAEMON_OK;
     278              : }
     279              : 
     280              : /**
     281              :  * @brief       : destroy and free communication handle
     282              :  * @param [in]  : handle         communication handle
     283              :  */
     284            5 : void AdxDestroyCommHandle(AdxCommHandle handle)
     285              : {
     286            5 :     if (handle != nullptr && handle->session != 0) {
     287            4 :         (void)Adx::HdcSessionDestroy(reinterpret_cast<HDC_SESSION>(handle->session));
     288            4 :         if (handle->client != nullptr) {
     289            3 :             (void)Adx::HdcClientDestroy(handle->client);
     290              :         }
     291            4 :         IdeXfree(handle);
     292              :     } else {
     293            1 :         IDE_LOGE("Can not destroy invalid handle.");
     294              :     }
     295            5 : }
     296              : 
     297              : /**
     298              :  * @brief       : send message by communication handle
     299              :  * @param [in]  : handle         communication handle
     300              :  * @param [in]  : data           message data
     301              :  * @param [in]  : len            data length
     302              :  * @return      : IDE_DAEMON_OK succeed; others failed
     303              :  */
     304           26 : int32_t AdxSendMsg(AdxCommConHandle handle, AdxString data, uint32_t len)
     305              : {
     306           26 :     if ((handle == nullptr) || (data == nullptr)) {
     307            2 :         return IDE_DAEMON_ERROR;
     308              :     }
     309              : 
     310           24 :     std::unique_ptr<AdxCommOpt> opt (CreateAdxCommOpt(handle->type));
     311           24 :     IDE_CTRL_VALUE_FAILED(opt != nullptr, return IDE_DAEMON_ERROR, "create hdc commopt exception");
     312           24 :     bool ret = AdxCommOptManager::Instance().CommOptsRegister(opt);
     313           24 :     IDE_CTRL_VALUE_FAILED(ret, return IDE_DAEMON_ERROR, "register hdc failed");
     314              : 
     315           24 :     return (Adx::AdxMsgProto::SendMsgData(*handle, GetReqTypeByComponentType(handle->comp),
     316              :         MsgStatus::MSG_STATUS_NONE_ERROR, static_cast<IdeSendBuffT>(data), len) ==
     317           24 :         IDE_DAEMON_NONE_ERROR) ? IDE_DAEMON_OK : IDE_DAEMON_ERROR;
     318           24 : }
     319              : 
     320              : /**
     321              :  * @brief          : receive message by communication handle
     322              :  * @param [in]     : handle         communication handle
     323              :  * @param [out]    : data           message data
     324              :  * @param [in|out] : len            data length
     325              :  * @param [in]     : timeout        max wait time; unit: ms
     326              :  * @return         : IDE_DAEMON_OK succeed; others failed
     327              :  */
     328           30 : int32_t AdxRecvMsg(AdxCommHandle handle, IdeStrBufAddrT data, uint32_t *len, uint32_t timeout)
     329              : {
     330           30 :     int32_t err = IDE_DAEMON_ERROR;
     331           30 :     if (len == nullptr) {
     332            1 :         IDE_LOGE("receive message failed, invalid length");
     333            1 :         return err;
     334              :     }
     335           29 :     if ((handle == nullptr) || (data == nullptr)) {
     336            2 :         *len = 0;
     337            2 :         IDE_LOGE("receive message failed, invalid input.");
     338            2 :         return err;
     339              :     }
     340              : 
     341           27 :     handle->timeout = static_cast<int32_t>(timeout);
     342           27 :     std::string value;
     343           27 :     err = AdxMsgProto::GetStringMsgData(*handle, value);
     344           27 :     if (err != IDE_DAEMON_OK) {
     345            7 :         *len = 0;
     346            7 :         return err;
     347              :     }
     348           20 :     if (value.empty()) {
     349            0 :         *len = 0;
     350            0 :         return IDE_DAEMON_RECV_NODATA;
     351              :     }
     352           20 :     if (*len < value.length()) {
     353            1 :         IDE_LOGE("input length(%u bytes) less than read message length(%zu bytes)", *len, value.length());
     354            1 :         *len = 0;
     355            1 :         return IDE_DAEMON_ERROR;
     356              :     }
     357           19 :     err = memcpy_s(*data, *len, value.c_str(), value.length());
     358           19 :     if (err != EOK) {
     359            0 :         IDE_LOGE("memcpy_s failed, result=%d.", err);
     360            0 :         *len = 0;
     361            0 :         return IDE_DAEMON_ERROR;
     362              :     }
     363           19 :     *len = value.length();
     364           19 :     return err;
     365           27 : }
     366              : 
     367            9 : static int32_t AdxServerCommProcess(AdxHdcServiceType type, AdxTlvConReq req, AdxStringBuffer result, uint32_t length,
     368              :     uint32_t timeout)
     369              : {
     370            9 :     if (req == nullptr) {
     371            2 :         IDE_LOGE("invalid input, tlv struct is null");
     372            2 :         return IDE_DAEMON_ERROR;
     373              :     }
     374            7 :     if (req->len < 0) {
     375            1 :         IDE_LOGE("invalid input, length of tlv struct is %d bytes", req->len);
     376            1 :         return IDE_DAEMON_ERROR;
     377              :     }
     378            6 :     IdeTlvReq ide = static_cast<IdeTlvReq>(IdeXmalloc(sizeof(TlvReqT) + req->len));
     379            6 :     if (ide == nullptr) {
     380            1 :         IDE_LOGE("malloc ide tlv failed, size=%zu bytes", sizeof(TlvReqT) + req->len);
     381            1 :         return IDE_DAEMON_ERROR;
     382              :     }
     383            5 :     ide->type = GetReqTypeByComponentType(req->type);
     384            5 :     if (ide->type == NR_IDE_CMD_CLASS) {
     385            1 :         IDE_LOGE("invalid input, component type of tlv struct is %d", static_cast<int32_t>(req->type));
     386            1 :         IDE_XFREE_AND_SET_NULL(ide);
     387            1 :         return IDE_DAEMON_ERROR;
     388              :     }
     389            4 :     ide->dev_id = req->devId;
     390            4 :     ide->len = req->len;
     391            4 :     int32_t ret = memcpy_s(ide->value, ide->len, req->value, req->len);
     392            4 :     if (ret != EOK) {
     393            1 :         IDE_LOGE("memcpy_s from cmptype to req failed, result=%d", ret);
     394            1 :         IDE_XFREE_AND_SET_NULL(ide);
     395            1 :         return IDE_DAEMON_ERROR;
     396              :     }
     397            3 :     if (result == nullptr) {
     398            2 :         IDE_LOGI("AdxDevCommShortLink, no results needed, cmpt=%d, cmd=%d, devId=%d",
     399              :             static_cast<int32_t>(req->type), static_cast<int32_t>(ide->type), ide->dev_id);
     400            2 :         ret = AdxSendMsgAndNoResultByType(type, ide);
     401              :     } else {
     402            1 :         IDE_LOGI("AdxDevCommShortLink, result wait timeout:%u, cmpt=%d, cmd=%d, devId=%d", timeout,
     403              :             static_cast<int32_t>(req->type), static_cast<int32_t>(ide->type), ide->dev_id);
     404            1 :         (void)memset_s(result, length, 0, length);
     405            1 :         ret = AdxSendMsgToServerByType(type, ide, result, length, static_cast<int32_t>(timeout));
     406              :     }
     407            3 :     IDE_XFREE_AND_SET_NULL(ide);
     408            3 :     return ret;
     409              : }
     410              : 
     411              : /**
     412              :  * @brief          : communication with the specific hdc server and get result if needed
     413              :  * @param [in]     : type         server type
     414              :  * @param [in]     : req          including device id, component type, message data
     415              :  * @param [in|out] : result       get result data from device, pass nullptr if result is not needed
     416              :  * @param [in]     : length       result data length
     417              :  * @param [in]     : timeout      0 : wait_always, > 0 wait_timeout; unit: ms
     418              :  * @return         : IDE_DAEMON_OK succeed; others failed
     419              :  */
     420            9 : int32_t AdxDevCommShortLink(AdxHdcServiceType type, AdxTlvConReq req, AdxStringBuffer result, uint32_t length,
     421              :     uint32_t timeout) {
     422            9 :     int32_t ret = AdxServerCommProcess(type, req, result, length, timeout);
     423            9 :     if ((ret != IDE_DAEMON_OK) && (result != nullptr) && (strlen(result) == 0)) {
     424            5 :         const std::string value = "get result data from server failed";
     425            5 :         int32_t err = strncpy_s(result, length, value.c_str(), value.length());
     426            5 :         if (err != EOK) {
     427            1 :             IDE_LOGE("strncpy_s null result data failed, result: %d.", err);
     428              :         }
     429            5 :     }
     430            9 :     return ret;
     431              : }
        

Generated by: LCOV version 2.0-1