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
20BDatagramSocket::BDatagramSocket()
21{
22}
23
24
25BDatagramSocket::BDatagramSocket(const BNetworkAddress& peer, bigtime_t timeout)
26{
27	Connect(peer, timeout);
28}
29
30
31BDatagramSocket::BDatagramSocket(const BDatagramSocket& other)
32	:
33	BAbstractSocket(other)
34{
35}
36
37
38BDatagramSocket::~BDatagramSocket()
39{
40}
41
42
43status_t
44BDatagramSocket::Bind(const BNetworkAddress& local, bool reuseAddr)
45{
46	return BAbstractSocket::Bind(local, reuseAddr, SOCK_DGRAM);
47}
48
49
50status_t
51BDatagramSocket::Accept(BAbstractSocket*& _socket)
52{
53	return B_NOT_SUPPORTED;
54}
55
56
57status_t
58BDatagramSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
59{
60	return BAbstractSocket::Connect(peer, SOCK_DGRAM, timeout);
61}
62
63
64status_t
65BDatagramSocket::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
76void
77BDatagramSocket::SetPeer(const BNetworkAddress& peer)
78{
79	fPeer = peer;
80}
81
82
83size_t
84BDatagramSocket::MaxTransmissionSize() const
85{
86	// TODO: might vary on family!
87	return 32768;
88}
89
90
91ssize_t
92BDatagramSocket::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
104ssize_t
105BDatagramSocket::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
121ssize_t
122BDatagramSocket::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
134ssize_t
135BDatagramSocket::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