Changeset 5406 for source/ariba/utility/transport/rfcomm/rfcomm.cpp
- Timestamp:
- Jul 29, 2009, 10:25:32 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
source/ariba/utility/transport/rfcomm/rfcomm.cpp
r5289 r5406 11 11 #include <deque> 12 12 13 14 13 namespace ariba { 15 14 namespace transport { 15 16 use_logging_cpp(rfcomm) 16 17 17 18 using namespace boost::asio; … … 31 32 public: 32 33 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) { 34 36 } 35 37 … … 38 40 rfcomm_endpoint local, remote; 39 41 bluetooth::rfcomm::socket socket; 42 int connect_retries; 40 43 41 44 // read buffer … … 50 53 }; 51 54 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 } 55 void 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 } 58 60 } 59 61 … … 76 78 rfcomm::rfcomm(uint16_t channel) : 77 79 channel(channel), io(asio_io_service::alloc()) { 80 accept_retries = 0; 78 81 } 79 82 … … 88 91 89 92 // create acceptor 90 cout << "Binding to channel " << channel << endl;93 logging_info( "Binding to channel " << channel ); 91 94 acceptor = new bluetooth::rfcomm::acceptor(io, 92 95 bluetooth::rfcomm::endpoint(bluetooth::rfcomm::get(), channel ) 93 96 ); 94 97 98 send_data = new link_data(); 99 95 100 // start accepting 96 101 start_accept(); … … 98 103 99 104 void rfcomm::stop() { 105 logging_info( "Stopping asio rfcomm" ); 100 106 101 107 } 102 108 103 109 void rfcomm::send(const address_v* remote, const uint8_t* data, size_t size) { 110 104 111 // get end-point 105 112 rfcomm_endpoint endpoint = *remote; … … 107 114 108 115 // try to find established connector 116 logging_debug("Trying to find a already existing link."); 109 117 link_info* info = NULL; 110 118 for (size_t i = 0; i < links.size(); i++) 111 119 if (links[i]->remote.mac() == endpoint.mac()) { 120 logging_debug("Using already established link"); 112 121 info = links[i]; 113 122 break; 114 123 } 115 124 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; 120 134 info->socket.async_connect( convert(endpoint), boost::bind( 121 135 &rfcomm::handle_connect, this, … … 156 170 157 171 void 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 } 159 184 } 160 185 … … 165 190 void rfcomm::start_accept() { 166 191 167 cout << "Waiting for connections ..." << endl;192 logging_info( "Waiting for connections ..." ); 168 193 169 194 // start accepting a connection … … 181 206 void rfcomm::handle_accept(const error_code& error, link_info* info) { 182 207 if (error) { 183 cout << "Error accepting" << endl; 208 logging_error( "Error waiting for new connections: " << error 209 << ", trying to recover (attempt " << accept_retries << ")"); 184 210 delete info; 211 212 // restart accepting 213 if (accept_retries<3) { 214 accept_retries++; 215 start_accept(); 216 } 185 217 return; 186 218 } … … 191 223 info->remote = convert( info->socket.remote_endpoint() ); 192 224 193 cout << "Accepting incoming connection from " << info->remote.to_string() << endl; 225 logging_debug("Accepting incoming connection from " 226 << info->remote.to_string() ); 194 227 195 228 // add to list … … 208 241 void rfcomm::handle_connect( const error_code& error, link_info* info ) { 209 242 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 } 213 260 } 214 261 … … 218 265 info->remote = convert( info->socket.remote_endpoint() ); 219 266 220 cout << "Connected to " << info->remote.to_string() << endl;267 logging_debug( "Connected to " << info->remote.to_string() ); 221 268 222 269 // add to list … … 233 280 // start read 234 281 boost::asio::async_read(info->socket, 282 235 283 // read size of packet 236 284 boost::asio::buffer(info->size_, 4), 285 237 286 // bind handler 238 287 boost::bind( 288 239 289 // bind parameters 240 290 &rfcomm::handle_read_header, this, 291 241 292 // handler parameters 242 293 placeholders::error, placeholders::bytes_transferred, info … … 248 299 link_info* info) { 249 300 301 // handle error 302 if (error) { 303 logging_error("Failed to receive message payload."); 304 shutdown(info); 305 return; 306 } 307 250 308 // ignore errors and wait for all data to be received 251 if ( error ||bytes != 4) return;309 if (bytes != 4) return; 252 310 253 311 // get size … … 255 313 (info->size_[2]<< 8) + (info->size_[3] << 0); 256 314 257 cout << "receive message of size " << info->size << endl;315 logging_debug( "Message header received -> receive message of size " << info->size ); 258 316 259 317 // allocate buffer … … 277 335 link_info* info) { 278 336 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); 282 341 return; 283 342 } 284 343 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 ); 286 348 287 349 // deliver data … … 296 358 297 359 void rfcomm::start_write( link_info* info ) { 360 boost::mutex::scoped_lock(info->mutex); 361 298 362 // do not start writing if sending is in progress 299 363 if (info->sending || !info->up || info->send_buffer.size()==0) return; … … 302 366 303 367 // safely remove data from deque 304 info->mutex.lock(); 305 link_data data = info->send_buffer.front(); 368 *send_data = info->send_buffer.front(); 306 369 info->send_buffer.pop_front(); 307 info->mutex.unlock();308 370 309 371 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); 312 374 313 375 // start writing … … 321 383 // handler parameters 322 384 placeholders::error, placeholders::bytes_transferred, 323 info, data.size, data.buffer385 info, send_data->size, send_data->buffer 324 386 ) 325 387 ); … … 332 394 if (error || bytes != (size+4) ) { 333 395 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; 336 401 } 337 402 return; 338 403 } 339 340 cout << "Message sent" << endl; 404 logging_debug( "Message sent" ); 341 405 342 406 // free buffer
Note:
See TracChangeset
for help on using the changeset viewer.