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