• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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