source: source/ariba/Node.cpp@ 12755

Last change on this file since 12755 was 12350, checked in by s_taenzer@…, 11 years ago

Logging: Properly enable logging with Log4Cxx in Node

File size: 13.3 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OF TELEMATICS OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#include "Node.h"
40
41#include <boost/foreach.hpp>
42
43#include "ariba/overlay/BaseOverlay.h"
44#include "ariba/communication/BaseCommunication.h"
45
46#include "ariba/utility/types/OverlayParameterSet.h"
47#include "ariba/communication/EndpointDescriptor.h"
48
49#include <boost/property_tree/exceptions.hpp>
50
51using namespace std;
52using ariba::communication::EndpointDescriptor;
53using boost::property_tree::ptree;
54
55namespace ariba {
56
57use_logging_cpp(Node);
58
59//Node::Node(AribaModule& ariba_mod, const Name& node_name) :
60// name(node_name), ariba_mod(ariba_mod) {
61// base_overlay = new BaseOverlay();
62//}
63
64Node::Node() :
65 name(Name::UNSPECIFIED),
66 base_communication(NULL),
67 base_overlay(NULL)
68{
69 base_communication = new BaseCommunication();
70 base_overlay = new BaseOverlay();
71}
72
73Node::~Node() {
74 delete base_overlay;
75 base_overlay = NULL;
76
77 delete base_communication;
78 base_communication = NULL;
79}
80
81void Node::connect(const ptree& config)
82{
83 using namespace boost::property_tree;
84 using namespace addressing2;
85
86 assert( ! base_communication->isStarted() );
87 assert( ! base_overlay->isStarted() );
88
89 // XXX needed since »empty_ptree<ptree>()« is not working
90 // ---> see: http://stackoverflow.com/questions/5003549/where-is-boost-property-treeempty-ptree
91 static const ptree empty_pt;
92
93 // SpovNet ID
94 Name spovnet_name(config.get<string>("spovnet_name"));
95 spovnetId = spovnet_name.toSpoVNetId();
96
97 // Node ID
98 try
99 {
100 name = config.get<string>("node_name");
101 }
102 catch ( ptree_bad_path& e )
103 {
104 name = Name::UNSPECIFIED;
105 }
106 nodeId = generateNodeId(name);
107
108
109
110 /* Base Communication */
111 EndpointSetPtr listen_on;
112 try
113 {
114 listen_on = endpoint_set::create_EndpointSet(
115 config.get_child("listen_on"));
116 }
117 catch ( ptree_bad_path& e )
118 {
119 /* no endpoints specified, using default: »[::]:41322+« */
120
121 ptree default_listen_on;
122 default_listen_on.put("endp.category", "TCPIP");
123 default_listen_on.put("endp.addr", "::");
124 default_listen_on.put("endp.port", 0); // defaults to 41322 (or higher)
125
126 listen_on = endpoint_set::create_EndpointSet(default_listen_on);
127// logging_warn("No endpoints specified in config. ---> Using default.");
128 cout << "No endpoints specified in config. ---> Using default." << endl;
129 }
130 base_communication->start(listen_on);
131
132 // TODO maybe notify the upper layer whether we have any active endpoints
133
134
135 /* Base Overlay */
136 base_overlay->start( base_communication, nodeId );
137
138 base_overlay->createSpoVNet( spovnetId );
139 base_overlay->joinSpoVNet( spovnetId );
140
141
142
143 /* Bootstrap */
144 const ptree& bootstrap_pt = config.get_child("bootstrap", empty_pt);
145
146 // Static Bootstrap
147 try
148 {
149 // read endpoint_set from config
150 EndpointSetPtr ep_set = endpoint_set::create_EndpointSet(
151 bootstrap_pt.get_child("direct"));
152
153 EndpointDescriptor ep = EndpointDescriptor::UNSPECIFIED();
154 ep.replace_endpoint_set(ep_set);
155
156 // try to connect
157 base_overlay->joinSpoVNet( spovnetId, ep);
158 }
159 catch ( ptree_bad_path& e )
160 {
161// logging_info("No direct bootstrap info in config.");
162 cout << "No direct bootstrap info in config." << endl;
163 }
164
165
166 /* Bootstrap modules */
167 vector<pair<BootstrapManager::BootstrapType,string> > internalmodules;
168
169 // Bootstrap: Broadcast
170 if ( bootstrap_pt.get("broadcast", false) )
171 {
172 internalmodules.push_back(make_pair(
173 BootstrapManager::BootstrapTypePeriodicBroadcast,""));
174 }
175
176 // Bootstrap: MDNS
177 if ( bootstrap_pt.get("mdns", false) )
178 {
179 internalmodules.push_back(make_pair(
180 BootstrapManager::BootstrapTypeMulticastDns,""));
181 }
182
183 // Bootstrap: SDP
184 if ( bootstrap_pt.get("sdp", false) )
185 {
186 internalmodules.push_back(make_pair(
187 BootstrapManager::BootstrapTypeBluetoothSdp,""));
188 }
189
190 // start automatic overlay bootstrapping modules
191 base_overlay->startBootstrapModules(internalmodules);
192}
193
194//void Node::join(const Name& vnetname) {
195// spovnetId = vnetname.toSpoVNetId();
196// nodeId = generateNodeId(name);
197//
198// // start base comm if not started
199// if( !ariba_mod.base_comm->isStarted() )
200// ariba_mod.base_comm->start();
201//
202// // start base overlay if not started
203// // join against ourselfs
204// if( !base_overlay->isStarted() )
205// base_overlay->start( *ariba_mod.base_comm, nodeId );
206// base_overlay->joinSpoVNet( spovnetId );
207//
208// // join against static bootstrap points and
209// // start automatic bootstrapping modules
210// vector<AribaModule::BootstrapMechanism> mechanisms
211// = ariba_mod.getBootstrapMechanisms(vnetname);
212//
213// vector<pair<BootstrapManager::BootstrapType,string> > internalmodules;
214//
215// BOOST_FOREACH(AribaModule::BootstrapMechanism m, mechanisms){
216// switch(m){
217// case AribaModule::BootstrapMechanismStatic:
218// {
219// const communication::EndpointDescriptor* ep =
220// ariba_mod.getBootstrapNode(vnetname, m);
221// if( ep != NULL && ep->isUnspecified() == false )
222// base_overlay->joinSpoVNet( spovnetId, *ep);
223// break;
224// }
225// case AribaModule::BootstrapMechanismBroadcast:
226// internalmodules.push_back(make_pair(
227// BootstrapManager::BootstrapTypePeriodicBroadcast,
228// ariba_mod.getBootstrapInfo(vnetname, m)));
229// break;
230// case AribaModule::BootstrapMechanismMulticastDNS:
231// internalmodules.push_back(make_pair(
232// BootstrapManager::BootstrapTypeMulticastDns,
233// ariba_mod.getBootstrapInfo(vnetname, m)));
234// break;
235// case AribaModule::BootstrapMechanismSDP:
236// internalmodules.push_back(make_pair(
237// BootstrapManager::BootstrapTypeBluetoothSdp,
238// ariba_mod.getBootstrapInfo(vnetname, m)));
239// break;
240// default:
241// break;
242// }
243// }
244//
245// // start automatic overlay bootstrapping modules
246// base_overlay->startBootstrapModules(internalmodules);
247//
248// // done
249//}
250//
251//void Node::initiate(const Name& vnetname, const SpoVNetProperties& parm) {
252// utility::OverlayParameterSet ovrpset;
253// ovrpset.setOverlayStructure(
254// (utility::OverlayParameterSet::_OverlayStructure)
255// parm.getBaseOverlayType()
256// );
257//
258// spovnetId = vnetname.toSpoVNetId();
259// nodeId = generateNodeId(name);
260//
261// // start base comm if not started
262// if( !ariba_mod.base_comm->isStarted() )
263// ariba_mod.base_comm->start();
264//
265// // start base overlay if not started
266// if( !base_overlay->isStarted() )
267// base_overlay->start( *ariba_mod.base_comm, nodeId );
268//
269// base_overlay->createSpoVNet( spovnetId, ovrpset );
270//}
271
272void Node::leave() {
273 base_overlay->stopBootstrapModules();
274 base_overlay->leaveSpoVNet();
275 base_communication->stop(); // XXX before »base_overlay->stop()« ??
276 base_overlay->stop();
277}
278
279const SpoVNetProperties& Node::getSpoVNetProperties() const {
280 return SpoVNetProperties::DEFAULT;
281}
282
283const SpoVNetID& Node::getSpoVNetId() const {
284 return spovnetId;
285}
286
287const NodeID& Node::getNodeId(const LinkID& lid) const {
288 if( lid == LinkID::UNSPECIFIED ) return nodeId;
289 else return base_overlay->getNodeID( lid );
290}
291
292NodeID Node::generateNodeId(const Name& name) const {
293 if (name == Name::UNSPECIFIED) return Name::random().toNodeId();
294 else return name.toNodeId();
295}
296
297vector<NodeID> Node::getNeighborNodes() const {
298 return base_overlay->getOverlayNeighbors();
299}
300
301LinkID Node::establishLink(const NodeID& nid, const ServiceID& sid) {
302 return base_overlay->establishLink(nid, sid);
303}
304
305void Node::dropLink(const LinkID& lnk) {
306 base_overlay->dropLink(lnk);
307}
308
309bool Node::isLinkDirect(const ariba::LinkID& lnk) const
310{
311 return base_overlay->isLinkDirect(lnk);
312}
313
314int Node::getHopCount(const ariba::LinkID& lnk) const
315{
316 return base_overlay->getHopCount(lnk);
317}
318
319
320
321
322/* +++++ Message sending +++++ */
323void Node::check_send_priority(uint8_t priority)
324{
325 if ( priority < send_priority::HIGHEST || priority > send_priority::LOWEST )
326 throw std::invalid_argument("Illegal priority");
327}
328
329
330// +++ new interface +++
331const SequenceNumber& Node::sendMessage(reboost::message_t msg, const LinkID& lnk, uint8_t priority)
332{
333 // check priority
334 check_send_priority(priority);
335
336 // * call base overlay *
337 return base_overlay->sendMessage(msg, lnk, priority);
338}
339
340// +++ legacy interface +++
341seqnum_t Node::sendMessage(const DataMessage& msg, const LinkID& lnk)
342{
343 reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
344
345 try
346 {
347 base_overlay->sendMessage(message, lnk, send_priority::NORMAL);
348 return 0;
349 }
350 catch ( ariba::overlay::message_not_sent& e )
351 {
352 logging_warn("Message could not be sent. Dropped.");
353 return -1;
354 }
355}
356
357
358// +++ new interface +++
359const SequenceNumber& Node::sendMessage(reboost::message_t msg, const NodeID& nid,
360 const ServiceID& sid, uint8_t priority, const LinkProperties& req) {
361
362 // check priority
363 check_send_priority(priority);
364
365 // * call base overlay *
366 return base_overlay->sendMessage(msg, nid, priority, sid);
367}
368
369// +++ legacy interface +++
370seqnum_t Node::sendMessage(const DataMessage& msg, const NodeID& nid,
371 const ServiceID& sid, const LinkProperties& req) {
372
373// reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
374 reboost::message_t message;
375 message.push_back( ((Message*) msg)->serialize_into_shared_buffer() );
376
377 try
378 {
379 sendMessage(message, nid, sid, send_priority::NORMAL, req);
380 return 0;
381 }
382 catch ( ariba::overlay::message_not_sent& e )
383 {
384 logging_warn("Message could not be sent. Dropped.");
385 return -1;
386 }
387}
388
389
390// +++ new interface +++
391NodeID Node::sendMessageCloserToNodeID(reboost::message_t msg, const NodeID& nid, const ServiceID& sid,
392 uint8_t priority, const LinkProperties& req) {
393
394 // check priority
395 check_send_priority(priority);
396
397 // * call base overlay *
398 return base_overlay->sendMessageCloserToNodeID(msg, nid, priority, sid);
399}
400
401// +++ legacy interface +++
402NodeID Node::sendMessageCloserToNodeID(const DataMessage& msg, const NodeID& nid, const ServiceID& sid,
403 const LinkProperties& req) {
404
405 reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
406
407 return sendMessageCloserToNodeID(message, nid, sid, send_priority::NORMAL, req);
408}
409
410
411// +++ new interface +++
412void Node::sendBroadcastMessage(reboost::message_t msg, const ServiceID& sid, uint8_t priority) {
413
414 // check priority
415 check_send_priority(priority);
416
417 // * call base overlay *
418 return base_overlay->broadcastMessage(msg, sid, priority);
419}
420
421// +++ legacy interface +++
422void Node::sendBroadcastMessage(const DataMessage& msg, const ServiceID& sid) {
423 reboost::message_t message = ((Message*) msg)->wrap_up_for_sending();
424
425 return sendBroadcastMessage(message, sid);
426}
427
428
429/* +++++ [Message sending] +++++ */
430
431
432
433
434bool Node::bind(NodeListener* listener) {
435 return base_overlay->bind(listener);
436}
437
438bool Node::unbind(NodeListener* listener) {
439 return base_overlay->unbind(listener);
440}
441
442bool Node::bind(CommunicationListener* listener, const ServiceID& sid) {
443 // bind the listener
444 bool ret = base_overlay->bind(listener, sid);
445
446// // now that we have a listener, we can ask if sniffing is ok
447// if( ariba_mod.sideport_sniffer != NULL ){
448// base_overlay->registerSidePort(ariba_mod.sideport_sniffer);
449// }
450
451 return ret;
452}
453
454bool Node::unbind(CommunicationListener* listener, const ServiceID& sid) {
455 return base_overlay->unbind(listener, sid);
456}
457
458// @see Module.h
459string Node::getName() const {
460 return name.toString();
461}
462
463} // namespace ariba
Note: See TracBrowser for help on using the repository browser.