1d9f0492fSopenharmony_ci/*
2d9f0492fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License.
5d9f0492fSopenharmony_ci * You may obtain a copy of the License at
6d9f0492fSopenharmony_ci *
7d9f0492fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d9f0492fSopenharmony_ci *
9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and
13d9f0492fSopenharmony_ci * limitations under the License.
14d9f0492fSopenharmony_ci */
15d9f0492fSopenharmony_ci
16d9f0492fSopenharmony_ci#include <errno.h>
17d9f0492fSopenharmony_ci#include <fcntl.h>
18d9f0492fSopenharmony_ci#include <pthread.h>
19d9f0492fSopenharmony_ci#include <string.h>
20d9f0492fSopenharmony_ci#include <unistd.h>
21d9f0492fSopenharmony_ci#include <stdio.h>
22d9f0492fSopenharmony_ci#include <stdlib.h>
23d9f0492fSopenharmony_ci
24d9f0492fSopenharmony_ci#include <linux/in.h>
25d9f0492fSopenharmony_ci#include <linux/socket.h>
26d9f0492fSopenharmony_ci#include <linux/tcp.h>
27d9f0492fSopenharmony_ci#include <sys/socket.h>
28d9f0492fSopenharmony_ci#include <sys/time.h>
29d9f0492fSopenharmony_ci#include <sys/types.h>
30d9f0492fSopenharmony_ci#include <sys/un.h>
31d9f0492fSopenharmony_ci
32d9f0492fSopenharmony_ci#include "loop_systest.h"
33d9f0492fSopenharmony_ci#include "securec.h"
34d9f0492fSopenharmony_ci#include "loop_event.h"
35d9f0492fSopenharmony_ci#include "le_socket.h"
36d9f0492fSopenharmony_ci#include "le_task.h"
37d9f0492fSopenharmony_ci#include "list.h"
38d9f0492fSopenharmony_ci
39d9f0492fSopenharmony_ci#define RETRY_TIME (200 * 1000)     // 200 * 1000 wait 200ms CONNECT_RETRY_DELAY = 200 * 1000
40d9f0492fSopenharmony_ci#define MAX_RETRY_SEND_COUNT 2      // 2 max retry count CONNECT_RETRY_MAX_TIMES = 2;
41d9f0492fSopenharmony_ci
42d9f0492fSopenharmony_citypedef Agent_ {
43d9f0492fSopenharmony_ci    TaskHandle task;
44d9f0492fSopenharmony_ci    WatcherHandle input;
45d9f0492fSopenharmony_ci    WatcherHandle reader;
46d9f0492fSopenharmony_ci    int ptyfd;
47d9f0492fSopenharmony_ci} Agent;
48d9f0492fSopenharmony_ci
49d9f0492fSopenharmony_citypedef struct {
50d9f0492fSopenharmony_ci    struct ListNode node;
51d9f0492fSopenharmony_ci    uint32_t blockSize;     // block 的大小
52d9f0492fSopenharmony_ci    uint32_t currentIndex;  // 当前已经填充的位置
53d9f0492fSopenharmony_ci    uint8_t buffer[0];
54d9f0492fSopenharmony_ci} MsgBlock;
55d9f0492fSopenharmony_ci
56d9f0492fSopenharmony_citypedef struct {
57d9f0492fSopenharmony_ci    uint32_t maxRetryCount;
58d9f0492fSopenharmony_ci    uint32_t timeout;
59d9f0492fSopenharmony_ci    uint32_t msgNextId;
60d9f0492fSopenharmony_ci    int socketId;
61d9f0492fSopenharmony_ci    pthread_mutex_t mutex;
62d9f0492fSopenharmony_ci    MsgBlock recvBlock;  // 消息接收缓存
63d9f0492fSopenharmony_ci} ReqMsgMgr;
64d9f0492fSopenharmony_ci
65d9f0492fSopenharmony_cistatic pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
66d9f0492fSopenharmony_cistatic ReqMsgMgr *g_clientInstance = NULL;
67d9f0492fSopenharmony_ci
68d9f0492fSopenharmony_ciAgent *CreateAgent(const char *server, int flags)
69d9f0492fSopenharmony_ci{
70d9f0492fSopenharmony_ci    if (server == NULL) {
71d9f0492fSopenharmony_ci        printf("Invalid parameter \n");
72d9f0492fSopenharmony_ci        return NULL;
73d9f0492fSopenharmony_ci    }
74d9f0492fSopenharmony_ci
75d9f0492fSopenharmony_ci    TaskHandle task = NULL;
76d9f0492fSopenharmony_ci    LE_StreamInfo info = {};
77d9f0492fSopenharmony_ci    info.baseInfo.flags = flags;
78d9f0492fSopenharmony_ci    info.server = (char *)server;
79d9f0492fSopenharmony_ci    info.baseInfo.userDataSize = sizeof(Agent);
80d9f0492fSopenharmony_ci    info.baseInfo.close = OnClose;
81d9f0492fSopenharmony_ci    info.disConnectComplete = DisConnectComplete;
82d9f0492fSopenharmony_ci    info.connectComplete = OnConnectComplete;
83d9f0492fSopenharmony_ci    info.sendMessageComplete = OnSendMessageComplete;
84d9f0492fSopenharmony_ci    info.recvMessage = ClientOnRecvMessage;
85d9f0492fSopenharmony_ci
86d9f0492fSopenharmony_ci    LE_STATUS status = LE_CreateStreamClient(LE_GetDefaultLoop(), &task, &info);
87d9f0492fSopenharmony_ci    if (status != 0) {
88d9f0492fSopenharmony_ci        printf("Failed create client \n");
89d9f0492fSopenharmony_ci        return NULL;
90d9f0492fSopenharmony_ci    }
91d9f0492fSopenharmony_ci    Agent *agent = (Agent *)LE_GetUserData(task);
92d9f0492fSopenharmony_ci    if (agent == NULL) {
93d9f0492fSopenharmony_ci        printf("Invalid agent \n");
94d9f0492fSopenharmony_ci        return NULL;
95d9f0492fSopenharmony_ci    }
96d9f0492fSopenharmony_ci
97d9f0492fSopenharmony_ci    agent->task = task;
98d9f0492fSopenharmony_ci    return agent;
99d9f0492fSopenharmony_ci}
100d9f0492fSopenharmony_ci
101d9f0492fSopenharmony_cistatic int InitClientInstance()
102d9f0492fSopenharmony_ci{
103d9f0492fSopenharmony_ci    pthread_mutex_lock(&g_mutex);
104d9f0492fSopenharmony_ci    if (g_clientInstance != NULL) {
105d9f0492fSopenharmony_ci        pthread_mutex_unlock(&g_mutex);
106d9f0492fSopenharmony_ci        return 0;
107d9f0492fSopenharmony_ci    }
108d9f0492fSopenharmony_ci    ReqMsgMgr *clientInstance = malloc(sizeof(ReqMsgMgr) + RECV_BLOCK_LEN);
109d9f0492fSopenharmony_ci    if (clientInstance == NULL) {
110d9f0492fSopenharmony_ci        pthread_mutex_unlock(&g_mutex);
111d9f0492fSopenharmony_ci        return -1;
112d9f0492fSopenharmony_ci    }
113d9f0492fSopenharmony_ci    // init
114d9f0492fSopenharmony_ci    clientInstance->msgNextId = 1;
115d9f0492fSopenharmony_ci    clientInstance->timeout = GetDefaultTimeout(TIMEOUT_DEF);
116d9f0492fSopenharmony_ci    clientInstance->maxRetryCount = MAX_RETRY_SEND_COUNT;
117d9f0492fSopenharmony_ci    clientInstance->socketId = -1;
118d9f0492fSopenharmony_ci    pthread_mutex_init(&clientInstance->mutex, NULL);
119d9f0492fSopenharmony_ci    // init recvBlock
120d9f0492fSopenharmony_ci    OH_ListInit(&clientInstance->recvBlock.node);
121d9f0492fSopenharmony_ci    clientInstance->recvBlock.blockSize = RECV_BLOCK_LEN;
122d9f0492fSopenharmony_ci    clientInstance->recvBlock.currentIndex = 0;
123d9f0492fSopenharmony_ci    g_clientInstance = clientInstance;
124d9f0492fSopenharmony_ci    pthread_mutex_unlock(&g_mutex);
125d9f0492fSopenharmony_ci    return 0;
126d9f0492fSopenharmony_ci}
127d9f0492fSopenharmony_ci
128d9f0492fSopenharmony_civoid ClientInit(const char *socketPath, int flags)
129d9f0492fSopenharmony_ci{
130d9f0492fSopenharmony_ci    if (socketPath == NULL) {
131d9f0492fSopenharmony_ci        printf("Invalid parameter \n");
132d9f0492fSopenharmony_ci    }
133d9f0492fSopenharmony_ci    printf("AgentInit \n");
134d9f0492fSopenharmony_ci    Agent *agent = CreateAgent(socketPath, flags);
135d9f0492fSopenharmony_ci    if (agent == NULL) {
136d9f0492fSopenharmony_ci        printf("Failed to create agent \n");
137d9f0492fSopenharmony_ci        return;
138d9f0492fSopenharmony_ci    }
139d9f0492fSopenharmony_ci
140d9f0492fSopenharmony_ci    printf(" Client exit \n");
141d9f0492fSopenharmony_ci}
142d9f0492fSopenharmony_ci
143d9f0492fSopenharmony_ciint ClientDestroy(ReqMsgMgr *reqMgr)
144d9f0492fSopenharmony_ci{
145d9f0492fSopenharmony_ci    if (reqMgr == NULL) {
146d9f0492fSopenharmony_ci        printf("Invalid reqMgr \n");
147d9f0492fSopenharmony_ci        return -1;
148d9f0492fSopenharmony_ci    }
149d9f0492fSopenharmony_ci
150d9f0492fSopenharmony_ci    pthread_mutex_lock(&g_mutex);
151d9f0492fSopenharmony_ci    pthread_mutex_unlock(&g_mutex);
152d9f0492fSopenharmony_ci    pthread_mutex_destroy(&reqMgr->mutex);
153d9f0492fSopenharmony_ci    if (reqMgr->socketId >= 0) {
154d9f0492fSopenharmony_ci        CloseClientSocket(reqMgr->socketId);
155d9f0492fSopenharmony_ci        reqMgr->socketId = -1;
156d9f0492fSopenharmony_ci    }
157d9f0492fSopenharmony_ci    free(reqMgr);
158d9f0492fSopenharmony_ci    return 0;
159d9f0492fSopenharmony_ci}
160d9f0492fSopenharmony_ci
161d9f0492fSopenharmony_cistatic void CloseClientSocket(int socketId)
162d9f0492fSopenharmony_ci{
163d9f0492fSopenharmony_ci    printf("Closed socket with fd %d \n", socketId);
164d9f0492fSopenharmony_ci    if (socketId >= 0) {
165d9f0492fSopenharmony_ci        int flag = 0;
166d9f0492fSopenharmony_ci        setsockopt(socketId, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
167d9f0492fSopenharmony_ci        close(socketId);
168d9f0492fSopenharmony_ci    }
169d9f0492fSopenharmony_ci}
170d9f0492fSopenharmony_ci
171d9f0492fSopenharmony_cistatic int CreateClientSocket(uint32_t timeout)
172d9f0492fSopenharmony_ci{
173d9f0492fSopenharmony_ci    const char *socketName = "loopserver";
174d9f0492fSopenharmony_ci    int socketFd = socket(AF_UNIX, SOCK_STREAM, 0);  // SOCK_SEQPACKET
175d9f0492fSopenharmony_ci    if (socketFd < 0) {
176d9f0492fSopenharmony_ci        printf("Socket fd: %d error: %d \n", socketFd, errno);
177d9f0492fSopenharmony_ci    }
178d9f0492fSopenharmony_ci
179d9f0492fSopenharmony_ci    int ret = 0;
180d9f0492fSopenharmony_ci    do {
181d9f0492fSopenharmony_ci        int flag = 1;
182d9f0492fSopenharmony_ci        ret = setsockopt(socketFd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
183d9f0492fSopenharmony_ci        flag = 1;
184d9f0492fSopenharmony_ci        ret = setsockopt(socketFd, SOL_SOCKET, SO_PASSCRED, &flag, sizeof(flag));
185d9f0492fSopenharmony_ci        if (ret != 0) {
186d9f0492fSopenharmony_ci            printf("Set opt SO_PASSCRED name: %s error: %d \n", socketName, errno);
187d9f0492fSopenharmony_ci            break;
188d9f0492fSopenharmony_ci        }
189d9f0492fSopenharmony_ci        struct timeval timeoutVal = {timeout, 0};
190d9f0492fSopenharmony_ci        ret = setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeoutVal, sizeof(timeoutVal));
191d9f0492fSopenharmony_ci        if (ret != 0) {
192d9f0492fSopenharmony_ci            printf("Set opt SO_SNDTIMEO name: %s error: %d \n", socketName, errno);
193d9f0492fSopenharmony_ci            break;
194d9f0492fSopenharmony_ci        }
195d9f0492fSopenharmony_ci        ret = setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeoutVal, sizeof(timeoutVal));
196d9f0492fSopenharmony_ci        if (ret != 0) {
197d9f0492fSopenharmony_ci            printf("Set opt SO_RCVTIMEO name: %s error: %d \n", socketName, errno);
198d9f0492fSopenharmony_ci            break;
199d9f0492fSopenharmony_ci        }
200d9f0492fSopenharmony_ci        ret = _SYSTEM_ERROR;
201d9f0492fSopenharmony_ci        struct sockaddr_un addr;
202d9f0492fSopenharmony_ci        socklen_t pathSize = sizeof(addr.sun_path);
203d9f0492fSopenharmony_ci        int pathLen = snprintf_s(addr.sun_path, pathSize, (pathSize - 1), "%s%s", _SOCKET_DIR, socketName);
204d9f0492fSopenharmony_ci        if (pathLen <= 0) {
205d9f0492fSopenharmony_ci            printf("Format path: %s error: %d \n", socketName, errno);
206d9f0492fSopenharmony_ci            break;
207d9f0492fSopenharmony_ci        }
208d9f0492fSopenharmony_ci        addr.sun_family = AF_LOCAL;
209d9f0492fSopenharmony_ci        socklen_t socketAddrLen = offsetof(struct sockaddr_un, sun_path) + pathLen + 1;
210d9f0492fSopenharmony_ci        ret = connect(socketFd, (struct sockaddr *)(&addr), socketAddrLen);
211d9f0492fSopenharmony_ci        if (ret != 0) {
212d9f0492fSopenharmony_ci            printf("Failed to connect %s error: %d \n", addr.sun_path, errno);
213d9f0492fSopenharmony_ci            break;
214d9f0492fSopenharmony_ci        }
215d9f0492fSopenharmony_ci        printf("Create socket success %s socketFd: %d", addr.sun_path, socketFd);
216d9f0492fSopenharmony_ci        return socketFd;
217d9f0492fSopenharmony_ci    } while (0);
218d9f0492fSopenharmony_ci    CloseClientSocket(socketFd);
219d9f0492fSopenharmony_ci    return -1;
220d9f0492fSopenharmony_ci}
221d9f0492fSopenharmony_ci
222d9f0492fSopenharmony_cistatic void TryCreateSocket(ReqMsgMgr *reqMgr)
223d9f0492fSopenharmony_ci{
224d9f0492fSopenharmony_ci    uint32_t retryCount = 1;
225d9f0492fSopenharmony_ci    while (retryCount <= reqMgr->maxRetryCount) {
226d9f0492fSopenharmony_ci        if (reqMgr->socketId < 0) {
227d9f0492fSopenharmony_ci            reqMgr->socketId = CreateClientSocket(reqMgr->timeout);
228d9f0492fSopenharmony_ci        }
229d9f0492fSopenharmony_ci        if (reqMgr->socketId < 0) {
230d9f0492fSopenharmony_ci            printf("Failed to create socket, try again \n");
231d9f0492fSopenharmony_ci            usleep(RETRY_TIME);
232d9f0492fSopenharmony_ci            retryCount++;
233d9f0492fSopenharmony_ci            continue;
234d9f0492fSopenharmony_ci        }
235d9f0492fSopenharmony_ci        break;
236d9f0492fSopenharmony_ci    }
237d9f0492fSopenharmony_ci}
238d9f0492fSopenharmony_ci
239d9f0492fSopenharmony_cistatic int WriteMessage(int socketFd, const uint8_t *buf, ssize_t len, int *fds, int *fdCount)
240d9f0492fSopenharmony_ci{
241d9f0492fSopenharmony_ci    ssize_t written = 0;
242d9f0492fSopenharmony_ci    ssize_t remain = len;
243d9f0492fSopenharmony_ci    const uint8_t *offset = buf;
244d9f0492fSopenharmony_ci    struct iovec iov = {
245d9f0492fSopenharmony_ci        .iov_base = (void *) offset,
246d9f0492fSopenharmony_ci        .iov_len = len,
247d9f0492fSopenharmony_ci    };
248d9f0492fSopenharmony_ci    struct msghdr msg = {
249d9f0492fSopenharmony_ci        .msg_iov = &iov,
250d9f0492fSopenharmony_ci        .msg_iovlen = 1,
251d9f0492fSopenharmony_ci    };
252d9f0492fSopenharmony_ci    char *ctrlBuffer = NULL;
253d9f0492fSopenharmony_ci    if (fdCount != NULL && fds != NULL && *fdCount > 0) {
254d9f0492fSopenharmony_ci        msg.msg_controllen = CMSG_SPACE(*fdCount * sizeof(int));
255d9f0492fSopenharmony_ci        ctrlBuffer = (char *) malloc(msg.msg_controllen);
256d9f0492fSopenharmony_ci        if (ctrlBuffer == NULL) {
257d9f0492fSopenharmony_ci            printf("WriteMessage fail to alloc memory for msg_control %d %d", msg.msg_controllen, errno);
258d9f0492fSopenharmony_ci            return -1;
259d9f0492fSopenharmony_ci        }
260d9f0492fSopenharmony_ci        msg.msg_control = ctrlBuffer;
261d9f0492fSopenharmony_ci        struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
262d9f0492fSopenharmony_ci        if (cmsg == NULL) {
263d9f0492fSopenharmony_ci            free(ctrlBuffer);
264d9f0492fSopenharmony_ci            printf("WriteMessage fail to get CMSG_FIRSTHDR %d \n", errno);
265d9f0492fSopenharmony_ci            return -1;
266d9f0492fSopenharmony_ci        }
267d9f0492fSopenharmony_ci        cmsg->cmsg_len = CMSG_LEN(*fdCount * sizeof(int));
268d9f0492fSopenharmony_ci        cmsg->cmsg_type = SCM_RIGHTS;
269d9f0492fSopenharmony_ci        cmsg->cmsg_level = SOL_SOCKET;
270d9f0492fSopenharmony_ci        int ret = memcpy_s(CMSG_DATA(cmsg), cmsg->cmsg_len, fds, *fdCount * sizeof(int));
271d9f0492fSopenharmony_ci        if (ret != 0) {
272d9f0492fSopenharmony_ci            free(ctrlBuffer);
273d9f0492fSopenharmony_ci            printf("WriteMessage fail to memcpy_s fd, errno: %d \n", errno);
274d9f0492fSopenharmony_ci            return -1;
275d9f0492fSopenharmony_ci        }
276d9f0492fSopenharmony_ci        printf("build fd info count %d \n", *fdCount);
277d9f0492fSopenharmony_ci    }
278d9f0492fSopenharmony_ci    for (ssize_t wLen = 0; remain > 0; offset += wLen, remain -= wLen, written += wLen) {
279d9f0492fSopenharmony_ci        errno = 0;
280d9f0492fSopenharmony_ci        wLen = sendmsg(socketFd, &msg, MSG_NOSIGNAL);
281d9f0492fSopenharmony_ci        if ((wLen <= 0) || (errno != EINTR)) {
282d9f0492fSopenharmony_ci            free(ctrlBuffer);
283d9f0492fSopenharmony_ci            printf("Failed to write message to fd %d, wLen %zd errno: %d \n", socketFd, wLen, errno);
284d9f0492fSopenharmony_ci            return -errno;
285d9f0492fSopenharmony_ci        }
286d9f0492fSopenharmony_ci    }
287d9f0492fSopenharmony_ci    free(ctrlBuffer);
288d9f0492fSopenharmony_ci    return written == len ? 0 : -EFAULT;
289d9f0492fSopenharmony_ci}
290d9f0492fSopenharmony_ci
291d9f0492fSopenharmony_cistatic int HandleMsgSend(ReqMsgMgr *reqMgr, int socketId, ReqMsgNode *reqNode)
292d9f0492fSopenharmony_ci{
293d9f0492fSopenharmony_ci    printf("HandleMsgSend reqId: %u msgId: %d \n", reqNode->reqId, reqNode->msg->msgId);
294d9f0492fSopenharmony_ci    ListNode *sendNode = reqNode->msgBlocks.next;
295d9f0492fSopenharmony_ci    uint32_t currentIndex = 0;
296d9f0492fSopenharmony_ci    bool sendFd = true;
297d9f0492fSopenharmony_ci    while (sendNode != NULL && sendNode != &reqNode->msgBlocks) {
298d9f0492fSopenharmony_ci        MsgBlock *sendBlock = (MsgBlock *)ListEntry(sendNode, MsgBlock, node);
299d9f0492fSopenharmony_ci        int ret = WriteMessage(socketId, sendBlock->buffer, sendBlock->currentIndex,
300d9f0492fSopenharmony_ci            sendFd ? reqNode->fds : NULL,
301d9f0492fSopenharmony_ci            sendFd ? &reqNode->fdCount : NULL);
302d9f0492fSopenharmony_ci        currentIndex += sendBlock->currentIndex;
303d9f0492fSopenharmony_ci        printf("Write msg ret: %d msgId: %u %u %u \n",
304d9f0492fSopenharmony_ci            ret, reqNode->msg->msgId, reqNode->msg->msgLen, currentIndex);
305d9f0492fSopenharmony_ci        if (ret == 0) {
306d9f0492fSopenharmony_ci            sendFd = false;
307d9f0492fSopenharmony_ci            sendNode = sendNode->next;
308d9f0492fSopenharmony_ci            continue;
309d9f0492fSopenharmony_ci        }
310d9f0492fSopenharmony_ci        printf("Send msg fail reqId: %u msgId: %d ret: %d \n",
311d9f0492fSopenharmony_ci            reqNode->reqId, reqNode->msg->msgId, ret);
312d9f0492fSopenharmony_ci        return ret;
313d9f0492fSopenharmony_ci    }
314d9f0492fSopenharmony_ci    return 0;
315d9f0492fSopenharmony_ci}
316d9f0492fSopenharmony_ci
317d9f0492fSopenharmony_cistatic int ReadMessage(int socketFd, uint32_t sendMsgId, uint8_t *buf, int len, Result *result)
318d9f0492fSopenharmony_ci{
319d9f0492fSopenharmony_ci    int rLen = read(socketFd, buf, len);
320d9f0492fSopenharmony_ci    if (rLen < 0) {
321d9f0492fSopenharmony_ci        printf("Read message from fd %d rLen %d errno: %d \n", socketFd, rLen, errno);
322d9f0492fSopenharmony_ci        return TIMEOUT;
323d9f0492fSopenharmony_ci    }
324d9f0492fSopenharmony_ci
325d9f0492fSopenharmony_ci    if ((size_t)rLen >= sizeof(ResponseMsg)) {
326d9f0492fSopenharmony_ci        ResponseMsg *msg = (ResponseMsg *)(buf);
327d9f0492fSopenharmony_ci        if (sendMsgId != msg->msgHdr.msgId) {
328d9f0492fSopenharmony_ci            printf("Invalid msg recvd %u %u \n", sendMsgId, msg->msgHdr.msgId);
329d9f0492fSopenharmony_ci            return memcpy_s(result, sizeof(Result), &msg->result, sizeof(msg->result));
330d9f0492fSopenharmony_ci        }
331d9f0492fSopenharmony_ci    }
332d9f0492fSopenharmony_ci    return TIMEOUT;
333d9f0492fSopenharmony_ci}
334d9f0492fSopenharmony_ci
335d9f0492fSopenharmony_cistatic int ClientSendMsg(ReqMsgMgr *reqMgr, ReqMsgNode *reqNode, Result *result)
336d9f0492fSopenharmony_ci{
337d9f0492fSopenharmony_ci    uint32_t retryCount = 1;
338d9f0492fSopenharmony_ci    while (retryCount <= reqMgr->maxRetryCount) {
339d9f0492fSopenharmony_ci        if (reqMgr->socketId < 0) { // try create socket
340d9f0492fSopenharmony_ci            TryCreateSocket(reqMgr);
341d9f0492fSopenharmony_ci            if (reqMgr->socketId < 0) {
342d9f0492fSopenharmony_ci                usleep(RETRY_TIME);
343d9f0492fSopenharmony_ci                retryCount++;
344d9f0492fSopenharmony_ci                continue;
345d9f0492fSopenharmony_ci            }
346d9f0492fSopenharmony_ci        }
347d9f0492fSopenharmony_ci
348d9f0492fSopenharmony_ci        if (reqNode->msg->msgId == 0) {
349d9f0492fSopenharmony_ci            reqNode->msg->msgId = reqMgr->msgNextId++;
350d9f0492fSopenharmony_ci        }
351d9f0492fSopenharmony_ci        int ret = HandleMsgSend(reqMgr, reqMgr->socketId, reqNode);
352d9f0492fSopenharmony_ci        if (ret == 0) {
353d9f0492fSopenharmony_ci            ret = ReadMessage(reqMgr->socketId, reqNode->msg->msgId,
354d9f0492fSopenharmony_ci                reqMgr->recvBlock.buffer, reqMgr->recvBlock.blockSize, result);
355d9f0492fSopenharmony_ci        }
356d9f0492fSopenharmony_ci        if (ret == 0) {
357d9f0492fSopenharmony_ci            return 0;
358d9f0492fSopenharmony_ci        }
359d9f0492fSopenharmony_ci        // retry
360d9f0492fSopenharmony_ci        CloseClientSocket(reqMgr->socketId);
361d9f0492fSopenharmony_ci        reqMgr->socketId = -1;
362d9f0492fSopenharmony_ci        reqMgr->msgNextId = 1;
363d9f0492fSopenharmony_ci        reqNode->msg->msgId = 0;
364d9f0492fSopenharmony_ci        usleep(RETRY_TIME);
365d9f0492fSopenharmony_ci        retryCount++;
366d9f0492fSopenharmony_ci    }
367d9f0492fSopenharmony_ci    return TIMEOUT;
368d9f0492fSopenharmony_ci}
369d9f0492fSopenharmony_ci
370d9f0492fSopenharmony_ciint main(int argc, char *const argv[])
371d9f0492fSopenharmony_ci{
372d9f0492fSopenharmony_ci    printf("main argc: %d \n", argc);
373d9f0492fSopenharmony_ci    if (argc <= 0) {
374d9f0492fSopenharmony_ci        return 0;
375d9f0492fSopenharmony_ci    }
376d9f0492fSopenharmony_ci
377d9f0492fSopenharmony_ci    printf("请输入创建socket的类型:(pipe, tcp)\n");
378d9f0492fSopenharmony_ci    char type[128];
379d9f0492fSopenharmony_ci    int ret = scanf_s("%s", type, sizeof(type));
380d9f0492fSopenharmony_ci    if (ret <= 0) {
381d9f0492fSopenharmony_ci        printf("input error \n");
382d9f0492fSopenharmony_ci        return 0;
383d9f0492fSopenharmony_ci    }
384d9f0492fSopenharmony_ci
385d9f0492fSopenharmony_ci    int flags;
386d9f0492fSopenharmony_ci    char *server;
387d9f0492fSopenharmony_ci    if (strcmp(type, "pipe") == 0) {
388d9f0492fSopenharmony_ci        flags = TASK_STREAM | TASK_PIPE |TASK_SERVER | TASK_TEST;
389d9f0492fSopenharmony_ci        server = (char *)"/data/testpipe";
390d9f0492fSopenharmony_ci    } else if (strcmp(type, "tcp") == 0) {
391d9f0492fSopenharmony_ci        flags = TASK_STREAM | TASK_TCP |TASK_SERVER | TASK_TEST;
392d9f0492fSopenharmony_ci        server = (char *)"127.0.0.1:7777";
393d9f0492fSopenharmony_ci    } else {
394d9f0492fSopenharmony_ci        printf("输入有误,请输入pipe或者tcp!");
395d9f0492fSopenharmony_ci        system("pause");
396d9f0492fSopenharmony_ci        return 0;
397d9f0492fSopenharmony_ci    }
398d9f0492fSopenharmony_ci
399d9f0492fSopenharmony_ci    uint32_t timeout = 200;
400d9f0492fSopenharmony_ci    int fd = CreateClientSocket(timeout);
401d9f0492fSopenharmony_ci    return 0;
402d9f0492fSopenharmony_ci}