#include "transport_peer.hpp" // ariba #include "StreamTransport/StreamTransport.hpp" #include "ariba/utility/addressing2/tcpip_endpoint.hpp" // boost #include #include // namespace ariba::transport namespace ariba { namespace transport { using namespace addressing2; using boost::asio::ip::tcp; #ifdef HAVE_LIBBLUETOOTH using boost::asio::bluetooth::rfcomm; #endif use_logging_cpp(transport_peer); transport_peer::transport_peer() : local(new addressing2::endpoint_set()) { } EndpointSetPtr transport_peer::add_listenOn_endpoints(EndpointSetPtr endpoints) { // TCP Endpoints BOOST_FOREACH( shared_ptr endp, endpoints->get_tcpip_endpoints() ) { // automatic port detection bool port_detection = false; uint16_t try_port = 41322; tcp::endpoint asio_endp = endp->to_asio(); if ( asio_endp.port() == 0 ) { port_detection = true; } // create new server socket do { try { // automatic port detection if ( port_detection ) { asio_endp.port(try_port); endp = tcpip_endpoint::create_TcpIP_Endpoint(asio_endp); } TransportProtocolPtr tmp_ptr(new StreamTransport(endp->to_asio())); transport_streams.push_back(tmp_ptr); logging_info("Listening on IP/TCP " << endp->to_string()); local->add_endpoint(endp); port_detection = false; } catch (boost::system::system_error& e) { // address in use if (e.code() == boost::asio::error::address_in_use) { // BRANCH: automatic port detection if ( port_detection ) { // give up ? if ( try_port > 41422 ) { logging_warn("[WARN] Unable to find free port. Giving up. :-( Last try was: " << endp->to_string() << ". Endpoint will be ignored!"); port_detection = false; } else { // try next port try_port++; } } // BRANCH: explicit given port --> error else { logging_warn("[WARN] Address already in use: " << endp->to_string() << ". Endpoint will be ignored!"); } } // Rethrow else { throw; } } } while ( port_detection ); } // TODO Bluetooth Endpoints #ifdef HAVE_LIBBLUETOOTH // foreach(rfcomm_channel_address channel, local.rfcomm) { // if (local.bluetooth.size() > 0) { // foreach(mac_address mac, local.bluetooth) { // rfcomm::endpoint endp(mac.bluetooth(), channel.value()); // create_service(endp); // } // } else { // rfcomm::endpoint endp(channel.value()); // create_service(endp); // } // } #endif return local; } //void transport_peer::create_service(tcp::endpoint endp) { // try { // TransportProtocolPtr tmp_ptr(new StreamTransport(endp)); // tcps.push_back(tmp_ptr); // logging_info("Listening on IP/TCP " << endp); // // } catch (boost::system::system_error& e) { // if (e.code() == boost::asio::error::address_in_use) { // logging_warn("[WARN] Address already in use: " // << endp << ". Endpoint will be ignored!"); // } else { // // Rethrow // throw; // } // } //} #ifdef HAVE_LIBBLUETOOTH //void transport_peer::create_service(rfcomm::endpoint endp) { // try { // TransportProtocolPtr tmp_ptr(new StreamTransport(endp)); // rfcomms.push_back(tmp_ptr); // logging_info("Listening on bluetooth/RFCOMM " << endp); // // } catch (boost::system::system_error& e) { // if (e.code() == boost::asio::error::address_in_use) { // logging_warn("[WARN] Address already in use: " // << endp << ". Endpoint will be ignored!"); // } else { // // Rethrow // throw; // } // } //} #endif transport_peer::~transport_peer() { } void transport_peer::start() { BOOST_FOREACH(TransportProtocolPtr stream, transport_streams) { stream->start(); } } void transport_peer::stop() { BOOST_FOREACH(TransportProtocolPtr stream, transport_streams) { stream->stop(); } } void transport_peer::send( const const_EndpointSetPtr endpoints, reboost::message_t message, uint8_t priority) { BOOST_FOREACH(TransportProtocolPtr stream, transport_streams) { stream->send(endpoints, message, priority); } } // XXX DEPRECATED //void transport_peer::terminate( const address_v* remote ) { // if (remote->instanceof())// TODO direkt auf der richtigen verbindung // { // foreach(TransportProtocolPtr tcp, tcps) { // tcp->terminate(remote); // } // } //#ifdef HAVE_LIBBLUETOOTH // if (remote->instanceof()) { // foreach(TransportProtocolPtr x, rfcomms) { // x->terminate(remote); // } // } //#endif //} void transport_peer::register_listener( transport_listener* listener ) { BOOST_FOREACH(TransportProtocolPtr stream, transport_streams) { stream->register_listener(listener); } } }} // namespace ariba::transport