LCOV - code coverage report
Current view: top level - sd/source/ui/remotecontrol - DiscoveryService.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 52 1.9 %
Date: 2014-11-03 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, (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           0 :     multicastRequest.imr_multiaddr.s_addr = inet_addr( "239.0.0.1" );
     126           0 :     multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
     127             : 
     128             :     rc = setsockopt( mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
     129             :     #ifdef WNT
     130             :         (const char*)
     131             :     #endif
     132           0 :         &multicastRequest, sizeof(multicastRequest));
     133             : 
     134           0 :     if (rc)
     135             :     {
     136             :         SAL_WARN("sd", "DiscoveryService: setsockopt failed: " << errno);
     137           0 :         return; // would be better to throw, but unsure if caller handles that
     138             :     }
     139             : }
     140             : 
     141           0 : void SAL_CALL DiscoveryService::run()
     142             : {
     143           0 :     osl::Thread::setName("DiscoveryService");
     144             : 
     145           0 :     setupSockets();
     146             : 
     147             :     // Kept for backwrad compatibility
     148             :     char aBuffer[BUFFER_SIZE];
     149             :     while ( true )
     150             :     {
     151           0 :         memset( aBuffer, 0, sizeof(char) * BUFFER_SIZE );
     152             :         sockaddr_in aAddr;
     153           0 :         socklen_t aLen = sizeof( aAddr );
     154           0 :         if(recvfrom( mSocket, aBuffer, BUFFER_SIZE, 0, (sockaddr*) &aAddr, &aLen ) > 0)
     155             :         {
     156           0 :             OString aString( aBuffer, strlen( "LOREMOTE_SEARCH" ) );
     157           0 :             if ( aString == "LOREMOTE_SEARCH" )
     158             :             {
     159           0 :                 OStringBuffer aStringBuffer("LOREMOTE_ADVERTISE\n");
     160             :                 aStringBuffer.append( OUStringToOString(
     161           0 :                                               osl::SocketAddr::getLocalHostname(), RTL_TEXTENCODING_UTF8 ) )
     162           0 :                     .append( "\n\n" );
     163           0 :                 if ( sendto( mSocket, aStringBuffer.getStr(),
     164           0 :                              aStringBuffer.getLength(), 0, (sockaddr*) &aAddr,
     165           0 :                              sizeof(aAddr) ) <= 0 )
     166             :                 {
     167             :                     // Write error or closed socket -- we are done.
     168           0 :                     return;
     169           0 :                 }
     170           0 :             }
     171             :         }
     172             :         else
     173             :         {
     174             :             // Read error or closed socket -- we are done.
     175           0 :             return;
     176             :         }
     177           0 :     }
     178             : }
     179             : 
     180             : DiscoveryService *sd::DiscoveryService::spService = NULL;
     181             : 
     182           0 : void DiscoveryService::setup()
     183             : {
     184           0 :   if (spService)
     185           0 :     return;
     186             : 
     187           0 :   spService = new DiscoveryService();
     188           0 :   spService->create();
     189         114 : }
     190             : 
     191             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10