Index: source/ariba/communication/BaseCommunication.cpp
===================================================================
--- source/ariba/communication/BaseCommunication.cpp	(revision 12775)
+++ source/ariba/communication/BaseCommunication.cpp	(revision 2378)
@@ -1,3 +1,3 @@
-// [License]
+// [Licence]
 // The Ariba-Underlay Copyright
 //
@@ -35,12 +35,7 @@
 // official policies, either expressed or implied, of the Institute of
 // Telematics.
-// [License]
+// [Licence]
 
 #include "BaseCommunication.h"
-
-#include "networkinfo/AddressDiscovery.h"
-#include "ariba/utility/types/PeerID.h"
-#include "ariba/utility/system/SystemQueue.h"
-#include <boost/function.hpp>
 
 #ifdef UNDERLAY_OMNET
@@ -57,137 +52,145 @@
 namespace communication {
 
-using namespace ariba::addressing2;
-
-using ariba::utility::PeerID;
-using ariba::utility::SystemQueue;
-
 use_logging_cpp(BaseCommunication);
-
-
-BaseCommunication::BaseCommunication() 
-	: listenOn_endpoints(new addressing2::endpoint_set()),
-	  currentSeqnum( 0 ),
-	  transport( NULL ),
-	  messageReceiver( NULL ),
-	  started( false )
-{
-}
-
-
-BaseCommunication::~BaseCommunication(){
-}
-
-
-void BaseCommunication::start(EndpointSetPtr listen_on) {
-    assert ( ! started );
-    
-    listenOn_endpoints = listen_on;
-    logging_info("Setting local end-points: " << listenOn_endpoints->to_string());
-    
-	logging_info( "Starting up ..." );
-	currentSeqnum = 0;
-
-	// creating transports
-	//  ---> transport_peer holds the set of the active endpoints we're listening on
-	logging_info( "Creating transports ..." );
-	transport = new transport_peer();
-	active_listenOn_endpoints = transport->add_listenOn_endpoints(listenOn_endpoints);
-	logging_info( "XXX. Active endpoints = " << active_listenOn_endpoints->to_string() ); // XXX
-
-	logging_info( "Searching for local locators ..." );
-	local_endpoints = AddressDiscovery::discover_endpoints(active_listenOn_endpoints);
-	if ( local_endpoints->count() > 0 )
-	{
-	    logging_info( "Done. Discovered local endpoints: " << local_endpoints->to_string() );
-	}
-	else
-	{
-	    logging_warn("WARING!! No local endpoints found, NO COMMUNICATION POSSIBLE!!");
-	    
-	    // TODO notify application, so that it may react properly. throw exception..?
-	    assert( false );
-	}
-
-	
-    // create local EndpointDescriptor
-	//  ---> localDescriptor hold the set endpoints that can be used to reach us
-    localDescriptor.getPeerId() = PeerID::random();
-    localDescriptor.replace_endpoint_set(local_endpoints);
-    logging_info( "Using PeerID: " << localDescriptor.getPeerId() );
-
-    // start transport_peer
-	transport->register_listener( this );
+const BaseCommunication::LinkDescriptor BaseCommunication::LinkDescriptor::UNSPECIFIED;
+
+BaseCommunication::BaseCommunication(const NetworkLocator* _locallocator, const uint16_t _listenport)
+	: messageReceiver( NULL ), currentSeqnum( 0 ), listenport( _listenport ) {
+
+	logging_info( "starting up base communication and creating transports ..." );
+	logging_info( "using port " << listenport );
+
+#ifdef UNDERLAY_OMNET
+	AribaOmnetModule* module = StartupWrapper::getCurrentModule();
+	module->setServerPort( listenport );
+
+	transport = module;
+	network = new OmnetNetworkProtocol( module );
+#else
+	transport = new TCPTransport( listenport );
+	network = new IPv4NetworkProtocol();
+#endif
+
+	logging_debug( "searching for local locators ..." );
+
+	NetworkProtocol::NetworkLocatorSet locators = network->getAddresses();
+	NetworkProtocol::NetworkLocatorSet::iterator i = locators.begin();
+	NetworkProtocol::NetworkLocatorSet::iterator iend = locators.end();
+
+	//
+	// choose the first locator that is not localhost
+	//
+
+	bool foundLocator = false;
+
+	for( ; i != iend; i++){
+		logging_debug( "local locator found " + (*i)->toString() );
+		IPv4Locator* ipv4locator = dynamic_cast<IPv4Locator*>(*i);
+
+		// TODO: which locators are find to bind to?
+		// localhost is not too bad, works when testing locally
+		// with several instances. the manual override currently
+		// enables to use an arbitrary address, guess this is fine.
+		// so the manual override also can use ANY, LOCALHOST, BROADCAST
+
+		if( *ipv4locator != IPv4Locator::LOCALHOST &&
+		    *ipv4locator != IPv4Locator::ANY       &&
+		    *ipv4locator != IPv4Locator::BROADCAST  ){
+
+			ipv4locator->setPort(listenport);
+			localDescriptor.locator = ipv4locator;
+			localDescriptor.isUnspec = false;
+			logging_info( "binding to addr = " + ipv4locator->toString() );
+			foundLocator = true;
+			break;
+		}
+	} // for( ; i != iend; i++)
+
+
+	if( _locallocator != NULL ) {
+		if( localDescriptor.locator != NULL) delete localDescriptor.locator;
+		localDescriptor.locator = new IPv4Locator( IPv4Locator::fromString( _locallocator->toString()) );
+		localDescriptor.isUnspec = false;
+		logging_debug( "manual locator override, using locator=" <<
+					localDescriptor.locator->toString() );
+		foundLocator = true;
+	}
+
+	// if we found no local locator, exit using logging fatal
+	if( !foundLocator )
+		logging_fatal( "did not find a useable local locator!" );
+
+	transport->addMessageReceiver( this );
 	transport->start();
 
+#ifndef UNDERLAY_OMNET
+	//
 	// bind to the network change detection
+	//
+
 	networkMonitor.registerNotification( this );
-
+#endif
+
+	//
 	// base comm startup done
-	started = true;
-	logging_info( "Started up." );
-}
-
-void BaseCommunication::stop() {
-	logging_info( "Stopping transports ..." );
+	//
+
+	logging_info( "base communication started up" );
+}
+
+BaseCommunication::~BaseCommunication() {
+
+	logging_info( "stopping base communication and transport ..." );
 
 	transport->stop();
 	delete transport;
-	started = false;
-
-	logging_info( "Stopped." );
-}
-
-bool BaseCommunication::isStarted(){
-	return started;
+	delete network;
+
+	logging_info( "base communication stopped" );
 }
 
 const LinkID BaseCommunication::establishLink(
-	const EndpointDescriptor& descriptor,
-	const LinkID& link_id,
-	const QoSParameterSet& qos,
-	const SecurityParameterSet& sec) {
-
-	// copy link id
-	LinkID linkid = link_id;
-
-	// debug
-	logging_debug( "Request to establish link" );
-
-	// create link identifier
-	if (linkid.isUnspecified())	linkid = LinkID::create();
-
-	// create link descriptor
-	logging_debug( "Creating new descriptor entry with local link id=" << linkid.toString() );
-	LinkDescriptor* ld = new LinkDescriptor();
-	ld->localLink = linkid;
-	addLink( ld );
-
-
-    /* send a message to request new link to remote */
-    logging_debug( "Send messages with request to open link to " << descriptor.toString() );
-
-    /*
-	 * Create Link-Request Message:
-	 * NOTE: - Their PeerID (in parent message)
-	 * - Our LinkID
-	 * - Our PeerID
-	 * - Our EndpointDescriptor
-	 */
-	reboost::message_t linkmsg;
-	linkmsg.push_back(linkid.serialize());
-	linkmsg.push_back(localDescriptor.getPeerId().serialize());
-	linkmsg.push_back(localDescriptor.endpoints->serialize());
-	
-//	// XXX AKTUELL BUG FINDING...
-//	reboost::shared_buffer_t xxx = localDescriptor.endpoints->serialize();
-//	EndpointSetPtr xxx_set = endpoint_set::create_EndpointSet();
-//	xxx_set->deserialize(xxx);
-//	cout << "/// MARIO VORHER: " << localDescriptor.endpoints->to_string() << endl;
-//	cout << "/// MARIO NACHHER: " << xxx_set->to_string() << endl;
-	
-	// send message
-	// TODO move enum to BaseComm
-	send_to_peer(AribaBaseMsg::typeLinkRequest, descriptor.getPeerId(), linkmsg,
-	        descriptor, system_priority::OVERLAY);
+			const EndpointDescriptor& descriptor,
+			const QoSParameterSet& qos,
+			const SecurityParameterSet& sec){
+
+	logging_debug( "request to establish link" );
+
+	//
+	// just use the first locator in the endp descriptors
+	//
+
+	if( descriptor.locator == NULL ){
+		logging_error( "invalid destination endpoint" );
+		return LinkID::UNSPECIFIED;
+	}
+
+	if( localDescriptor.locator == NULL ){
+		logging_error( "invalid local endpoint" );
+		return LinkID::UNSPECIFIED;
+	}
+
+	const NetworkLocator* remote = descriptor.locator;
+	const NetworkLocator* local =  localDescriptor.locator;
+
+	//
+	// create link and link descriptor
+	//
+
+	LinkID linkid = LinkID::create();
+
+	logging_debug( "creating new local descriptor entry with local link id " + linkid.toString() );
+	LinkDescriptor linkDescriptor( linkid, local, LinkID::UNSPECIFIED, remote, descriptor );
+	addLink( linkDescriptor );
+
+	//
+	// create a base msg with our link id and
+	// a request to open a link on the other side
+	//
+
+	logging_debug( "sending out base messages with request to open link to " + remote->toString() );
+	AribaBaseMsg baseMsg( remote, AribaBaseMsg::LINK_STATE_OPEN_REQUEST, linkid,
+								LinkID::UNSPECIFIED );
+	transport->sendMessage(&baseMsg);
 
 	return linkid;
@@ -196,23 +199,29 @@
 void BaseCommunication::dropLink(const LinkID link) {
 
-	logging_debug( "Starting to drop link " + link.toString() );
+	logging_debug( "starting to drop link " + link.toString() );
 
 	// see if we have the link
-	LinkDescriptor& ld = queryLocalLink( link );
-	if( ld.isUnspecified() ) {
-		logging_error( "Don't know the link you want to drop "+ link.toString() );
+	LinkDescriptor& descriptor = queryLocalLink( link );
+	if( descriptor.isUnspecified() ){
+		logging_error( "don't know the link you want to drop" );
 		return;
 	}
 
+	// create message to drop the link
+	logging_debug( "sending out link close request. for us, the link is closed now" );
+	AribaBaseMsg msg(
+		descriptor.remoteLocator,
+		AribaBaseMsg::LINK_STATE_CLOSE_REQUEST,
+		descriptor.localLink,
+		descriptor.remoteLink
+	);
+
+	// send message to drop the link
+	transport->sendMessage( &msg );
+
 	// tell the registered listeners
-	foreach( CommunicationEvents* i, eventListener ) {
-		i->onLinkDown( link, ld.localLocator, ld.remoteLocator );
-	}
-
-
-	// * send message to drop the link *
-	logging_debug( "Sending out link close request. for us, the link is closed now" );
-	reboost::message_t empty_message;
-	send_over_link( AribaBaseMsg::typeLinkClose, empty_message, ld, system_priority::OVERLAY );
+	BOOST_FOREACH( CommunicationEvents* i, eventListener ){
+		i->onLinkDown( link, descriptor.localLocator, descriptor.remoteLocator );
+	}
 
 	// remove from map
@@ -220,62 +229,53 @@
 }
 
-
-seqnum_t BaseCommunication::sendMessage( const LinkID& lid,
-        reboost::message_t message,
-        uint8_t priority,
-        bool bypass_overlay) throw(communication_message_not_sent)
-{
-    // message type: direct data or (normal) data 
-    AribaBaseMsg::type_ type;
-    if ( bypass_overlay )
-    {
-        type = AribaBaseMsg::typeDirectData;
-        logging_debug( "Sending out direct-message to link " << lid.toString() );
-    }
-    else
-    {
-        type = AribaBaseMsg::typeData;
-        logging_debug( "Sending out message to link " << lid.toString() );
-    }
-
-    
+seqnum_t BaseCommunication::sendMessage( const LinkID lid, const Message* message) {
+
+	logging_debug( "sending out message to link " + lid.toString() );
+
 	// query local link info
-	LinkDescriptor& ld = queryLocalLink(lid);
-	if( ld.isUnspecified() )
-	{
-	    throw communication_message_not_sent("Don't know the link with id "
-	            + lid.toString());
-	}
-
-	// link not up-> error
-	if( !ld.up )
-	{
-	    throw communication_message_not_sent("Can not send on link "
-	            + lid.toString() + ": link not up");
-	}
-
-
-	// * send message *
-	bool okay = send_over_link( type, message, ld, priority );
-
-	if ( ! okay )
-	{
-	    throw communication_message_not_sent("send_over_link failed!");
-	}
-	
+	LinkDescriptor& linkDesc = queryLocalLink(lid);
+	if( linkDesc.isUnspecified() ){
+		logging_error( "don't know the link with id " + lid.toString() );
+		return 0;
+	}
+
+	// create message
+	AribaBaseMsg msg(
+		linkDesc.remoteLocator,
+		AribaBaseMsg::LINK_STATE_DATA,
+		linkDesc.localLink,
+		linkDesc.remoteLink
+	);
+
+	// encapsulate the payload message
+	msg.encapsulate( const_cast<Message*>(message) );
+
+	// send message
+	transport->sendMessage( &msg );
+
 	return ++currentSeqnum;
 }
 
 const EndpointDescriptor& BaseCommunication::getEndpointDescriptor(const LinkID link) const {
-	if( link.isUnspecified() ){
+
+	if( link == LinkID::UNSPECIFIED){
 		return localDescriptor;
 	} else {
 		LinkDescriptor& linkDesc = queryLocalLink(link);
-		if (linkDesc.isUnspecified()) return EndpointDescriptor::UNSPECIFIED();
-		return linkDesc.remoteDescriptor;
-	}
+		if (linkDesc.isUnspecified()) return EndpointDescriptor::UNSPECIFIED;
+		return linkDesc.remoteEndpoint;
+	}
+}
+
+void BaseCommunication::registerMessageReceiver(MessageReceiver* _receiver) {
+	messageReceiver = _receiver;
+}
+
+void BaseCommunication::unregisterMessageReceiver(MessageReceiver* _receiver) {
+	messageReceiver = NULL;
 }
 
 void BaseCommunication::registerEventListener(CommunicationEvents* _events){
+
 	if( eventListener.find( _events ) == eventListener.end() )
 		eventListener.insert( _events );
@@ -283,4 +283,5 @@
 
 void BaseCommunication::unregisterEventListener(CommunicationEvents* _events){
+
 	EventListenerSet::iterator i = eventListener.find( _events );
 	if( i != eventListener.end() )
@@ -289,493 +290,288 @@
 
 
-
-/*------------------------------
- | ASIO thread --> SystemQueue |
- ------------------------------*/
-
-/// ASIO thread
-void BaseCommunication::receive_message(transport_connection::sptr connection,
-	reboost::shared_buffer_t msg) {
-
-	logging_debug( "Dispatching message" );
-	
-    SystemQueue::instance().scheduleCall(
-            boost::bind(
-                    &BaseCommunication::receiveMessage,
-                    this,
-                    connection,
-                    msg)
-        );
-}
-
-/// ASIO thread
-void BaseCommunication::connection_terminated(transport_connection::sptr connection)
-{
-    SystemQueue::instance().scheduleCall(
-            boost::bind(
-                    &BaseCommunication::connectionTerminated,
-                    this,
-                    connection)
-        );
-}
-
-/*--------------------------------
- | [ASIO thread --> SystemQueue] |
- -------------------------------*/
-
-/// ARIBA thread (System Queue)
-void BaseCommunication::connectionTerminated(transport_connection::sptr connection)
-{
-    vector<LinkID*> links = connection->get_communication_links();
-    
-    logging_debug("[BaseCommunication] Connection terminated: "
-            << connection->getLocalEndpoint()->to_string()
-            << " <--> " << connection->getRemoteEndpoint()->to_string()
-            << " (" << links.size() << " links)");
-    
-    // remove all links that used the terminated connection
-    for ( vector<LinkID*>::iterator it = links.begin(); it != links.end(); ++it )
-    {
-        LinkID& link_id = **it;
-        
-        logging_debug("  ---> Removing link: " << link_id.toString());
-        
-        // searching for link, not found-> warn
-        LinkDescriptor& linkDesc = queryLocalLink( link_id );
-        if (linkDesc.isUnspecified()) {
-            logging_warn("Failed to find local link " << link_id.toString());
-            continue;
-        }
-
-        // inform listeners
-        foreach( CommunicationEvents* i, eventListener ){
-            i->onLinkFail( linkDesc.localLink,
-                    linkDesc.localLocator, linkDesc.remoteLocator );
-        }
-
-        // remove the link descriptor
-        removeLink( link_id );
-    }
-}
-
-/// ARIBA thread (System Queue)
-void BaseCommunication::receiveMessage(transport_connection::sptr connection,
-        reboost::shared_buffer_t message)
-{
-    // XXX
-    logging_debug("/// [receiveMessage] buffersize: " << message.size());
-        
-    // get type
-    uint8_t type = message.data()[0];
-    reboost::shared_buffer_t sub_buff = message(1);
-    
-    // get link id
-    LinkID link_id;
-    if ( type != AribaBaseMsg::typeLinkRequest)
-    {
-        sub_buff = link_id.deserialize(sub_buff);
-    }
-    
-	// handle message
-	switch ( type )
-	{
-		// ---------------------------------------------------------------------
-		// data message
-		// ---------------------------------------------------------------------
-		case AribaBaseMsg::typeData:
-		{
-			logging_debug( "Received data message, forwarding to overlay." );
-			if( messageReceiver != NULL )
-			{
-				messageReceiver->receiveMessage(
-					sub_buff, link_id, NodeID::UNSPECIFIED, false
-				);
-			}
-			
+bool BaseCommunication::receiveMessage(const Message* message, const LinkID& link, const NodeID& node){
+
+	//
+	// these messages arrive from the Transport module
+	// and are incoming network messages. Unpack the
+	// AribaBaseMsg and handle control packets,
+	// deliver data packets to the overlay
+	//
+
+	AribaBaseMsg* spovmsg = ((Message*)message)->decapsulate<AribaBaseMsg>();
+	logging_debug( "receiving base comm message of type " + spovmsg->getTypeString() );
+
+	//
+	// deliver data to the overlays. we just give the
+	// inner packet to every registered overlay ...
+	//
+
+	if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_DATA ){
+
+		logging_debug( "received data message, forwarding to overlay" );
+
+		//
+		// put the linkid as address into the message
+		// and sent it to the receiver
+		//
+
+		if( messageReceiver != NULL ) {
+			messageReceiver->receiveMessage(
+				spovmsg,
+				spovmsg->getRemoteLink(),
+				NodeID::UNSPECIFIED
+			);
+		}
+
+	} // LINK_STATE_DATA
+
+	//
+	// handle link open requests
+	//
+
+	else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_OPEN_REQUEST ){
+
+		logging_debug( "received link open request" );
+
+		//
+		// create a link context
+		//
+
+		//  in an incoming packet the localLink is from
+		// the sender perspective local and from our
+		// perspective remote
+
+		logging_debug( "creating local link" );
+
+		LinkID localLink  = LinkID::create();
+		LinkID remoteLink = spovmsg->getLocalLink();
+
+
+		const NetworkLocator* localLocator  = dynamic_cast<const NetworkLocator*>(localDescriptor.locator);
+		const NetworkLocator* remoteLocator = dynamic_cast<const NetworkLocator*>(message->getSourceAddress());
+
+		logging_debug( "localLocator=" + localLocator->toString() + " remoteLocator="+remoteLocator->toString());
+
+		// ask the registered listeners if this link
+		// creation is fine. we will only allow the
+		// link if all of them agree
+
+		bool allowlink = true;
+		BOOST_FOREACH( CommunicationEvents* i, eventListener ){
+			allowlink &= i->onLinkRequest( localLink, localLocator, remoteLocator );
+		}
+
+		if( !allowlink ){
+			logging_warn( "overlay denied creation of link" );
+			return true;
+		}
+
+		//
+		// create and save the descriptor for the link
+		//
+
+		LinkDescriptor linkDescriptor(localLink, localLocator, remoteLink,
+					remoteLocator, EndpointDescriptor(remoteLocator));
+
+		logging_debug( "saving new link descriptor with " <<
+				"[local link " << localLink.toString() << "] " <<
+				"[local locator " << localLocator->toString() << "] " <<
+				"[remote link " << remoteLink.toString() << "] " <<
+				"[remote locator " << remoteLocator->toString() << "]" );
+
+		addLink( linkDescriptor );
+
+		//
+		// send out a link reply
+		//
+
+		logging_debug( "sending back link open reply for " <<
+					"[local link " << localLink.toString() << "] " <<
+					"[remote link " << remoteLink.toString() << "]" );
+
+		AribaBaseMsg reply(remoteLocator,
+				     AribaBaseMsg::LINK_STATE_OPEN_REPLY,
+				     localLink,
+				     remoteLink);
+
+		transport->sendMessage( &reply );
+
+		//
+		// the link is now open
+		//
+
+		BOOST_FOREACH( CommunicationEvents* i, eventListener ){
+			i->onLinkUp( localLink, localLocator, remoteLocator );
+		}
+
+	} // LINK_STATE_OPEN_REQUEST
+
+	//
+	// handle link open replies
+	//
+
+	else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_OPEN_REPLY ){
+
+		logging_debug( "received link open reply for a link we initiated" );
+
+		// this is a reply to a link open request, so we have already
+		// a link mapping and can now set the remote link to valid
+		LinkDescriptor& linkDesc = queryLocalLink( spovmsg->getRemoteLink() );
+
+		if (linkDesc.isUnspecified()) {
+			logging_warn("Failed to find local link "+spovmsg->getRemoteLink().toString());
+			return false;
+		}
+
+		linkDesc.remoteLink = spovmsg->getLocalLink();
+		logging_debug( "the link is now up with local link id " + spovmsg->getRemoteLink().toString() );
+
+		BOOST_FOREACH( CommunicationEvents* i, eventListener ){
+			i->onLinkUp( linkDesc.localLink, linkDesc.localLocator, linkDesc.remoteLocator );
+		}
+
+	} // LINK_STATE_OPEN_REPLY
+
+	//
+	// handle link close requests
+	//
+
+	else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_CLOSE_REQUEST ){
+
+		const LinkID& localLink = spovmsg->getRemoteLink();
+		logging_debug( "received link close request for link " + localLink.toString() );
+
+		//
+		// the link is closed immediately, we
+		// don't need to send out a reply, so we
+		// delete the mapping and inform
+		//
+
+		LinkDescriptor& linkDesc = queryLocalLink( localLink );
+		if (linkDesc.isUnspecified()) {
+			logging_warn("Failed to find local link "+localLink.toString());
+			return false;
+		}
+
+		BOOST_FOREACH( CommunicationEvents* i, eventListener ){
+			i->onLinkDown( linkDesc.localLink, linkDesc.localLocator, linkDesc.remoteLocator );
+		}
+
+		removeLink( localLink );
+
+	} // LINK_STATE_CLOSE_REQUEST
+
+	//
+	// handle locator updates
+	//
+
+	else if( spovmsg->getType() == AribaBaseMsg::LINK_STATE_UPDATE ){
+
+		const LinkID& localLink = spovmsg->getRemoteLink();
+		logging_debug( "received link update for link " + localLink.toString() );
+
+		//
+		// find the link description
+		//
+
+		LinkDescriptor& linkDesc = queryLocalLink( localLink );
+		if (linkDesc.isUnspecified()) {
+			logging_warn("Failed to update local link "+localLink.toString());
+			return false;
+		}
+
+		//
+		// update the remote locator
+		//
+
+		const NetworkLocator* oldremote = linkDesc.remoteLocator;
+		linkDesc.remoteLocator = dynamic_cast<const NetworkLocator*>(message->getSourceAddress());
+
+		//
+		// inform the listeners (local link has _not_ changed!)
+		//
+
+		BOOST_FOREACH( CommunicationEvents* i, eventListener ){
+			i->onLinkChanged(
+				linkDesc.localLink,	// linkid
+				linkDesc.localLocator,	// old local
+				linkDesc.localLocator,	// new local
+				oldremote,		// old remote
+				linkDesc.remoteLocator	// new remote
+			);
+		}
+
+	} // LINK_STATE_UPDATE
+
+	return true;
+}
+
+void BaseCommunication::addLink( const LinkDescriptor& link ) {
+	linkSet.push_back( link );
+}
+
+void BaseCommunication::removeLink( const LinkID& localLink ) {
+
+	LinkSet::iterator i = linkSet.begin();
+	LinkSet::iterator iend = linkSet.end();
+
+	for( ; i != iend; i++){
+		if( (*i).localLink == localLink){
+			linkSet.erase( i );
 			break;
 		}
-
-        // ---------------------------------------------------------------------
-        // direct data message (bypass overlay-layer)
-        // ---------------------------------------------------------------------
-        case AribaBaseMsg::typeDirectData:
-        {
-            logging_debug( "Received direct data message, forwarding to application." );
-            
-            if( messageReceiver != NULL )
-            {
-                messageReceiver->receiveMessage(
-                    sub_buff, link_id, NodeID::UNSPECIFIED, true
-                );
-            }
-            
-            break;
-        }
-
-
-        
-		// ---------------------------------------------------------------------
-		// handle link request from remote
-		// ---------------------------------------------------------------------
-		case AribaBaseMsg::typeLinkRequest:
-		{
-			logging_debug( "Received link open request on "
-			        << connection->getLocalEndpoint()->to_string() );
-			
-			/*
-			 * Deserialize Peer Message
-			 * - Our PeerID 
-			 */
-			PeerID our_peer_id;
-			sub_buff = our_peer_id.deserialize(sub_buff);
-
-            /// not the correct peer id-> skip request
-            if ( our_peer_id != localDescriptor.getPeerId() &&
-                    ! our_peer_id.isUnspecified() /* overlay bootstrap */ )
-            {
-                logging_info("Received link request for "
-                    << our_peer_id.toString()
-                    << "but i'm "
-                    << localDescriptor.getPeerId()
-                    << ": Ignoring!");
-                
-                // TODO terminate connection?
-                
-                break;
-            }
-
-            
-		    /*
-		     * Deserialize Link-Request Message:
-		     * - Their LinkID
-		     * - Their PeerID
-		     * - Their EndpointDescriptor
-		     */
-            LinkID their_link_id;
-            PeerID their_peer_id;
-            EndpointSetPtr their_endpoints = endpoint_set::create_EndpointSet();
-            sub_buff = their_link_id.deserialize(sub_buff);
-            sub_buff = their_peer_id.deserialize(sub_buff);
-            sub_buff = their_endpoints->deserialize(sub_buff);
-            /* [ Deserialize Link-Request Message ] */
-
-            
-			/// only answer the first request
-			if (!queryRemoteLink(their_link_id).isUnspecified())
-			{
-			    
-			    // TODO aktuell: When will these connections be closed?
-			    // ---> Close it now (if it services no links) ?
-			    //   (see also ! allowlink below)
-			    
-			    // XXX AKTUELL TESTING !! This will cause race conditions. So this is test-code only!
-			    if ( connection->get_communication_links().size() == 0 )
-			    {
-			        connection->terminate();
-			    }
-			    
-				logging_debug("Link request already received. Ignore!");
-				break;
-			}
-
-			/// create link ids
-			LinkID localLink  = LinkID::create();
-			LinkID remoteLink = their_link_id;  // XXX intermediate variable is unnecessary
-			logging_debug(
-			        "local=" << connection->getLocalEndpoint()->to_string()
-				<< " remote=" << connection->getRemoteEndpoint()->to_string()
-			);
-
-			// check if link creation is allowed by ALL listeners
-			bool allowlink = true;
-			foreach( CommunicationEvents* i, eventListener ){
-				allowlink &= i->onLinkRequest( localLink,
-				        connection->getLocalEndpoint(),
-				        connection->getRemoteEndpoint());
-			}
-
-			// not allowed-> warn
-			if( !allowlink ){
-				logging_warn( "Overlay denied creation of link" );
-				return;
-			}
-
-			// create descriptor
-			LinkDescriptor* ld = new LinkDescriptor();
-			ld->localLink = localLink;
-			ld->remoteLink = remoteLink;
-			ld->localLocator = connection->getLocalEndpoint();
-			ld->remoteLocator = connection->getRemoteEndpoint();
-			ld->remoteDescriptor = EndpointDescriptor(their_peer_id, their_endpoints);
-			ld->set_connection(connection);
-
-            
-			// update endpoints (should only have any effect in case of NAT)
-			ld->remoteDescriptor.endpoints->add_endpoint(connection->getRemoteEndpoint());
-//			localDescriptor.endpoints->add_endpoint(connection->getLocalEndpoint());  // XXX 0.0.0.0:0
-
-			// link is now up-> add it
-			ld->up = true;
-			addLink(ld);
-
-
-			
-            /* sending link reply */
-            logging_debug( "Sending link reply with ids "
-                << "local=" << localLink.toString() << ", "
-                << "remote=" << remoteLink.toString() );
-
-		    /*
-		     * Create Link-Reply Message:
-		     * - Our LinkID
-		     * - Our Endpoint_Set (as update)
-		     * - Their EndpointDescriptor (maybe they learn something about NAT)
-		     */
-		    reboost::message_t linkmsg;
-		    linkmsg.push_back(localLink.serialize());
-		    linkmsg.push_back(localDescriptor.endpoints->serialize());
-		    linkmsg.push_back(ld->remoteDescriptor.endpoints->serialize());
-		    
-		    // XXX
-		    cout << "/// MARIO: " << ld->get_connection()->getRemoteEndpoint()->to_string() << endl;
-		    
-		    // send message
-			bool sent = send_over_link( AribaBaseMsg::typeLinkReply, linkmsg, *ld, system_priority::OVERLAY );
-			
-			if ( ! sent )
-			{
-			    logging_error("ERROR: Could not send LinkReply to: " << ld->remoteLocator->to_string());
-			    
-			    // TODO remove link, close link, ..?
-			    
-			    break;
-			}
-
-
-            // link is up!
-            logging_debug( "Link (initiated from remote) is up with "
-                << "local(id=" << ld->localLink.toString() << ","
-                << "locator=" << ld->localLocator->to_string() << ") "
-                << "remote(id=" << ld->remoteLink.toString() << ", "
-                << "locator=" << ld->remoteLocator->to_string() << ")"
-            );
-
-			// inform listeners about new open link
-			foreach( CommunicationEvents* i, eventListener ) {
-				i->onLinkUp( localLink, ld->localLocator, ld->remoteLocator);
-			}
-
-			// done
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle link request reply
-		// ---------------------------------------------------------------------
-		case AribaBaseMsg::typeLinkReply:
-		{
-			logging_debug( "Received link open reply for a link we initiated" );
-
-            /*
-             * Deserialize Link-Reply Message:
-             * - Their LinkID
-             * - Their Endpoint_Set (as update)
-             * - Our EndpointDescriptor (maybe we can learn something about NAT)
-             */
-			LinkID their_link_id;
-			EndpointSetPtr their_endpoints = endpoint_set::create_EndpointSet();
-			EndpointSetPtr our_endpoints = endpoint_set::create_EndpointSet();
-			sub_buff = their_link_id.deserialize(sub_buff);
-			sub_buff = their_endpoints->deserialize(sub_buff);
-			sub_buff = our_endpoints->deserialize(sub_buff);
-
-            
-			// this is a reply to a link open request, so we have already
-			// a link mapping and can now set the remote link to valid
-			LinkDescriptor& ld = queryLocalLink( link_id );
-
-			// no link found-> warn!
-			if (ld.isUnspecified()) {
-				logging_warn("Failed to find local link " << link_id.toString());
-				return;
-			}
-			
-			if ( ld.up )
-			{
-                logging_warn("Got link replay for already open link. Ignore. LinkID: " << link_id.toString());
-                
-                // TODO send LinkClose ?
-                return;			    
-			}
-
-			// store the connection
-			ld.set_connection(connection);
-			
-			// set remote locator and link id
-			ld.remoteLink = their_link_id;
-			ld.remoteLocator = connection->getRemoteEndpoint();
-			
-			
-			/* Update endpoints */
-			// NOTE: we might loose some information here, but it's our only chance to get rid of outdated information.
-			ld.remoteDescriptor.replace_endpoint_set(their_endpoints);
-			
-			// add actual remote endpoint to this set (should only have any effect in case of NAT)
-			ld.remoteDescriptor.endpoints->add_endpoint(connection->getRemoteEndpoint());
-			
-			// TODO In case of NAT, we could learn something about our external IP.
-			//   ---> But we must trust the remote peer about this information!!  
-//			localDescriptor.endpoints->add_endpoints(our_endpoints);
-			
-			
-			
-			
-			ld.up = true;
-
-			logging_debug( "Link is now up with local id "
-				<< ld.localLink.toString() << " and remote id "
-				<< ld.remoteLink.toString() );
-
-
-			// inform lisneters about link up event
-			foreach( CommunicationEvents* i, eventListener ){
-				i->onLinkUp( ld.localLink, ld.localLocator, ld.remoteLocator );
-			}
-
-			// done
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle link close requests
-		// ---------------------------------------------------------------------
-		case AribaBaseMsg::typeLinkClose: {
-			// get remote link
-//			const LinkID& localLink = msg.getRemoteLink();
-			logging_debug( "Received link close request for link " << link_id.toString() );
-
-			// searching for link, not found-> warn
-			LinkDescriptor& linkDesc = queryLocalLink( link_id );
-			if (linkDesc.isUnspecified()) {
-				logging_warn("Failed to find local link " << link_id.toString());
-				return;
-			}
-
-			// inform listeners
-			foreach( CommunicationEvents* i, eventListener ){
-				i->onLinkDown( linkDesc.localLink,
-						linkDesc.localLocator, linkDesc.remoteLocator );
-			}
-
-			// remove the link descriptor
-			removeLink( link_id );
-
-			// done
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle link locator changes  -- TODO is this ever called..?
-		// ---------------------------------------------------------------------
-//		case AribaBaseMsg::typeLinkUpdate: {
-//			const LinkID& localLink = msg.getRemoteLink();
-//			logging_debug( "Received link update for link "
-//				<< localLink.toString() );
-//
-//			// find the link description
-//			LinkDescriptor& linkDesc = queryLocalLink( localLink );
-//			if (linkDesc.isUnspecified()) {
-//				logging_warn("Failed to update local link "
-//					<< localLink.toString());
-//				return;
-//			}
-//
-//			// update the remote locator
-//			addressing2::EndpointPtr oldremote = linkDesc.remoteLocator;
-//			linkDesc.remoteLocator = connection->getRemoteEndpoint();
-//			
-//			// TODO update linkDesc.connection ?
-//
-//			// inform the listeners (local link has _not_ changed!)
-//			foreach( CommunicationEvents* i, eventListener ){
-//				i->onLinkChanged(
-//					linkDesc.localLink,	// linkid
-//					linkDesc.localLocator,	// old local
-//					linkDesc.localLocator,	// new local
-//					oldremote,		        // old remote
-//					linkDesc.remoteLocator	// new remote
-//				);
-//			}
-//
-//			// done
-//			break;
-//		}
-		
-		
-        default: {
-            logging_warn( "Received unknown message type!" );
-            break;
-        }
-
-	}
-}
-
-/// add a newly allocated link to the set of links
-void BaseCommunication::addLink( LinkDescriptor* link ) {
-	linkSet.push_back( link );
-}
-
-/// remove a link from set
-void BaseCommunication::removeLink( const LinkID& localLink ) {
-	for(LinkSet::iterator i=linkSet.begin(); i != linkSet.end(); i++){
-		if( (*i)->localLink != localLink) continue;
-//		remove_endpoint((*i)->remoteLocator);  // XXX
-		delete *i;
-		linkSet.erase( i );
-		break;
-	}
-}
-
-/// query a descriptor by local link id
+	}
+}
+
 BaseCommunication::LinkDescriptor& BaseCommunication::queryLocalLink( const LinkID& link ) const {
-	for (size_t i=0; i<linkSet.size();i++)
-		if (linkSet[i]->localLink == link) return (LinkDescriptor&)*linkSet[i];
-
-	return LinkDescriptor::UNSPECIFIED();
-}
-
-/// query a descriptor by remote link id
+	for (int i=0; i<linkSet.size();i++)
+		if (linkSet[i].localLink == link) return (LinkDescriptor&)linkSet[i];
+	return (LinkDescriptor&)LinkDescriptor::UNSPECIFIED;
+}
+
 BaseCommunication::LinkDescriptor& BaseCommunication::queryRemoteLink( const LinkID& link ) const {
-	for (size_t i=0; i<linkSet.size();i++)
-		if (linkSet[i]->remoteLink == link) return (LinkDescriptor&)*linkSet[i];
-
-	return LinkDescriptor::UNSPECIFIED();
-}
-
-//LinkIDs BaseCommunication::getLocalLinks( const address_v* addr ) const {
-//	LinkIDs ids;
-//	for (size_t i=0; i<linkSet.size(); i++){
-//		if( addr == NULL ){
-//			ids.push_back( linkSet[i]->localLink );
-//		} else {
-//			if ( *linkSet[i]->remoteLocator == *addr )
-//				ids.push_back( linkSet[i]->localLink );
-//		}
-//	}
-//	return ids;
-//}
+	for (int i=0; i<linkSet.size();i++)
+		if (linkSet[i].remoteLink == link) return (LinkDescriptor&)linkSet[i];
+	return (LinkDescriptor&)LinkDescriptor::UNSPECIFIED;
+}
+
+LinkIDs BaseCommunication::getLocalLinks( const EndpointDescriptor& ep ) const {
+	LinkIDs ids;
+
+	for (int i=0; i<linkSet.size(); i++){
+		if( ep == EndpointDescriptor::UNSPECIFIED ){
+			ids.push_back( linkSet[i].localLink );
+		} else {
+			if ( linkSet[i].remoteLocator == ep.locator )
+				ids.push_back( linkSet[i].localLink );
+		}
+	}
+
+	return ids;
+}
 
 void BaseCommunication::onNetworkChange(const NetworkChangeInterface::NetworkChangeInfo& info){
 
-/*- disabled!
-
+#ifdef UNDERLAY_OMNET
+
+	// we have no mobility support for simulations
+	return
+
+#endif // UNDERLAY_OMNET
+
+	//
 	// we only care about address changes, not about interface changes
 	// as address changes are triggered by interface changes, we are safe here
+	//
+
 	if( info.type != NetworkChangeInterface::EventTypeAddressNew &&
 		info.type != NetworkChangeInterface::EventTypeAddressDelete ) return;
 
-	logging_info( "base communication is handling network address changes" );
-
+	logging_info("base communication is handling network address changes");
+
+	//
 	// get all now available addresses
+	//
+
 	NetworkInformation networkInformation;
 	AddressInformation addressInformation;
@@ -814,5 +610,5 @@
 
 	for( ; i != iend; i++){
-		logging_debug( "local locator found " << (*i)->toString() );
+		logging_debug( "local locator found " + (*i)->toString() );
 		IPv4Locator* ipv4locator = dynamic_cast<IPv4Locator*>(*i);
 
@@ -900,80 +696,5 @@
 		transport->sendMessage( &updateMsg );
 	}
-*/
-}
-
-
-addressing2::EndpointPtr BaseCommunication::get_local_endpoint_of_link(
-        const LinkID& linkid)
-{
-    LinkDescriptor& ld = queryLocalLink(linkid);
-    
-    return ld.get_connection()->getLocalEndpoint();
-}
-
-addressing2::EndpointPtr BaseCommunication::get_remote_endpoint_of_link(
-        const LinkID& linkid)
-{
-    LinkDescriptor& ld = queryLocalLink(linkid);
-    
-    return ld.get_connection()->getRemoteEndpoint();
-}
-
-
-
-bool BaseCommunication::send_over_link(
-        const uint8_t type,
-        reboost::message_t message,
-        const LinkDescriptor& desc,
-        const uint8_t priority)
-{
-    /*
-     * Create Link Message:
-     * - Type
-     * - Their LinkID
-     */
-    // link id
-    message.push_front(desc.remoteLink.serialize());
-    // type
-    memcpy(message.push_front(sizeof(uint8_t)).mutable_data(), &type, sizeof(uint8_t));
-    /* [ Create Link Message ] */
-    
-    
-    /* send message */
-    transport_connection::sptr conn = desc.get_connection();
-    if ( ! conn )
-    {
-        cout << "/// MARIO: No connection!!" << endl;  // XXX debug
-        return false;
-    }
-    
-    // * send over connection *
-    return conn->send(message, priority);
-}
-
-void BaseCommunication::send_to_peer(
-        const uint8_t type,
-        const PeerID& peer_id,
-        reboost::message_t message,
-        const EndpointDescriptor& endpoint,
-        const uint8_t priority )
-{
-    /*
-     * Create Peer Message:
-     * - Type
-     * - Their PeerID
-     */
-    // peer id
-    message.push_front(peer_id.serialize());
-    // type
-    memcpy(message.push_front(sizeof(uint8_t)).mutable_data(), &type, sizeof(uint8_t));
-    
-    
-    /* send message */
-    transport->send(endpoint.getEndpoints(), message, priority);
-}
-
-
-
+}
 
 }} // namespace ariba, communication
