tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sd / source / ui / remotecontrol / DiscoveryService.cxx
blobbdd0b51c80020467a680104fb75d8ae82e3b8c43
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <errno.h>
11 #include <string.h>
12 #include <iostream>
14 #include <osl/socket.hxx>
15 #include <config_features.h>
16 #include <sal/log.hxx>
18 #include "DiscoveryService.hxx"
19 #include "ZeroconfService.hxx"
21 #ifdef _WIN32
22 // LO vs WinAPI conflict
23 #undef WB_LEFT
24 #undef WB_RIGHT
26 #include <winsock2.h>
27 #include <ws2tcpip.h>
29 #include "WINNetworkService.hxx"
30 typedef int socklen_t;
31 #else
32 #include <unistd.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #endif
37 #ifdef MACOSX
38 #include <osl/conditn.hxx>
39 #include <premac.h>
40 #import <CoreFoundation/CoreFoundation.h>
41 #include <postmac.h>
42 #import "OSXNetworkService.hxx"
43 #endif
45 #if HAVE_FEATURE_AVAHI
46 #include "AvahiNetworkService.hxx"
47 #endif
49 using namespace osl;
50 using namespace sd;
52 DiscoveryService::DiscoveryService()
53 : mSocket(-1)
54 , zService(nullptr)
58 DiscoveryService::~DiscoveryService()
60 if (mSocket != -1)
62 #ifdef _WIN32
63 closesocket( mSocket );
64 #else
65 close( mSocket );
66 #endif
69 if (zService)
70 zService->clear();
73 void DiscoveryService::setupSockets()
76 #ifdef MACOSX
77 // Bonjour for OSX
78 zService = new OSXNetworkService();
79 zService->setup();
80 #endif
82 #if HAVE_FEATURE_AVAHI
83 // Avahi for Linux
84 char hostname[1024];
85 hostname[1023] = '\0';
86 gethostname(hostname, 1023);
88 zService = new AvahiNetworkService(hostname);
89 zService->setup();
90 #endif
92 #ifdef _WIN32
93 zService = new WINNetworkService();
94 zService->setup();
95 #endif
97 // Old implementation for backward compatibility matter
98 mSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
99 if (mSocket == -1)
101 SAL_WARN("sd", "DiscoveryService: socket failed: " << errno);
102 return; // would be better to throw, but unsure if caller handles that
105 sockaddr_in aAddr = {};
106 aAddr.sin_family = AF_INET;
107 aAddr.sin_addr.s_addr = htonl(INADDR_ANY);
108 aAddr.sin_port = htons( PORT_DISCOVERY );
110 int rc = bind( mSocket, reinterpret_cast<sockaddr*>(&aAddr), sizeof(sockaddr_in) );
112 if (rc)
114 SAL_WARN("sd", "DiscoveryService: bind failed: " << errno);
115 return; // would be better to throw, but unsure if caller handles that
118 struct ip_mreq multicastRequest;
120 multicastRequest.imr_multiaddr.s_addr = htonl((239U << 24) | 1U); // 239.0.0.1
121 multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
123 rc = setsockopt( mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
124 #ifdef _WIN32
125 reinterpret_cast<const char*>(&multicastRequest),
126 #else
127 &multicastRequest,
128 #endif
129 sizeof(multicastRequest));
131 if (rc)
133 SAL_WARN("sd", "DiscoveryService: setsockopt failed: " << errno);
134 return; // would be better to throw, but unsure if caller handles that
138 void SAL_CALL DiscoveryService::run()
140 osl::Thread::setName("DiscoveryService");
142 setupSockets();
144 // Kept for backward compatibility
145 while ( true )
147 char aBuffer[BUFFER_SIZE] = {};
148 sockaddr_in aAddr;
149 socklen_t aLen = sizeof( aAddr );
150 if(recvfrom( mSocket, aBuffer, BUFFER_SIZE, 0, reinterpret_cast<sockaddr*>(&aAddr), &aLen ) > 0)
152 OString aString( aBuffer, strlen( "LOREMOTE_SEARCH" ) );
153 if ( aString == "LOREMOTE_SEARCH" )
155 OString aStringBuffer = "LOREMOTE_ADVERTISE\n" +
156 OUStringToOString(osl::SocketAddr::getLocalHostname(), RTL_TEXTENCODING_UTF8 ) +
157 "\n\n";
158 if ( sendto( mSocket, aStringBuffer.getStr(),
159 aStringBuffer.getLength(), 0, reinterpret_cast<sockaddr*>(&aAddr),
160 sizeof(aAddr) ) <= 0 )
162 // Write error or closed socket -- we are done.
163 return;
167 else
169 // Read error or closed socket -- we are done.
170 return;
175 DiscoveryService *sd::DiscoveryService::spService = nullptr;
177 void DiscoveryService::setup()
179 if (spService)
180 return;
182 spService = new DiscoveryService();
183 spService->create();
186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */