• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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