1 /*
2 * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <DatagramSocket.h>
8
9 #include <errno.h>
10
11
12 //#define TRACE_SOCKET
13 #ifdef TRACE_SOCKET
14 # define TRACE(x...) printf(x)
15 #else
16 # define TRACE(x...) ;
17 #endif
18
19
BDatagramSocket()20 BDatagramSocket::BDatagramSocket()
21 {
22 }
23
24
BDatagramSocket(const BNetworkAddress & peer,bigtime_t timeout)25 BDatagramSocket::BDatagramSocket(const BNetworkAddress& peer, bigtime_t timeout)
26 {
27 Connect(peer, timeout);
28 }
29
30
BDatagramSocket(const BDatagramSocket & other)31 BDatagramSocket::BDatagramSocket(const BDatagramSocket& other)
32 :
33 BAbstractSocket(other)
34 {
35 }
36
37
~BDatagramSocket()38 BDatagramSocket::~BDatagramSocket()
39 {
40 }
41
42
43 status_t
Bind(const BNetworkAddress & local,bool reuseAddr)44 BDatagramSocket::Bind(const BNetworkAddress& local, bool reuseAddr)
45 {
46 return BAbstractSocket::Bind(local, reuseAddr, SOCK_DGRAM);
47 }
48
49
50 status_t
Accept(BAbstractSocket * & _socket)51 BDatagramSocket::Accept(BAbstractSocket*& _socket)
52 {
53 return B_NOT_SUPPORTED;
54 }
55
56
57 status_t
Connect(const BNetworkAddress & peer,bigtime_t timeout)58 BDatagramSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
59 {
60 return BAbstractSocket::Connect(peer, SOCK_DGRAM, timeout);
61 }
62
63
64 status_t
SetBroadcast(bool broadcast)65 BDatagramSocket::SetBroadcast(bool broadcast)
66 {
67 int value = broadcast ? 1 : 0;
68 if (setsockopt(fSocket, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value))
69 != 0)
70 return errno;
71
72 return B_OK;
73 }
74
75
76 void
SetPeer(const BNetworkAddress & peer)77 BDatagramSocket::SetPeer(const BNetworkAddress& peer)
78 {
79 fPeer = peer;
80 }
81
82
83 size_t
MaxTransmissionSize() const84 BDatagramSocket::MaxTransmissionSize() const
85 {
86 // TODO: might vary on family!
87 return 32768;
88 }
89
90
91 ssize_t
SendTo(const BNetworkAddress & address,const void * buffer,size_t size)92 BDatagramSocket::SendTo(const BNetworkAddress& address, const void* buffer,
93 size_t size)
94 {
95 ssize_t bytesSent = sendto(fSocket, buffer, size, 0, address,
96 address.Length());
97 if (bytesSent < 0)
98 return errno;
99
100 return bytesSent;
101 }
102
103
104 ssize_t
ReceiveFrom(void * buffer,size_t bufferSize,BNetworkAddress & from)105 BDatagramSocket::ReceiveFrom(void* buffer, size_t bufferSize,
106 BNetworkAddress& from)
107 {
108 socklen_t fromLength = sizeof(sockaddr_storage);
109 ssize_t bytesReceived = recvfrom(fSocket, buffer, bufferSize, 0,
110 from, &fromLength);
111 if (bytesReceived < 0)
112 return errno;
113
114 return bytesReceived;
115 }
116
117
118 // #pragma mark - BDataIO implementation
119
120
121 ssize_t
Read(void * buffer,size_t size)122 BDatagramSocket::Read(void* buffer, size_t size)
123 {
124 ssize_t bytesReceived = recv(Socket(), buffer, size, 0);
125 if (bytesReceived < 0) {
126 TRACE("%p: BSocket::Read() error: %s\n", this, strerror(errno));
127 return errno;
128 }
129
130 return bytesReceived;
131 }
132
133
134 ssize_t
Write(const void * buffer,size_t size)135 BDatagramSocket::Write(const void* buffer, size_t size)
136 {
137 ssize_t bytesSent;
138
139 if (!fIsConnected)
140 bytesSent = sendto(Socket(), buffer, size, 0, fPeer, fPeer.Length());
141 else
142 bytesSent = send(Socket(), buffer, size, 0);
143
144 if (bytesSent < 0) {
145 TRACE("%p: BDatagramSocket::Write() error: %s\n", this,
146 strerror(errno));
147 return errno;
148 }
149
150 return bytesSent;
151 }
152