LCOV - code coverage report
Current view: top level - adcore/commopts - sock_api.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 77.5 % 138 107
Test Date: 2026-07-28 10:54:24 Functions: 100.0 % 13 13

            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 "sock_api.h"
      12              : #include <arpa/inet.h>
      13              : #include <netinet/tcp.h>
      14              : #include "log/adx_log.h"
      15              : #include "adx_msg.h"
      16              : #include "mmpa_api.h"
      17              : using namespace Adx;
      18              : 
      19              : /**
      20              :  * @brief      create sock server
      21              :  * @param [in] adxLocalChan: local channel string
      22              :  *
      23              :  * @return
      24              :  *      sock fd
      25              :  */
      26            4 : int32_t SockServerCreate(const std::string &adxLocalChan)
      27              : {
      28            4 :     IDE_CTRL_VALUE_FAILED(!adxLocalChan.empty(), return -1, "local socket failed");
      29            4 :     int32_t sockFd = mmSocket(PF_LOCAL, SOCK_STREAM, 0);
      30            4 :     IDE_CTRL_VALUE_FAILED(sockFd >= 0, return sockFd, "local socket failed");
      31              : 
      32              :     struct sockaddr_un sockAddr;
      33            4 :     (void)memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr));
      34            4 :     int32_t ret = strcpy_s(sockAddr.sun_path + 1, sizeof(sockAddr.sun_path) - 1, adxLocalChan.c_str());
      35            4 :     if (ret != EOK) {
      36            1 :         IDE_LOGE("local socket path copy failed");
      37            1 :         ADX_LOCAL_CLOSE_AND_SET_INVALID(sockFd);
      38            1 :         return sockFd;
      39              :     }
      40              : 
      41            3 :     sockAddr.sun_family = AF_LOCAL;
      42            3 :     ret = mmBind(sockFd, reinterpret_cast<mmSockAddr *>(&sockAddr),
      43            3 :         offsetof(struct sockaddr_un, sun_path) + 1 + adxLocalChan.size());
      44            3 :     if (ret < 0) {
      45            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
      46            1 :         IDE_LOGE("local server bind exception info : %s",
      47              :                  mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
      48            1 :         ADX_LOCAL_CLOSE_AND_SET_INVALID(sockFd);
      49            1 :         return sockFd;
      50              :     }
      51              : 
      52            2 :     ret = mmListen(sockFd, TCP_MAX_LISTEN_NUM);
      53            2 :     if (ret < 0) {
      54            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
      55            1 :         IDE_LOGE("local server listen exception info : %s",
      56              :                  mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
      57            1 :         ADX_LOCAL_CLOSE_AND_SET_INVALID(sockFd);
      58            1 :         return sockFd;
      59              :     }
      60              : 
      61            1 :     IDE_LOGD("local server init %d", sockFd);
      62            1 :     return sockFd;
      63              : }
      64              : 
      65              : /**
      66              :  * @brief      destroy sock server
      67              :  * @param [in] sockFd: sock Fd
      68              :  *
      69              :  * @return
      70              :  *      IDE_DAEMON_OK: destroy sock server success
      71              :  *      IDE_DAEMON_ERROR: destroy sock server failed
      72              :  */
      73            2 : int32_t SockServerDestroy(int32_t &sockFd)
      74              : {
      75            2 :     if (sockFd < 0) {
      76            1 :         return IDE_DAEMON_ERROR;
      77              :     }
      78              : 
      79            1 :     mmClose(sockFd);
      80            1 :     sockFd = -1;
      81            1 :     return IDE_DAEMON_OK;
      82              : }
      83              : 
      84              : /**
      85              :  * @brief      create sock client
      86              :  *
      87              :  * @return
      88              :  *      sock fd
      89              :  */
      90            2 : int32_t SockClientCreate()
      91              : {
      92            2 :     int sockFd = mmSocket(PF_LOCAL, SOCK_STREAM, 0);
      93            2 :     IDE_CTRL_VALUE_FAILED(sockFd >= 0, return sockFd, "local socket failed");
      94            2 :     IDE_LOGI("SockClientCreate sockFd: %d", sockFd);
      95            2 :     return sockFd;
      96              : }
      97              : 
      98              : /**
      99              :  * @brief      destroy sock client
     100              :  * @param [in] sockFd: sock Fd
     101              :  *
     102              :  * @return
     103              :  *      IDE_DAEMON_OK: destroy sock client success
     104              :  *      IDE_DAEMON_ERROR: destroy sock client failed
     105              :  */
     106            1 : int32_t SockClientDestory(int32_t &sockFd)
     107              : {
     108            1 :     IDE_CTRL_VALUE_FAILED(sockFd >= 0, return IDE_DAEMON_ERROR, "sockFd invalid");
     109              : 
     110            1 :     mmClose(sockFd);
     111            1 :     sockFd = -1;
     112            1 :     return IDE_DAEMON_OK;
     113              : }
     114              : 
     115              : /**
     116              :  * @brief      call sock accept
     117              :  * @param [in] sockFd: sock Fd
     118              :  *
     119              :  * @return
     120              :  *      clientFd
     121              :  */
     122            2 : int32_t SockAccept(int32_t sockFd)
     123              : {
     124            2 :     IDE_CTRL_VALUE_FAILED(sockFd >= 0, return sockFd, "local socket failed");
     125              :     mmSockAddr clientAddr;
     126            2 :     (void)memset_s(&clientAddr, sizeof(clientAddr), 0, sizeof(clientAddr));
     127            2 :     mmSocklen_t len = sizeof(mmSockAddr);
     128            2 :     int32_t clientFd = mmAccept(sockFd, &clientAddr, &len);
     129            2 :     if (clientFd < 0) {
     130            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     131            1 :         IDE_LOGE("local socket accept failed, info : %s",
     132              :                  mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     133              :     }
     134              : 
     135            2 :     return clientFd;
     136              : }
     137              : 
     138              : /**
     139              :  * @brief      sock connect
     140              :  * @param [in] sockFd: sock Fd
     141              :  * @param [in] adxLocalChan: local channel string
     142              :  *
     143              :  * @return
     144              :  *      sockFd: sock fd
     145              :  *      IDE_DAEMON_ERROR: sock connect failed
     146              :  */
     147            4 : int32_t SockConnect(int32_t sockFd, const std::string &adxLocalChan)
     148              : {
     149            4 :     IDE_CTRL_VALUE_FAILED(sockFd >= 0, return IDE_DAEMON_ERROR, "local socket failed");
     150            4 :     IDE_CTRL_VALUE_FAILED(!adxLocalChan.empty(), return IDE_DAEMON_ERROR,
     151              :         "local socket failed");
     152              :     struct sockaddr_un sockAddr;
     153            4 :     (void)memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr));
     154            4 :     int32_t ret = strcpy_s(sockAddr.sun_path + 1, sizeof(sockAddr.sun_path) - 1, adxLocalChan.c_str());
     155            4 :     if (ret != EOK) {
     156            1 :         IDE_LOGE("local socket strcpy_s failed");
     157            1 :         return IDE_DAEMON_ERROR;
     158              :     }
     159              : 
     160            3 :     sockAddr.sun_family = AF_LOCAL;
     161            3 :     ret = mmConnect(sockFd, reinterpret_cast<mmSockAddr *>(&sockAddr),
     162            3 :         offsetof(struct sockaddr_un, sun_path) + 1 + adxLocalChan.size());
     163            3 :     if (ret < 0) {
     164            1 :         IDE_LOGE("local socket connect failed");
     165            1 :         return IDE_DAEMON_ERROR;
     166              :     }
     167              : 
     168            2 :     IDE_LOGI("SockConnect ret: %d, sockFd: %d", ret, sockFd);
     169            2 :     return sockFd;
     170              : }
     171              : 
     172              : /**
     173              :  * @brief      sock hal read
     174              :  * @param [in] fd: file descriptor
     175              :  * @param [in] readBuf: read buffer
     176              :  * @param [in] recvLen: receive length
     177              :  * @param [in] flag: read flag
     178              :  *
     179              :  * @return
     180              :  *      recvLen: receive length
     181              :  *      IDE_DAEMON_ERROR: sock hal read failed
     182              :  */
     183            3 : static uint32_t SockHalRead(int32_t fd, IdeBuffT readBuf, int32_t recvLen, int32_t flag)
     184              : {
     185            3 :     if (fd < 0 || readBuf == nullptr || recvLen <= 0) {
     186            0 :         return IDE_DAEMON_ERROR;
     187              :     }
     188              : 
     189            3 :     int32_t remainLen = recvLen;
     190              :     do {
     191           72 :         int32_t len = mmSocketRecv(fd, readBuf, remainLen, flag);
     192           72 :         IDE_LOGI("sock %d recv length %d, %d", fd, len, remainLen);
     193           72 :         if (len < 0 && mmGetErrorCode() == EINTR) {
     194            0 :             continue;
     195           72 :         } else if (len < 0) {
     196            0 :             char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     197            0 :             IDE_LOGE("sock recv error, info : %s", mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     198            0 :             return IDE_DAEMON_ERROR;
     199              :         }
     200              : 
     201           72 :         remainLen -= len;
     202           72 :     } while (remainLen > 0);
     203              : 
     204            3 :     return static_cast<uint32_t>(recvLen);
     205              : }
     206              : 
     207              : /**
     208              :  * @brief      check msg valid
     209              :  * @param [in] proto: msg proto
     210              :  *
     211              :  * @return
     212              :  *      true: msg is valid
     213              :  *      false: msg is invalid
     214              :  */
     215            3 : static bool CheckMsgValid(const MsgProto &proto)
     216              : {
     217            3 :     if (proto.headInfo != ADX_PROTO_MAGIC_VALUE) {
     218            3 :         return false;
     219              :     }
     220              : 
     221            0 :     if (proto.totalLen > INT32_MAX - sizeof(MsgProto)) {
     222            0 :         return false;
     223              :     }
     224              : 
     225            0 :     return true;
     226              : }
     227              : 
     228              : /**
     229              :  * @brief      sock proto read
     230              :  * @param [in] fd: file descriptor
     231              :  * @param [in] readBuf: read buffer
     232              :  * @param [in] recvLen: receive length
     233              :  * @param [in] flag: read flag
     234              :  *
     235              :  * @return
     236              :  *      recvTotalLen: receive total length
     237              :  *      IDE_DAEMON_ERROR: sock proto read failed
     238              :  */
     239            3 : static int32_t SockProtoRead(int32_t fd, IdeRecvBuffT readBuf, IdeI32Pt recvLen, int32_t flag)
     240              : {
     241              :     MsgProto proto;
     242            3 :     (void)memset_s(&proto, sizeof(proto), 0, sizeof(proto));
     243            3 :     if (SockHalRead(fd, static_cast<IdeBuffT>(&proto), sizeof(MsgProto), flag) != sizeof(MsgProto)) {
     244            0 :         IDE_LOGE("sock recv proto head error");
     245            0 :         return IDE_DAEMON_ERROR;
     246              :     }
     247              : 
     248            3 :     if (CheckMsgValid(proto) == false) {
     249            3 :         IDE_LOGE("check proto head error");
     250            3 :         return IDE_DAEMON_ERROR;
     251              :     }
     252              : 
     253            0 :     IdeU8Pt buffer = (IdeU8Pt)ADX_SAFE_MALLOC(proto.totalLen + sizeof(MsgProto));
     254            0 :     if (buffer == nullptr) {
     255            0 :         IDE_LOGE("check proto malloc error");
     256            0 :         return IDE_DAEMON_ERROR;
     257              :     }
     258              : 
     259            0 :     int32_t recvTotalLen = proto.totalLen + sizeof(MsgProto);
     260            0 :     int ret = memcpy_s(buffer, recvTotalLen, &proto, sizeof(MsgProto));
     261            0 :     IDE_LOGI("recvTotalLen: %d, sizeof(MsgProto): %zu", recvTotalLen, sizeof(MsgProto));
     262            0 :     if (ret != EOK) {
     263            0 :         IDE_LOGE("check memcpy_s head error");
     264            0 :         ADX_SAFE_FREE(buffer);
     265            0 :         return IDE_DAEMON_ERROR;
     266              :     }
     267              : 
     268            0 :     if (proto.totalLen != 0) {
     269            0 :         if (SockHalRead(fd, buffer + sizeof(MsgProto), proto.totalLen, flag) != proto.totalLen) {
     270            0 :             IDE_LOGE("sock recv proto body error");
     271            0 :             ADX_SAFE_FREE(buffer);
     272            0 :             return IDE_DAEMON_ERROR;
     273              :         }
     274              :     }
     275            0 :     *readBuf = buffer;
     276            0 :     *recvLen = recvTotalLen;
     277            0 :     return recvTotalLen;
     278              : }
     279              : 
     280              : /**
     281              :  * @brief      sock read
     282              :  * @param [in] fd: file descriptor
     283              :  * @param [in] readBuf: read buffer
     284              :  * @param [in] recvLen: receive length
     285              :  * @param [in] flag: read flag
     286              :  *
     287              :  * @return
     288              :  *      IDE_DAEMON_OK: sock read success
     289              :  *      IDE_DAEMON_ERROR: sock read failed
     290              :  */
     291            3 : int32_t SockRead(int32_t fd, IdeRecvBuffT readBuf, IdeI32Pt recvLen, int32_t flag)
     292              : {
     293            3 :     if (fd < 0 || readBuf == nullptr || recvLen == nullptr) {
     294            0 :         return IDE_DAEMON_ERROR;
     295              :     }
     296              : 
     297            3 :     if (SockProtoRead(fd, readBuf, recvLen, flag) < 0) {
     298            3 :         return IDE_DAEMON_ERROR;
     299              :     }
     300            0 :     return IDE_DAEMON_OK;
     301              : }
     302              : 
     303              : /**
     304              :  * @brief      sock hal write
     305              :  * @param [in] fd: file descriptor
     306              :  * @param [in] writeBuf: write buffer
     307              :  * @param [in] writeLen: receive length
     308              :  * @param [in] flag: write flag
     309              :  *
     310              :  * @return
     311              :  *      len: return len of mmSocketSend
     312              :  */
     313            3 : static int32_t SockHalWrite(int32_t fd, IdeSendBuffT writeBuf, int32_t writeLen, int32_t flag)
     314              : {
     315            3 :     int32_t len = 0;
     316              :     do {
     317            3 :         len = mmSocketSend(fd, const_cast<IdeBuffT>(writeBuf), writeLen, flag);
     318            3 :     } while (len < 0 && mmGetErrorCode() == EINTR);
     319            3 :     return len;
     320              : }
     321              : 
     322              : /**
     323              :  * @brief      sock write
     324              :  * @param [in] fd: file descriptor
     325              :  * @param [in] writeBuf: write buffer
     326              :  * @param [in] writeLen: receive length
     327              :  * @param [in] flag: write flag
     328              :  *
     329              :  * @return
     330              :  *      IDE_DAEMON_OK: sock write success
     331              :  *      IDE_DAEMON_ERROR: sock write failed
     332              :  */
     333            4 : int32_t SockWrite(int32_t fd, IdeSendBuffT writeBuf, int32_t len, int32_t flag)
     334              : {
     335            4 :     if (fd < 0 || writeBuf == nullptr || len <= 0) {
     336            1 :         return IDE_DAEMON_ERROR;
     337              :     }
     338              : 
     339            3 :     if (SockHalWrite(fd, writeBuf, len, flag) < 0) {
     340            1 :         return IDE_DAEMON_ERROR;
     341              :     }
     342            2 :     return IDE_DAEMON_OK;
     343              : }
     344              : 
     345              : /**
     346              :  * @brief      sock close for server accept
     347              :  * @param [in] sockFd: sock file descriptor
     348              :  *
     349              :  * @return
     350              :  *      ret: return val of mmClose
     351              :  *      IDE_DAEMON_ERROR: sockFd invalid
     352              :  */
     353            2 : int32_t SockClose(int32_t &sockFd)
     354              : {
     355            2 :     if (sockFd < 0) {
     356            1 :         return IDE_DAEMON_ERROR;
     357              :     }
     358              : 
     359            1 :     int32_t ret = mmClose(sockFd);
     360            1 :     sockFd = -1;
     361            1 :     return ret;
     362              : }
        

Generated by: LCOV version 2.0-1