DiscoveryUdpKernelName.cpp

Go to the documentation of this file.
00001 /** @file    DiscoveryUdpKernelName.cpp
00002  *  @author  Alessandro Polo
00003  *  @version $Id: DiscoveryUdpKernelName.cpp 3775 2011-01-01 16:38:17Z alex $
00004  *  @brief
00005  * File containing methods for the wosh::bundles::DiscoveryUdpKernelName class.
00006  * The header for this class can be found in DiscoveryUdpKernelName.h, check that file
00007  * for class description.
00008  ****************************************************************************/
00009 /* Copyright (c) 2007-2011, WOSH - Wide Open Smart Home 
00010  * by Alessandro Polo - OpenSmartHome.com
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *     * Redistributions of source code must retain the above copyright
00016  *       notice, this list of conditions and the following disclaimer.
00017  *     * Redistributions in binary form must reproduce the above copyright
00018  *       notice, this list of conditions and the following disclaimer in the
00019  *       documentation and/or other materials provided with the distribution.
00020  *     * Neither the name of the OpenSmartHome.com WOSH nor the
00021  *       names of its contributors may be used to endorse or promote products
00022  *       derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
00025  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
00028  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  ****************************************************************************/
00035 
00036  #include "DiscoveryUdpKernelName.h"
00037  #include <core/Thread.h>
00038  #include <core/Utilities.h>
00039  #include <core/WoshKernel.h>
00040  #include <framework/network/NetworkUtilities.h>
00041  #ifndef DiscoveryUdpKernelName_DynamicSocket
00042  # ifdef WOSH_NETWORK_CSOCKETS
00043  #  include <framework/network/csockets/SocketUdpCS.h>
00044  # endif
00045  #else
00046  # include <core/ObjectFactory.h>
00047  #endif
00048 
00049  
00050 using namespace std;
00051 namespace wosh {
00052  namespace bundles {
00053 
00054 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00055 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00056 
00057 DiscoveryUdpKernelName::DiscoveryUdpKernelName() {
00058     this->timeout = 5000;
00059     this->bind_addressport = _DiscoveryUdpKernelName_DEFAULT_BindAddressPort;
00060     this->target_addresses.push_back(_DiscoveryUdpKernelName_DEFAULT_BroadcastAddressPort);
00061 
00062     Log.setContext( "DiscoveryUdpKernelName" );
00063     Log.setIndent( 2 );
00064     Log.setLevel( LOG_INFO );
00065     
00066  }
00067 
00068 DiscoveryUdpKernelName::~DiscoveryUdpKernelName() {
00069  }
00070 
00071 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00072 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00073 
00074 void DiscoveryUdpKernelName::setBaseKernelName( const std::string& name ) {
00075     this->name_base = name;
00076     WoshKernel::fixName( this->name_base );
00077     Log(LOG_VERBOSE, ":setBaseKernelName(%s) Configured %s", name.c_str(), this->name_base.c_str() );
00078  }
00079 
00080 int DiscoveryUdpKernelName::setTargetAddresses( const std::string& addresses ) {
00081     std::vector<std::string> destinations;
00082     wosh::String::split(destinations, addresses, ";", _String_SPLIT_OPTION_NOT_EMPTY | _String_SPLIT_OPTION_TRIM | _String_SPLIT_OPTION_UNIQUE );
00083     return setTargetAddresses(destinations);
00084  }
00085 
00086 int DiscoveryUdpKernelName::setTargetAddresses( const std::vector<std::string>& destinations ) {
00087     this->target_addresses.clear();
00088     int errors = 0;
00089     std::vector<std::string>::const_iterator it;
00090     for ( it=destinations.begin(); it!=destinations.end(); it++ ) {
00091         if ( wosh::network::NetworkUtilities::isAddressPortValid(*it, true) )
00092             this->target_addresses.push_back(*it, true);
00093         else
00094             ++errors;
00095      }
00096     if ( errors != 0 ) {
00097         Log(LOG_WARNING, ":setTargetAddresses(%s) Configured %d targets [%d errors]", this->target_addresses.size(), errors );
00098         return -errors;
00099      }
00100     Log(LOG_VERBOSE, ":setTargetAddresses(%s) Configured %d targets", this->target_addresses.size() );
00101     return this->target_addresses.size();
00102  }
00103 
00104 
00105 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00106 
00107 WRESULT DiscoveryUdpKernelName::validateNetworkKernelName() {
00108     wosh::network::SocketUdp* socket = NULL;
00109 
00110 #ifdef DiscoveryUdpKernelName_DynamicSocket
00111     Log(LOG_DEBUG, ":validateNetworkKernelName() : Creating 'wosh::network::SocketUdp'" );
00112     socket = ObjectFactory::createTypeOf<wosh::network::SocketUdp>(false);
00113 #elif WOSH_NETWORK_CSOCKETS
00114     Log(LOG_DEBUG, ":validateNetworkKernelName() : Using 'wosh::network::csockets::SocketUdpCS'" );
00115     socket = new wosh::network::csockets::SocketUdpCS();
00116 #endif
00117 
00118     if ( socket == NULL ) {
00119         return WRET_ERR_INTERNAL;
00120      }
00121     socket->setListener(this);
00122     Log(LOG_DEBUG, ":validateNetworkKernelName() : Binding Socket to %s", this->bind_addressport.c_str() );
00123     WRESULT bound = socket->bindSocket(this->bind_addressport, 30000 );
00124     if ( WFAILED(bound) ) {
00125         return WRET_ERR_INTERNAL;
00126      }
00127     Log(LOG_INFO, ":validateNetworkKernelName() : Discovering Neighbours.." );
00128     long timet = this->timeout/500; int ret = 0; int send_cnt = 5;
00129     VectorT<std::string>::ConstIterator it;
00130     while( --timet > 0 ) {
00131         if ( --send_cnt > 0 ) {
00132             for( it=target_addresses.begin(); it!=target_addresses.end(); ++it ) {
00133                 Log(LOG_DEBUG, ":validateNetworkKernelName() : Broadcasting to %s", (*it).c_str() );
00134                 ret = socket->sendDatagram( *it, this->request.data(), this->request.size() );
00135              }
00136          }
00137         ThreadImpl::sleepForMSec(500);
00138      }
00139     socket->unbindSocket();
00140 
00141 #ifdef DiscoveryUdpKernelName_DynamicSocket
00142     ObjectFactory::destroy(socket); socket = NULL;
00143 #else
00144     delete socket; socket = NULL;
00145 #endif
00146 
00147     Log(LOG_DEBUG, ":validateNetworkKernelName() : Validating name %s against %d known hosts", this->name_base.c_str(), this->names_found.size() );
00148     this->name_final = this->name_base; int i = 0;
00149     while( this->names_found.exists(this->name_final) ) {
00150         this->name_final = this->name_base + String::toString(++i);
00151      }
00152 
00153     if ( this->names_found.exists(this->name_final) ) {
00154         Log(LOG_WARNING, ":validateNetworkKernelName() : NOT Validated name %s against %d known hosts", this->name_final.c_str(), this->names_found.size() );
00155         return WRET_ERR_INTERNAL;
00156      }
00157     Log(LOG_INFO, ":validateNetworkKernelName() : Validated name %s", this->name_final.c_str() );
00158     return WRET_OK;
00159  }
00160 
00161 ///////////////////////////////////////////////////////////////////////////////////////////////////// METHODS
00162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00163 
00164 void DiscoveryUdpKernelName::udpIncomingDatagram( const char* data, int maxSize, const std::string& source, wosh::network::SocketUdp* ) {
00165     if ( maxSize == this->request.size() ) {
00166         // unprotected access to this->request is ok since noone is supposed to edit the object
00167         if ( strncmp(data, this->request.data(), maxSize) == 0 )
00168             return;
00169      }
00170 /*
00171     DiscoveryUdpMessage message;
00172     // parse the datagram into temporary representation
00173     WRESULT loaded = message.loadFrom(data, maxSize);
00174     if ( WFAILED(loaded) ) {
00175         Log(LOG_WARNING, ":validateNetworkKernelName() : FAILED#%d loading message from %s [%d bytes]", loaded, source.c_str(), maxSize );
00176         return;
00177      }
00178 
00179     Log(LOG_DEBUG, ":validateNetworkKernelName() : Adding Neighbours of %s..", message.getKernelName().c_str() );
00180     this->names_found.push_back( message.getKernelName(), true );
00181     std::map<std::string, long> neighb;
00182     message.getNeighbours(neighb);
00183     std::map<std::string, long>::const_iterator it;
00184     for ( it=neighb.begin(); it!=neighb.end(); ++it )
00185         this->names_found.push_back(it->first, true );
00186 */
00187  }
00188 
00189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00191 
00192 WRESULT DiscoveryUdpKernelName::doNameDiscovery( std::string& woshName ) {
00193 
00194     DiscoveryUdpKernelName dkn;
00195     dkn.setBaseKernelName(woshName);
00196     dkn.validateNetworkKernelName();
00197     woshName = dkn.getNameFinal();
00198 
00199     return WRET_OK;
00200  }
00201 
00202  }; // namespace bundles
00203 }; // namespace wosh

Generated on Tue Feb 8 2011 09:32:51 for WOSH system 0.8.888 [wolf] by Alessandro Polo, using DoxyGen 1.7.2 hosted by WOSH Framework