1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2022 Huawei Device Co., Ltd.
4 *
5 * Description: Demo example of NewIP tcp client.
6 *
7 * Author: Yang Yanjun <yangyanjun@huawei.com>
8 *
9 * Data: 2022-09-06
10 */
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <arpa/inet.h>
15 #include <sys/socket.h>
16 #include <sys/time.h>
17 #include <sys/socket.h>
18
19 #include "nip_uapi.h"
20 #include "nip_lib.h"
21 #include "newip_route.h"
22
23 #define __USE_GNU
24 #include <sched.h>
25 #include <pthread.h>
26
_send(int cfd,int pkt_num)27 static int _send(int cfd, int pkt_num)
28 {
29 char buf[BUFLEN] = {0};
30 struct timeval sys_time;
31 int ret;
32
33 gettimeofday(&sys_time, NULL);
34 ret = sprintf(buf, "%ld %6ld NIP_TCP # %6d", sys_time.tv_sec, sys_time.tv_usec, pkt_num);
35 if (ret < 0) {
36 printf("sprintf failed\n");
37 return -1;
38 }
39 if (send(cfd, buf, PKTLEN, 0) < 0) {
40 perror("sendto");
41 return -1;
42 }
43
44 return 0;
45 }
46
_recv(int cfd,int pkt_num,int * success)47 static int _recv(int cfd, int pkt_num, int *success)
48 {
49 char buf[BUFLEN] = {0};
50 fd_set readfds;
51 int tmp;
52 struct timeval tv;
53
54 FD_ZERO(&readfds);
55 FD_SET(cfd, &readfds);
56 tv.tv_sec = TIMEOUT_SEC;
57 tv.tv_usec = 0;
58 if (select(cfd + 1, &readfds, NULL, NULL, &tv) < 0) {
59 perror("select");
60 return -1;
61 }
62
63 if (FD_ISSET(cfd, &readfds)) {
64 ssize_t ret;
65 int no = 0;
66
67 ret = recv(cfd, buf, PKTLEN, MSG_WAITALL);
68 if (ret > 0) {
69 *success += 1;
70 ret = sscanf(buf, "%d %d NIP_TCP # %d", &tmp, &tmp, &no);
71 if (ret <= 0) {
72 perror("sscanf");
73 return -1;
74 }
75 printf("Received --%s sock %d success:%6d/%6d/no=%6d\n",
76 buf, cfd, *success, pkt_num + 1, no);
77 } else {
78 printf("recv fail, ret=%zd\n", ret);
79 return -1;
80 }
81 }
82
83 return 0;
84 }
85
send_recv(void * args)86 static void *send_recv(void *args)
87 {
88 int cfd = ((struct thread_args *)args)->cfd;
89 int success = 0;
90
91 for (int i = 0; i < PKTCNT; i++) {
92 if (_send(cfd, i) != 0)
93 goto END;
94
95 if (_recv(cfd, i, &success) != 0)
96 goto END;
97
98 usleep(SLEEP_US);
99 }
100
101 END: return NULL;
102 }
103
main(int argc,char ** argv)104 int main(int argc, char **argv)
105 {
106 int cfd;
107 pthread_t th;
108 struct thread_args th_args;
109 struct sockaddr_nin si_server;
110
111 cfd = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP);
112 if (cfd < 0) {
113 perror("socket");
114 return -1;
115 }
116 printf("creat newip socket, fd=%d\n", cfd);
117
118 memset((char *)&si_server, 0, sizeof(si_server));
119 si_server.sin_family = AF_NINET;
120 si_server.sin_port = htons(TCP_SERVER_PORT);
121 // 2-byte address of the server: 0xDE00
122 si_server.sin_addr.NIP_ADDR_FIELD8[INDEX_0] = 0xDE;
123 si_server.sin_addr.NIP_ADDR_FIELD8[INDEX_1] = 0x00;
124 si_server.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit
125 if (connect(cfd, (struct sockaddr *)&si_server, sizeof(si_server)) < 0) {
126 perror("connect");
127 return -1;
128 }
129 printf("connect success, addr=0x%02x%02x, port=%d\n",
130 si_server.sin_addr.NIP_ADDR_FIELD8[INDEX_0],
131 si_server.sin_addr.NIP_ADDR_FIELD8[INDEX_1], TCP_SERVER_PORT);
132
133 th_args.si_server = si_server;
134 th_args.si_server.sin_port = htons(TCP_SERVER_PORT);
135 th_args.cfd = cfd;
136 pthread_create(&th, NULL, send_recv, &th_args);
137 /* Wait for the thread to end and synchronize operations between threads */
138 pthread_join(th, NULL);
139 close(cfd);
140 return 0;
141 }
142
143