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
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 sockaddr_in addr;
28 };
29
ProcUdpData(UdpBuffer udpBuffer,char * data,socklen_t & lenAddr,int64_t (* func)(int fd,char * buf,size_t len,sockaddr_in addr,socklen_t & lenAddr))30 int32_t ProcUdpData(UdpBuffer udpBuffer, char *data, socklen_t &lenAddr,
31 int64_t (*func)(int fd, char *buf, size_t len, sockaddr_in addr, socklen_t &lenAddr))
32 {
33 char *curPos = data;
34 size_t leftSize = udpBuffer.size;
35 int64_t length = -1;
36 int retry = 0;
37 while (leftSize > 0) {
38 int32_t resPoll = Poll(udpBuffer.sock, udpBuffer.event, &retry);
39 if (resPoll < 0) {
40 return -1;
41 } else if (resPoll == 0) {
42 continue;
43 }
44
45 length = func(udpBuffer.sock, curPos, leftSize, udpBuffer.addr, lenAddr);
46 if (length <= 0) {
47 if (errno == EAGAIN && retry < MAX_POLL_RETRY) {
48 ++retry;
49 continue;
50 }
51 return -1;
52 }
53 return length;
54 }
55 return leftSize;
56 }
57
SendUdpWrapper(int32_t fd,char * buf,size_t len,sockaddr_in addr,socklen_t & lenAddr)58 int64_t SendUdpWrapper(int32_t fd, char *buf, size_t len, sockaddr_in addr, socklen_t &lenAddr)
59 {
60 (void)lenAddr;
61 return sendto(fd, buf, len, 0, (sockaddr *)&addr, sizeof(sockaddr_in));
62 }
63
RecvUdpWrapper(int32_t fd,char * buf,size_t len,sockaddr_in addr,socklen_t & lenAddr)64 int64_t RecvUdpWrapper(int32_t fd, char *buf, size_t len, sockaddr_in addr, socklen_t &lenAddr)
65 {
66 return recvfrom(fd, buf, len, 0, (sockaddr *)&addr, &lenAddr);
67 }
68 }
69
MakeUdpNonBlock(int32_t sock)70 bool PollUdpDataTransfer::MakeUdpNonBlock(int32_t sock)
71 {
72 if (sock < 0) {
73 return false;
74 }
75 return MakeNonBlock(sock);
76 }
77
PollUdpSendData(int32_t sock,char * data,size_t size,sockaddr_in addr,socklen_t & lenAddr)78 int32_t PollUdpDataTransfer::PollUdpSendData(int32_t sock, char *data, size_t size, sockaddr_in addr,
79 socklen_t &lenAddr)
80 {
81 struct UdpBuffer udpBuffer;
82 udpBuffer.size = size;
83 udpBuffer.sock = sock;
84 udpBuffer.event = POLLOUT;
85 udpBuffer.addr = addr;
86 return ProcUdpData(udpBuffer, data, lenAddr, SendUdpWrapper);
87 }
88
PollUdpRecvData(int32_t sock,char * data,size_t size,sockaddr_in addr,socklen_t & lenAddr)89 int32_t PollUdpDataTransfer::PollUdpRecvData(int32_t sock, char *data, size_t size, sockaddr_in addr,
90 socklen_t &lenAddr)
91 {
92 struct UdpBuffer udpBuffer;
93 udpBuffer.size = size;
94 udpBuffer.sock = sock;
95 udpBuffer.event = POLLIN;
96 udpBuffer.addr = addr;
97 return ProcUdpData(udpBuffer, data, lenAddr, RecvUdpWrapper);
98 }
99 } // namespace nmd
100 } // namespace OHOS