Fix a conflict with Audio Hijack in JackCoreAudioDriver.
[jack2.git] / posix / JackNetUnixSocket.cpp
blob301e4bc547ac4ec94206ef0b4439c6055918b3e8
1 /*
2 Copyright (C) 2008 Romain Moret at Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "JackNetUnixSocket.h"
22 namespace Jack
24 //utility *********************************************************************************************************
25 int GetHostName ( char * name, int size )
27 if ( gethostname ( name, size ) == SOCKET_ERROR )
29 jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) );
30 strcpy ( name, "default" );
31 return SOCKET_ERROR;
33 return 0;
36 //construct/destruct***********************************************************************************************
37 JackNetUnixSocket::JackNetUnixSocket()
39 fSockfd = 0;
40 fPort = 0;
41 fSendAddr.sin_family = AF_INET;
42 fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
43 memset ( &fSendAddr.sin_zero, 0, 8 );
44 fRecvAddr.sin_family = AF_INET;
45 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
46 memset ( &fRecvAddr.sin_zero, 0, 8 );
49 JackNetUnixSocket::JackNetUnixSocket ( const char* ip, int port )
51 fSockfd = 0;
52 fPort = port;
53 fSendAddr.sin_family = AF_INET;
54 fSendAddr.sin_port = htons ( port );
55 inet_aton ( ip, &fSendAddr.sin_addr );
56 memset ( &fSendAddr.sin_zero, 0, 8 );
57 fRecvAddr.sin_family = AF_INET;
58 fRecvAddr.sin_port = htons ( port );
59 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
60 memset ( &fRecvAddr.sin_zero, 0, 8 );
63 JackNetUnixSocket::JackNetUnixSocket ( const JackNetUnixSocket& socket )
65 fSockfd = 0;
66 fPort = socket.fPort;
67 fSendAddr = socket.fSendAddr;
68 fRecvAddr = socket.fRecvAddr;
71 JackNetUnixSocket::~JackNetUnixSocket()
73 Close();
76 JackNetUnixSocket& JackNetUnixSocket::operator= ( const JackNetUnixSocket& socket )
78 if ( this != &socket )
80 fSockfd = 0;
81 fPort = socket.fPort;
82 fSendAddr = socket.fSendAddr;
83 fRecvAddr = socket.fRecvAddr;
85 return *this;
88 //socket***********************************************************************************************************
89 int JackNetUnixSocket::NewSocket()
91 if ( fSockfd )
93 Close();
94 Reset();
96 fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 );
97 return fSockfd;
100 int JackNetUnixSocket::Bind()
102 return bind ( fSockfd, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), sizeof ( socket_address_t ) );
105 int JackNetUnixSocket::BindWith ( const char* ip )
107 int addr_conv = inet_aton ( ip, &fRecvAddr.sin_addr );
108 if ( addr_conv < 0 )
109 return addr_conv;
110 return Bind();
113 int JackNetUnixSocket::BindWith ( int port )
115 fRecvAddr.sin_port = htons ( port );
116 return Bind();
119 int JackNetUnixSocket::Connect()
121 return connect ( fSockfd, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) );
124 int JackNetUnixSocket::ConnectTo ( const char* ip )
126 int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
127 if ( addr_conv < 0 )
128 return addr_conv;
129 return Connect();
132 void JackNetUnixSocket::Close()
134 if ( fSockfd )
135 close ( fSockfd );
136 fSockfd = 0;
139 void JackNetUnixSocket::Reset()
141 fSendAddr.sin_family = AF_INET;
142 fSendAddr.sin_port = htons ( fPort );
143 fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
144 memset ( &fSendAddr.sin_zero, 0, 8 );
145 fRecvAddr.sin_family = AF_INET;
146 fRecvAddr.sin_port = htons ( fPort );
147 fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY );
148 memset ( &fRecvAddr.sin_zero, 0, 8 );
151 bool JackNetUnixSocket::IsSocket()
153 return ( fSockfd ) ? true : false;
156 //IP/PORT***********************************************************************************************************
157 void JackNetUnixSocket::SetPort ( int port )
159 fPort = port;
160 fSendAddr.sin_port = htons ( port );
161 fRecvAddr.sin_port = htons ( port );
164 int JackNetUnixSocket::GetPort()
166 return fPort;
169 //address***********************************************************************************************************
170 int JackNetUnixSocket::SetAddress ( const char* ip, int port )
172 int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
173 if ( addr_conv < 0 )
174 return addr_conv;
175 fSendAddr.sin_port = htons ( port );
176 return 0;
179 char* JackNetUnixSocket::GetSendIP()
181 return inet_ntoa ( fSendAddr.sin_addr );
184 char* JackNetUnixSocket::GetRecvIP()
186 return inet_ntoa ( fRecvAddr.sin_addr );
189 //utility************************************************************************************************************
190 int JackNetUnixSocket::GetName ( char* name )
192 return gethostname ( name, 255 );
195 int JackNetUnixSocket::JoinMCastGroup ( const char* ip )
197 struct ip_mreq multicast_req;
198 inet_aton ( ip, &multicast_req.imr_multiaddr );
199 multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY );
200 return SetOption ( IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof ( multicast_req ) );
203 //options************************************************************************************************************
204 int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen )
206 return setsockopt ( fSockfd, level, optname, optval, optlen );
209 int JackNetUnixSocket::GetOption ( int level, int optname, void* optval, socklen_t* optlen )
211 return getsockopt ( fSockfd, level, optname, optval, optlen );
214 //timeout************************************************************************************************************
215 int JackNetUnixSocket::SetTimeOut ( int us )
217 jack_log ( "JackNetUnixSocket::SetTimeout %d usecs", us );
219 //negative timeout, or exceding 10s, return
220 if ( ( us < 0 ) || ( us > 10000000 ) )
221 return SOCKET_ERROR;
222 struct timeval timeout;
224 //less than 1sec
225 if ( us < 1000000 )
227 timeout.tv_sec = 0;
228 timeout.tv_usec = us;
230 //more than 1sec
231 else
233 float sec = static_cast<float> ( us ) / 1000000.f;
234 timeout.tv_sec = ( int ) sec;
235 float usec = ( sec - static_cast<float> ( timeout.tv_sec ) ) * 1000000;
236 timeout.tv_usec = ( int ) usec;
238 return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) );
241 //local loop**********************************************************************************************************
242 int JackNetUnixSocket::SetLocalLoop()
244 char disable = 0;
245 return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) );
248 //network operations**************************************************************************************************
249 int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags )
251 return sendto ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) );
254 int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip )
256 int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr );
257 if ( addr_conv < 1 )
258 return addr_conv;
259 return SendTo ( buffer, nbytes, flags );
262 int JackNetUnixSocket::Send ( const void* buffer, size_t nbytes, int flags )
264 return send ( fSockfd, buffer, nbytes, flags );
267 int JackNetUnixSocket::RecvFrom ( void* buffer, size_t nbytes, int flags )
269 socklen_t addr_len = sizeof ( socket_address_t );
270 return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), &addr_len );
273 int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags )
275 return recv ( fSockfd, buffer, nbytes, flags );
278 int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags )
280 socklen_t addr_len = sizeof ( socket_address_t );
281 return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len );
284 net_error_t JackNetUnixSocket::GetError()
286 switch ( errno )
288 case EAGAIN:
289 return NET_NO_DATA;
290 case ECONNABORTED:
291 return NET_CONN_ERROR;
292 case EINVAL:
293 return NET_CONN_ERROR;
294 case ECONNREFUSED:
295 return NET_CONN_ERROR;
296 case ECONNRESET:
297 return NET_CONN_ERROR;
298 case EHOSTDOWN:
299 return NET_CONN_ERROR;
300 case EHOSTUNREACH:
301 return NET_CONN_ERROR;
302 default:
303 return NET_OP_ERROR;