1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "netsys_udp_transfer.h"
17 #include "netnative_log_wrapper.h"
18 #include "netsys_client.h"
19
20 namespace OHOS {
21 namespace nmd {
22 namespace {
23 struct UdpBuffer {
24 size_t size;
25 int32_t sock;
26 int16_t event;
27 AlignedSockAddr addr;
28 };
ProcUdpData(UdpBuffer udpBuffer,char * data,socklen_t & lenAddr,int64_t (* func)(int fd,char * buf,size_t len,AlignedSockAddr & addr,socklen_t & lenAddr))29 int32_t ProcUdpData(UdpBuffer udpBuffer, char *data, socklen_t &lenAddr,
30 int64_t (*func)(int fd, char *buf, size_t len, AlignedSockAddr &addr, socklen_t &lenAddr))
31 {
32 char *curPos = data;
33 size_t leftSize = udpBuffer.size;
34 int64_t length = -1;
35 int retry = 0;
36 while (leftSize > 0) {
37 length = func(udpBuffer.sock, curPos, leftSize, udpBuffer.addr, lenAddr);
38 if (length <= 0) {
39 if (errno == EAGAIN && retry < MAX_POLL_RETRY) {
40 ++retry;
41 continue;
42 }
43 return -1;
44 }
45 return length;
46 }
47 return leftSize;
48 }
SendUdpWrapper(int32_t fd,char * buf,size_t len,AlignedSockAddr & addr,socklen_t & lenAddr)49 int64_t SendUdpWrapper(int32_t fd, char *buf, size_t len, AlignedSockAddr &addr, socklen_t &lenAddr)
50 {
51 (void)lenAddr;
52 size_t addrLen = (addr.sa.sa_family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
53 return sendto(fd, buf, len, 0, (sockaddr *)&addr, addrLen);
54 }
RecvUdpWrapper(int32_t fd,char * buf,size_t len,AlignedSockAddr & addr,socklen_t & lenAddr)55 int64_t RecvUdpWrapper(int32_t fd, char *buf, size_t len, AlignedSockAddr &addr, socklen_t &lenAddr)
56 {
57 return recvfrom(fd, buf, len, 0, (sockaddr *)&addr, &lenAddr);
58 }
59 } // namespace
60
MakeUdpNonBlock(int32_t sock)61 bool PollUdpDataTransfer::MakeUdpNonBlock(int32_t sock)
62 {
63 if (sock < 0) {
64 return false;
65 }
66 return MakeNonBlock(sock);
67 }
PollUdpSendData(int32_t sock,char * data,size_t size,AlignedSockAddr & addr,socklen_t & lenAddr)68 int32_t PollUdpDataTransfer::PollUdpSendData(int32_t sock, char *data, size_t size, AlignedSockAddr &addr,
69 socklen_t &lenAddr)
70 {
71 struct UdpBuffer udpBuffer;
72 udpBuffer.size = size;
73 udpBuffer.sock = sock;
74 udpBuffer.event = POLLOUT;
75 udpBuffer.addr = addr;
76 return ProcUdpData(udpBuffer, data, lenAddr, SendUdpWrapper);
77 }
PollUdpRecvData(int32_t sock,char * data,size_t size,AlignedSockAddr & addr,socklen_t & lenAddr)78 int32_t PollUdpDataTransfer::PollUdpRecvData(int32_t sock, char *data, size_t size, AlignedSockAddr &addr,
79 socklen_t &lenAddr)
80 {
81 struct UdpBuffer udpBuffer;
82 udpBuffer.size = size;
83 udpBuffer.sock = sock;
84 udpBuffer.event = POLLIN;
85 udpBuffer.addr = addr;
86 return ProcUdpData(udpBuffer, data, lenAddr, RecvUdpWrapper);
87 }
88 } // namespace nmd
89 } // namespace OHOS