• 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 udp 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 
18 #define __USE_GNU
19 #include <sched.h>
20 #include <pthread.h>
21 
22 #include "nip_uapi.h"
23 #include "nip_lib.h"
24 #include "newip_route.h"
25 
_sendto(int cfd,struct sockaddr_nin * si_server,int pkt_num)26 int _sendto(int cfd, struct sockaddr_nin *si_server, int pkt_num)
27 {
28 	char buf[BUFLEN] = {0};
29 	struct timeval sys_time;
30 	socklen_t slen = sizeof(struct sockaddr_nin);
31 	int ret;
32 
33 	gettimeofday(&sys_time, NULL);
34 	ret = sprintf(buf, "%ld %6ld NIP_UDP # %6d", sys_time.tv_sec, sys_time.tv_usec, pkt_num);
35 	if (ret < 0) {
36 		printf("sprintf failed");
37 		return -1;
38 	}
39 	if (sendto(cfd, buf, BUFLEN, 0, (struct sockaddr *)si_server, slen) < 0) {
40 		printf("client sendto fail, pkt_num=%d", pkt_num);
41 		return -1;
42 	}
43 
44 	return 0;
45 }
46 
_recvfrom(int cfd,struct sockaddr_nin * si_server,int pkt_num,int * success)47 int _recvfrom(int cfd, struct sockaddr_nin *si_server, int pkt_num, int *success)
48 {
49 	char buf[BUFLEN] = {0};
50 	fd_set readfds;
51 	int tmp;
52 	struct timeval tv;
53 	socklen_t slen = sizeof(struct sockaddr_nin);
54 
55 	FD_ZERO(&readfds);
56 	FD_SET(cfd, &readfds);
57 	tv.tv_sec = TIMEOUT_SEC;
58 	tv.tv_usec = 0;
59 	if (select(cfd + 1, &readfds, NULL, NULL, &tv) < 0) {
60 		printf("client select fail, pkt_num=%d", pkt_num);
61 		return -1;
62 	}
63 
64 	if (FD_ISSET(cfd, &readfds)) {
65 		int ret;
66 		int no = 0;
67 
68 		ret = recvfrom(cfd, buf, BUFLEN, 0, (struct sockaddr *)si_server, &slen);
69 		if (ret > 0) {
70 			*success += 1;
71 			ret = sscanf(buf, "%d %d NIP_UDP # %d", &tmp, &tmp, &no);
72 			if (ret)
73 				printf("Received --%s sock %d success:%6d/%6d/no=%6d\n",
74 				       buf, cfd, *success, pkt_num + 1, no);
75 		} else {
76 			printf("client recvfrom fail, ret=%d\n", ret);
77 			return -1;
78 		}
79 	}
80 
81 	return 0;
82 }
83 
send_recv(void * args)84 void *send_recv(void *args)
85 {
86 	int success = 0;
87 	int cfd = ((struct thread_args *)args)->cfd;
88 	struct sockaddr_nin si_server = ((struct thread_args *)args)->si_server;
89 
90 	for (int i = 0; i < PKTCNT; i++) {
91 		if (_sendto(cfd, &si_server, i) != 0)
92 			goto END;
93 
94 		if (_recvfrom(cfd, &si_server, i, &success) != 0)
95 			goto END;
96 
97 		usleep(SLEEP_US);
98 	}
99 
100 END:	return NULL;
101 }
102 
main(int argc,char ** argv)103 int main(int argc, char **argv)
104 {
105 	pthread_t th;
106 	int cfd;
107 	struct thread_args th_args;
108 	struct sockaddr_nin si_server;
109 
110 	cfd = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP);
111 	if (cfd < 0) {
112 		perror("socket");
113 		return -1;
114 	}
115 
116 	memset((char *)&si_server, 0, sizeof(si_server));
117 	si_server.sin_family = AF_NINET;
118 	si_server.sin_port = htons(UDP_SERVER_PORT);
119 	// 2-byte address of the server: 0xDE00
120 	si_server.sin_addr.NIP_ADDR_FIELD8[INDEX_0] = 0xDE;
121 	si_server.sin_addr.NIP_ADDR_FIELD8[INDEX_1] = 0x00;
122 	si_server.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit
123 
124 	th_args.si_server = si_server;
125 	th_args.si_server.sin_port = htons(UDP_SERVER_PORT);
126 	th_args.cfd = cfd;
127 	pthread_create(&th, NULL, send_recv, &th_args);
128 	/* Wait for the thread to end and synchronize operations between threads */
129 	pthread_join(th, NULL);
130 	close(cfd);
131 	return 0;
132 }
133 
134