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 26int _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 47int _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 84void *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 100END: return NULL; 101} 102 103int 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