00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "OverlayBootstrap.h"
00040
00041 #include "BaseOverlay.h"
00042 #include "ariba/utility/bootstrap/modules/bluetoothsdp/BluetoothSdp.h"
00043
00044 using ariba::utility::BluetoothSdp;
00045
00046 namespace ariba {
00047 namespace overlay {
00048
00049 use_logging_cpp(OverlayBootstrap);
00050 SystemEventType OverlayBootstrapMethodType("OverlayBootstrapMethodType");
00051
00052 OverlayBootstrap::OverlayBootstrap()
00053 : manager( BootstrapManager::instance() ),
00054 spovnetid( SpoVNetID::UNSPECIFIED ),
00055 nodeid( NodeID::UNSPECIFIED ),
00056 overlay( NULL ),
00057 watchtimer(this),
00058 haveOverlayConnection(false){
00059
00060 srand(time(NULL));
00061
00062 BluetoothSdp::CONNECTION_CHECKER = this;
00063 }
00064
00065 OverlayBootstrap::~OverlayBootstrap(){
00066 }
00067
00068 void OverlayBootstrap::start(BaseOverlay* _overlay, const SpoVNetID& _spovnetid, const NodeID& _nodeid){
00069 overlay = _overlay;
00070 spovnetid = _spovnetid;
00071 nodeid = _nodeid;
00072
00073 logging_info("starting overlay bootstrap");
00074
00075 manager.registerCallback( this );
00076 manager.registerModule( BootstrapManager::BootstrapTypePeriodicBroadcast );
00077 manager.registerModule( BootstrapManager::BootstrapTypeBluetoothSdp );
00078
00079 watchtimer.startWatchdog();
00080 }
00081
00082 void OverlayBootstrap::stop(){
00083 overlay = NULL;
00084 spovnetid = SpoVNetID::UNSPECIFIED;
00085 nodeid = NodeID::UNSPECIFIED;
00086
00087 logging_info("stopping overlay bootstrap");
00088
00089 manager.unregisterCallback( this );
00090 manager.unregisterModule( BootstrapManager::BootstrapTypePeriodicBroadcast );
00091 manager.unregisterModule( BootstrapManager::BootstrapTypeBluetoothSdp );
00092
00093 watchtimer.stopWatchdog();
00094 }
00095
00096 void OverlayBootstrap::handleSystemEvent(const SystemEvent& event){
00097 JoinData* data = event.getData<JoinData>();
00098
00099
00100 logging_info( "found bootstrap node for our SpoVNetID " << data->spovnetid.toString()
00101 << " on NodeID " << data->nodeid.toString() << " with endpoint " << data->endpoint.toString() );
00102
00103
00104 assert( overlay != NULL );
00105 overlay->joinSpoVNet( spovnetid, data->endpoint );
00106
00107 delete data;
00108 }
00109
00110 void OverlayBootstrap::onBootstrapServiceFound(string name, string info1, string info2, string info3){
00111 if( overlay == NULL ) return;
00112 if(name.length() <= 0 || info1.length() <= 0 || info2.length() <= 0 || info3.length() <= 0) return;
00113
00114
00115
00116
00117
00118 SpoVNetID sid( info1 );
00119 NodeID nid( info2 );
00120 EndpointDescriptor ep( info3 );
00121
00122
00123
00124
00125
00126
00127 if( sid != this->spovnetid ) return;
00128
00129
00130
00131 if( nid == this->nodeid ) return;
00132
00133
00134
00135
00136
00137
00138 JoinData* data = new JoinData();
00139 data->spovnetid = sid;
00140 data->nodeid = nid;
00141 data->endpoint = ep;
00142
00143 SystemQueue::instance().scheduleEvent(
00144 SystemEvent( this, OverlayBootstrapMethodType, data), 0 );
00145 }
00146
00147 void OverlayBootstrap::publish(const EndpointDescriptor& _ep){
00148
00149 ostringstream r;
00150 r << std::hex << rand();
00151
00152 randname = r.str();
00153 manager.publish( randname, spovnetid.toString(), nodeid.toString(), _ep.toString() );
00154 }
00155
00156 void OverlayBootstrap::revoke(){
00157 manager.revoke( randname );
00158 }
00159
00160 void OverlayBootstrap::recordJoin(const EndpointDescriptor& _ep){
00161 boost::mutex::scoped_lock lock(lastJoinesMutex);
00162
00163 JoinData data;
00164 data.spovnetid = spovnetid;
00165 data.nodeid = nodeid;
00166 data.endpoint = _ep;
00167
00168 logging_info("recording bootstrap information " << data.endpoint.toString());
00169
00170 lastJoines.push_front(data);
00171 }
00172
00173 bool OverlayBootstrap::haveOverlayConnections(){
00174 boost::mutex::scoped_lock lock(haveOverlayConnectionMutex);
00175 return haveOverlayConnection;
00176 }
00177
00178 void OverlayBootstrap::checkOverlayStatus(){
00179
00180
00181
00182
00183 {
00184 boost::mutex::scoped_lock lock(lastJoinesMutex);
00185 while(lastJoines.size() > 10)
00186 lastJoines.pop_back();
00187 }
00188
00189 {
00190 boost::mutex::scoped_lock lock(haveOverlayConnectionMutex);
00191 haveOverlayConnection = overlay->getOverlayNeighbors().size() > 0;
00192
00193
00194 if(haveOverlayConnection > 0) return;
00195 }
00196
00197
00198 logging_info("overlay not joined, checking for earlier used bootstrap information");
00199 EndpointDescriptor joinep = EndpointDescriptor::UNSPECIFIED();
00200
00201
00202
00203 JoinData data;
00204 {
00205 boost::mutex::scoped_lock lock(lastJoinesMutex);
00206 JoinStack::iterator i = lastJoines.begin();
00207 if(i == lastJoines.end()) return;
00208
00209
00210 joinep = (*i).endpoint;
00211
00212 if(lastJoines.size() >= 2)
00213 swap( *lastJoines.begin(), *(--(lastJoines.end())) );
00214 }
00215
00216 logging_info("no overlay conenctivity detected, " <<
00217 "trying to join using old bootstrap information: " <<
00218 joinep.toString());
00219
00220
00221
00222 overlay->joinSpoVNet( spovnetid, joinep );
00223 }
00224
00225 OverlayBootstrap::WatchdogTimer::WatchdogTimer(OverlayBootstrap* _obj) : obj(_obj) {
00226 }
00227
00228 void OverlayBootstrap::WatchdogTimer::startWatchdog(){
00229 Timer::setInterval(5000);
00230 Timer::start();
00231 }
00232
00233 void OverlayBootstrap::WatchdogTimer::stopWatchdog(){
00234 Timer::stop();
00235 }
00236
00237 void OverlayBootstrap::WatchdogTimer::eventFunction(){
00238 if(obj == NULL) return;
00239 obj->checkOverlayStatus();
00240 }
00241
00242 }}