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

Generated by: LCOV version 2.0-1