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 server.
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
17 #define __USE_GNU
18 #include <sched.h>
19 #include <pthread.h>
20
21 #include "nip_uapi.h"
22 #include "nip_lib.h"
23 #include "newip_route.h"
24
recv_send(void * args)25 static void *recv_send(void *args)
26 {
27 int cfd;
28 ssize_t ret;
29 char buf[BUFLEN] = {0};
30
31 memcpy(&cfd, args, sizeof(int));
32 for (int i = 0; i < PKTCNT; i++) {
33 ssize_t recv_num = recv(cfd, buf, PKTLEN, MSG_WAITALL);
34
35 if (recv_num < 0) {
36 perror("recv");
37 goto END;
38 } else if (recv_num == 0) { /* no data */
39 ;
40 } else {
41 printf("Received -- %s --:%zd\n", buf, recv_num);
42 ret = send(cfd, buf, recv_num, 0);
43 if (ret < 0) {
44 perror("send");
45 goto END;
46 }
47 printf("Sending -- %s --:%zd\n", buf, recv_num);
48 }
49 }
50 END: close(cfd);
51 return NULL;
52 }
53
main(int argc,char ** argv)54 int main(int argc, char **argv)
55 {
56 pthread_t th;
57 int fd, cfd, addr_len;
58 struct sockaddr_nin si_local;
59 struct sockaddr_nin si_remote;
60
61 fd = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP);
62 if (fd < 0) {
63 perror("socket");
64 return -1;
65 }
66
67 memset((char *)&si_local, 0, sizeof(si_local));
68 si_local.sin_family = AF_NINET;
69 si_local.sin_port = htons(TCP_SERVER_PORT);
70 // 2-byte address of the server: 0xDE00
71 si_local.sin_addr.NIP_ADDR_FIELD8[INDEX_0] = 0xDE;
72 si_local.sin_addr.NIP_ADDR_FIELD8[INDEX_1] = 0x00;
73 si_local.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit
74
75 if (bind(fd, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) {
76 perror("bind");
77 goto END;
78 }
79 printf("bind success, addr=0x%02x%02x, port=%d\n",
80 si_local.sin_addr.NIP_ADDR_FIELD8[INDEX_0],
81 si_local.sin_addr.NIP_ADDR_FIELD8[INDEX_1], TCP_SERVER_PORT);
82
83 if (listen(fd, LISTEN_MAX) < 0) {
84 perror("listen");
85 goto END;
86 }
87
88 addr_len = sizeof(si_remote);
89 memset(&si_remote, 0, sizeof(si_remote));
90 cfd = accept(fd, (struct sockaddr *)&si_remote, (socklen_t *)&addr_len);
91 pthread_create(&th, NULL, recv_send, &cfd);
92 /* Wait for the thread to end and synchronize operations between threads */
93 pthread_join(th, NULL);
94 END: close(fd);
95 return 0;
96 }
97
98