1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
17 #include <comphelper/processfactory.hxx>
18 #include <rtl/strbuf.hxx>
19 #include <config_features.h>
21 #include "DiscoveryService.hxx"
24 // LO vs WinAPI conflict
31 #include "WINNetworkService.hxx"
32 typedef int socklen_t
;
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
42 #include <osl/conditn.hxx>
44 #import <CoreFoundation/CoreFoundation.h>
46 #import "OSXNetworkService.hxx"
49 #if HAVE_FEATURE_AVAHI
50 #include "AvahiNetworkService.hxx"
56 DiscoveryService::DiscoveryService()
62 DiscoveryService::~DiscoveryService()
67 closesocket( mSocket
);
77 void DiscoveryService::setupSockets()
82 zService
= new OSXNetworkService();
85 #if HAVE_FEATURE_AVAHI
88 hostname
[1023] = '\0';
89 gethostname(hostname
, 1023);
91 zService
= new AvahiNetworkService(hostname
);
95 zService
= new WINNetworkService();
101 // Old implementation for backward compatibility matter
102 mSocket
= socket( AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
105 SAL_WARN("sd", "DiscoveryService: socket failed: " << errno
);
106 return; // would be better to throw, but unsure if caller handles that
110 memset(&aAddr
, 0, sizeof(aAddr
));
111 aAddr
.sin_family
= AF_INET
;
112 aAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
113 aAddr
.sin_port
= htons( PORT_DISCOVERY
);
115 int rc
= bind( mSocket
, reinterpret_cast<sockaddr
*>(&aAddr
), sizeof(sockaddr_in
) );
119 SAL_WARN("sd", "DiscoveryService: bind failed: " << errno
);
120 return; // would be better to throw, but unsure if caller handles that
123 struct ip_mreq multicastRequest
;
125 // the Win32 SDK 8.1 deprecates inet_addr()
126 #if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
128 OUString
const saddr("239.0.0.1");
129 INT ret
= InetPtonW(AF_INET
, saddr
.getStr(), & addr
);
132 multicastRequest
.imr_multiaddr
.s_addr
= addr
.S_un
.S_addr
;
135 multicastRequest
.imr_multiaddr
.s_addr
= inet_addr( "239.0.0.1" );
137 multicastRequest
.imr_interface
.s_addr
= htonl(INADDR_ANY
);
139 rc
= setsockopt( mSocket
, IPPROTO_IP
, IP_ADD_MEMBERSHIP
,
143 &multicastRequest
, sizeof(multicastRequest
));
147 SAL_WARN("sd", "DiscoveryService: setsockopt failed: " << errno
);
148 return; // would be better to throw, but unsure if caller handles that
152 void SAL_CALL
DiscoveryService::run()
154 osl::Thread::setName("DiscoveryService");
158 // Kept for backwrad compatibility
159 char aBuffer
[BUFFER_SIZE
];
162 memset( aBuffer
, 0, sizeof(char) * BUFFER_SIZE
);
164 socklen_t aLen
= sizeof( aAddr
);
165 if(recvfrom( mSocket
, aBuffer
, BUFFER_SIZE
, 0, reinterpret_cast<sockaddr
*>(&aAddr
), &aLen
) > 0)
167 OString
aString( aBuffer
, strlen( "LOREMOTE_SEARCH" ) );
168 if ( aString
== "LOREMOTE_SEARCH" )
170 OStringBuffer
aStringBuffer("LOREMOTE_ADVERTISE\n");
171 aStringBuffer
.append( OUStringToOString(
172 osl::SocketAddr::getLocalHostname(), RTL_TEXTENCODING_UTF8
) )
174 if ( sendto( mSocket
, aStringBuffer
.getStr(),
175 aStringBuffer
.getLength(), 0, reinterpret_cast<sockaddr
*>(&aAddr
),
176 sizeof(aAddr
) ) <= 0 )
178 // Write error or closed socket -- we are done.
185 // Read error or closed socket -- we are done.
191 DiscoveryService
*sd::DiscoveryService::spService
= NULL
;
193 void DiscoveryService::setup()
198 spService
= new DiscoveryService();
202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */