Ignore:
Timestamp:
Jul 29, 2009, 10:25:32 AM (15 years ago)
Author:
mies
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • source/ariba/utility/transport/rfcomm/rfcomm.cpp

    r5289 r5406  
    1111#include <deque>
    1212
    13 
    1413namespace ariba {
    1514namespace transport {
     15
     16use_logging_cpp(rfcomm)
    1617
    1718using namespace boost::asio;
     
    3132public:
    3233        link_info(io_service& io ) :
    33                 up(false), local(), remote(), socket(io), size(0), buffer(NULL), sending(false) {
     34                up(false), local(), remote(), socket(io), connect_retries(0),
     35                size(0), buffer(NULL), sending(false) {
    3436        }
    3537
     
    3840        rfcomm_endpoint local, remote;
    3941        bluetooth::rfcomm::socket socket;
     42        int connect_retries;
    4043
    4144        // read buffer
     
    5053};
    5154
    52 void rfcomm::remove_info(link_info* info) {
    53         for (vector<link_info*>::iterator i = links.begin(); i!=links.end();i++)
    54                 if (*i==info) {
    55                         delete info;
    56                         links.erase(i);
    57                 }
     55void rfcomm::shutdown(link_info* info) {
     56        if (info != NULL && info->up) {
     57                info->up = false;
     58                info->socket.shutdown( bluetooth::rfcomm::socket::shutdown_both );
     59        }
    5860}
    5961
     
    7678rfcomm::rfcomm(uint16_t channel) :
    7779        channel(channel), io(asio_io_service::alloc()) {
     80        accept_retries = 0;
    7881}
    7982
     
    8891
    8992        // create acceptor
    90         cout << "Binding to channel " << channel << endl;
     93        logging_info( "Binding to channel " << channel );
    9194        acceptor = new bluetooth::rfcomm::acceptor(io,
    9295                bluetooth::rfcomm::endpoint(bluetooth::rfcomm::get(), channel )
    9396        );
    9497
     98        send_data = new link_data();
     99
    95100        // start accepting
    96101        start_accept();
     
    98103
    99104void rfcomm::stop() {
     105        logging_info( "Stopping asio rfcomm" );
    100106
    101107}
    102108
    103109void rfcomm::send(const address_v* remote, const uint8_t* data, size_t size) {
     110
    104111        // get end-point
    105112        rfcomm_endpoint endpoint = *remote;
     
    107114
    108115        // try to find established connector
     116        logging_debug("Trying to find a already existing link.");
    109117        link_info* info = NULL;
    110118        for (size_t i = 0; i < links.size(); i++)
    111119                if (links[i]->remote.mac() == endpoint.mac()) {
     120                        logging_debug("Using already established link");
    112121                        info = links[i];
    113122                        break;
    114123                }
    115124
    116         // not found? ->try to connect
    117         if (info==NULL) {
    118                 cout << "Connecting to " << endpoint.to_string() << endl;
    119                 info = new link_info(io);
     125        // not found, or not up? ->try to (re-)connect
     126        if (info==NULL || !info->up) {
     127                logging_debug( "Connecting to " << endpoint.to_string() );
     128                if (info != NULL && !info->up) {
     129                        logging_debug("Old link is down. Trying to re-establish link.");
     130                } else {
     131                        info = new link_info(io);
     132                }
     133                info->remote = endpoint;
    120134                info->socket.async_connect( convert(endpoint), boost::bind(
    121135                        &rfcomm::handle_connect, this,
     
    156170
    157171void rfcomm::terminate(const address_v* local, const address_v* remote) {
    158         // not supported right now!
     172        // get end-point
     173        rfcomm_endpoint endpoint = *remote;
     174
     175        for (size_t i = 0; i < links.size(); i++)
     176                if (links[i]->remote.mac() == endpoint.mac()) {
     177
     178                        // close socket
     179                        links[i]->socket.cancel();
     180                        links[i]->socket.close();
     181                        links[i]->up = false;
     182                        break;
     183                }
    159184}
    160185
     
    165190void rfcomm::start_accept() {
    166191
    167         cout << "Waiting for connections ..." << endl;
     192        logging_info( "Waiting for connections ..." );
    168193
    169194        // start accepting a connection
     
    181206void rfcomm::handle_accept(const error_code& error, link_info* info) {
    182207        if (error) {
    183                 cout << "Error accepting" << endl;
     208                logging_error( "Error waiting for new connections: " << error
     209                                << ", trying to recover (attempt " << accept_retries << ")");
    184210                delete info;
     211
     212                // restart accepting
     213                if (accept_retries<3) {
     214                        accept_retries++;
     215                        start_accept();
     216                }
    185217                return;
    186218        }
     
    191223        info->remote = convert( info->socket.remote_endpoint() );
    192224
    193         cout << "Accepting incoming connection from " << info->remote.to_string() << endl;
     225        logging_debug("Accepting incoming connection from "
     226                << info->remote.to_string() );
    194227
    195228        // add to list
     
    208241void rfcomm::handle_connect( const error_code& error, link_info* info ) {
    209242        if (error) {
    210                 cout << "Error connecting ..." << endl;
    211                 delete info;
    212                 return;
     243                logging_error( "Can not connect. Retrying ... "
     244                                "(attempt " << info->connect_retries << ")" );
     245
     246                // do we retry this connection? yes->
     247                if (info->connect_retries<3) {
     248                        // increase counter
     249                        info->connect_retries++;
     250
     251                        // retry connection attempt
     252                        info->socket.async_connect( convert(info->remote), boost::bind(
     253                                &rfcomm::handle_connect, this,
     254                                boost::asio::placeholders::error, info
     255                        ));
     256
     257                } else { // no-> delete link and stop
     258                        return;
     259                }
    213260        }
    214261
     
    218265        info->remote = convert( info->socket.remote_endpoint() );
    219266
    220         cout << "Connected to " << info->remote.to_string() << endl;
     267        logging_debug( "Connected to " << info->remote.to_string() );
    221268
    222269        // add to list
     
    233280        // start read
    234281        boost::asio::async_read(info->socket,
     282
    235283                // read size of packet
    236284                boost::asio::buffer(info->size_, 4),
     285
    237286                // bind handler
    238287                boost::bind(
     288
    239289                        // bind parameters
    240290                        &rfcomm::handle_read_header, this,
     291
    241292                        // handler parameters
    242293                        placeholders::error, placeholders::bytes_transferred, info
     
    248299        link_info* info) {
    249300
     301        // handle error
     302        if (error) {
     303                logging_error("Failed to receive message payload.");
     304                shutdown(info);
     305                return;
     306        }
     307
    250308        // ignore errors and wait for all data to be received
    251         if (error || bytes != 4) return;
     309        if (bytes != 4) return;
    252310
    253311        // get size
     
    255313                        (info->size_[2]<< 8) + (info->size_[3] << 0);
    256314
    257         cout << "receive message of size " << info->size << endl;
     315        logging_debug( "Message header received -> receive message of size " << info->size );
    258316
    259317        // allocate buffer
     
    277335        link_info* info) {
    278336
    279         // ignore errors and wait for all data to be received
    280         if (error || bytes != info->size) {
    281                 if (error) remove_info(info);
     337        // check error
     338        if (error) {
     339                logging_error("Failed to receive message payload.");
     340                shutdown(info);
    282341                return;
    283342        }
    284343
    285         cout << "received message of size " << info->size << endl;
     344        // wait for all data to be received
     345        if (bytes != info->size) return;
     346
     347        logging_debug( "Received message of size " << info->size );
    286348
    287349        // deliver data
     
    296358
    297359void rfcomm::start_write( link_info* info ) {
     360        boost::mutex::scoped_lock(info->mutex);
     361
    298362        // do not start writing if sending is in progress
    299363        if (info->sending || !info->up || info->send_buffer.size()==0) return;
     
    302366
    303367        // safely remove data from deque
    304         info->mutex.lock();
    305         link_data data = info->send_buffer.front();
     368        *send_data = info->send_buffer.front();
    306369        info->send_buffer.pop_front();
    307         info->mutex.unlock();
    308370
    309371        boost::array<boost::asio::mutable_buffer, 2> buffer;
    310         buffer[0] = boost::asio::buffer(data.size_,4);
    311         buffer[1] = boost::asio::buffer(data.buffer,data.size);
     372        buffer[0] = boost::asio::buffer(send_data->size_,4);
     373        buffer[1] = boost::asio::buffer(send_data->buffer,send_data->size);
    312374
    313375        // start writing
     
    321383                        // handler parameters
    322384                        placeholders::error, placeholders::bytes_transferred,
    323                         info, data.size, data.buffer
     385                        info, send_data->size, send_data->buffer
    324386                )
    325387        );
     
    332394        if (error || bytes != (size+4) ) {
    333395                if (error) {
    334                         cout << "Message sent error" << endl;
    335                         remove_info(info);
     396                        logging_error( "Message sent error" );
     397
     398                        // close socket
     399                        info->socket.close();
     400                        info->up = false;
    336401                }
    337402                return;
    338403        }
    339 
    340         cout << "Message sent" << endl;
     404        logging_debug( "Message sent" );
    341405
    342406        // free buffer
Note: See TracChangeset for help on using the changeset viewer.