LCOV - code coverage report
Current view: top level - sd/source/ui/remotecontrol - DiscoveryService.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1 52 1.9 %
Date: 2015-06-13 12:38:46 Functions: 2 8 25.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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             :  */
       9             : 
      10             : #include <errno.h>
      11             : #include <stdlib.h>
      12             : #include <string.h>
      13             : #include <algorithm>
      14             : #include <vector>
      15             : #include <iostream>
      16             : 
      17             : #include <comphelper/processfactory.hxx>
      18             : #include <rtl/strbuf.hxx>
      19             : #include <config_features.h>
      20             : 
      21             : #include "DiscoveryService.hxx"
      22             : 
      23             : #ifdef WIN32
      24             :   // LO vs WinAPI conflict
      25             :   #undef WB_LEFT
      26             :   #undef WB_RIGHT
      27             : 
      28             :   #include <winsock2.h>
      29             :   #include <ws2tcpip.h>
      30             : 
      31             :   #include "WINNetworkService.hxx"
      32             :   typedef int socklen_t;
      33             : #else
      34             :   #include <unistd.h>
      35             :   #include <sys/types.h>
      36             :   #include <sys/socket.h>
      37             :   #include <netinet/in.h>
      38             :   #include <arpa/inet.h>
      39             : #endif
      40             : 
      41             : #ifdef MACOSX
      42             :   #include <osl/conditn.hxx>
      43             :   #include <premac.h>
      44             :   #import <CoreFoundation/CoreFoundation.h>
      45             :   #include <postmac.h>
      46             :   #import "OSXNetworkService.hxx"
      47             : #endif
      48             : 
      49             : #if HAVE_FEATURE_AVAHI
      50             :   #include "AvahiNetworkService.hxx"
      51             : #endif
      52             : 
      53             : using namespace osl;
      54             : using namespace sd;
      55             : 
      56           0 : DiscoveryService::DiscoveryService()
      57             :     : mSocket(-1)
      58           0 :     , zService(0)
      59             : {
      60           0 : }
      61             : 
      62           0 : DiscoveryService::~DiscoveryService()
      63             : {
      64           0 :     if (mSocket != -1)
      65             :     {
      66             : #ifdef WNT
      67             :         closesocket( mSocket );
      68             : #else
      69           0 :         close( mSocket );
      70             : #endif
      71             :     }
      72             : 
      73           0 :      if (zService)
      74           0 :          zService->clear();
      75           0 : }
      76             : 
      77           0 : void DiscoveryService::setupSockets()
      78             : {
      79             : 
      80             : #ifdef MACOSX
      81             :     // Bonjour for OSX
      82             :     zService = new OSXNetworkService();
      83             : #endif
      84             : 
      85             : #if HAVE_FEATURE_AVAHI
      86             :     // Avahi for Linux
      87             :     char hostname[1024];
      88             :     hostname[1023] = '\0';
      89             :     gethostname(hostname, 1023);
      90             : 
      91             :     zService = new AvahiNetworkService(hostname);
      92             : #endif
      93             : 
      94             : #ifdef WIN32
      95             :     zService = new WINNetworkService();
      96             : #endif
      97             : 
      98           0 :     if (zService)
      99           0 :         zService->setup();
     100             : 
     101             :     // Old implementation for backward compatibility matter
     102           0 :     mSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
     103           0 :     if (mSocket == -1)
     104             :     {
     105             :         SAL_WARN("sd", "DiscoveryService: socket failed: " << errno);
     106           0 :         return; // would be better to throw, but unsure if caller handles that
     107             :     }
     108             : 
     109             :     sockaddr_in aAddr;
     110           0 :     memset(&aAddr, 0, sizeof(aAddr));
     111           0 :     aAddr.sin_family = AF_INET;
     112           0 :     aAddr.sin_addr.s_addr = htonl(INADDR_ANY);
     113           0 :     aAddr.sin_port = htons( PORT_DISCOVERY );
     114             : 
     115           0 :     int rc = bind( mSocket, reinterpret_cast<sockaddr*>(&aAddr), sizeof(sockaddr_in) );
     116             : 
     117           0 :     if (rc)
     118             :     {
     119             :         SAL_WARN("sd", "DiscoveryService: bind failed: " << errno);
     120           0 :         return; // would be better to throw, but unsure if caller handles that
     121             :     }
     122             : 
     123             :     struct ip_mreq multicastRequest;
     124             : 
     125             : // the Win32 SDK 8.1 deprecates inet_addr()
     126             : #if defined(_WIN32_WINNT) &&  _WIN32_WINNT >= _WIN32_WINNT_VISTA
     127             :     IN_ADDR addr;
     128             :     OUString const saddr("239.0.0.1");
     129             :     INT ret = InetPtonW(AF_INET, saddr.getStr(), & addr);
     130             :     if (1 == ret)
     131             :     {
     132             :         multicastRequest.imr_multiaddr.s_addr = addr.S_un.S_addr;
     133             :     }
     134             : #else
     135           0 :     multicastRequest.imr_multiaddr.s_addr = inet_addr( "239.0.0.1" );
     136             : #endif
     137           0 :     multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
     138             : 
     139             :     rc = setsockopt( mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
     140             :     #ifdef WNT
     141             :         (const char*)
     142             :     #endif
     143           0 :         &multicastRequest, sizeof(multicastRequest));
     144             : 
     145           0 :     if (rc)
     146             :     {
     147             :         SAL_WARN("sd", "DiscoveryService: setsockopt failed: " << errno);
     148           0 :         return; // would be better to throw, but unsure if caller handles that
     149             :     }
     150             : }
     151             : 
     152           0 : void SAL_CALL DiscoveryService::run()
     153             : {
     154           0 :     osl::Thread::setName("DiscoveryService");
     155             : 
     156           0 :     setupSockets();
     157             : 
     158             :     // Kept for backwrad compatibility
     159             :     char aBuffer[BUFFER_SIZE];
     160             :     while ( true )
     161             :     {
     162           0 :         memset( aBuffer, 0, sizeof(char) * BUFFER_SIZE );
     163             :         sockaddr_in aAddr;
     164           0 :         socklen_t aLen = sizeof( aAddr );
     165           0 :         if(recvfrom( mSocket, aBuffer, BUFFER_SIZE, 0, reinterpret_cast<sockaddr*>(&aAddr), &aLen ) > 0)
     166             :         {
     167           0 :             OString aString( aBuffer, strlen( "LOREMOTE_SEARCH" ) );
     168           0 :             if ( aString == "LOREMOTE_SEARCH" )
     169             :             {
     170           0 :                 OStringBuffer aStringBuffer("LOREMOTE_ADVERTISE\n");
     171             :                 aStringBuffer.append( OUStringToOString(
     172           0 :                                               osl::SocketAddr::getLocalHostname(), RTL_TEXTENCODING_UTF8 ) )
     173           0 :                     .append( "\n\n" );
     174           0 :                 if ( sendto( mSocket, aStringBuffer.getStr(),
     175           0 :                              aStringBuffer.getLength(), 0, reinterpret_cast<sockaddr*>(&aAddr),
     176           0 :                              sizeof(aAddr) ) <= 0 )
     177             :                 {
     178             :                     // Write error or closed socket -- we are done.
     179           0 :                     return;
     180           0 :                 }
     181           0 :             }
     182             :         }
     183             :         else
     184             :         {
     185             :             // Read error or closed socket -- we are done.
     186           0 :             return;
     187             :         }
     188           0 :     }
     189             : }
     190             : 
     191             : DiscoveryService *sd::DiscoveryService::spService = NULL;
     192             : 
     193           0 : void DiscoveryService::setup()
     194             : {
     195           0 :   if (spService)
     196           0 :     return;
     197             : 
     198           0 :   spService = new DiscoveryService();
     199           0 :   spService->create();
     200          66 : }
     201             : 
     202             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11