00001 #include <config.h>
00002 #ifdef OASYS_BLUETOOTH_ENABLED
00003
00004 #include <stdlib.h>
00005 #include <sys/types.h>
00006 #include <sys/socket.h>
00007 #include <errno.h>
00008
00009 #include <bluetooth/bluetooth.h>
00010 #include <bluetooth/hci.h>
00011 #include <bluetooth/rfcomm.h>
00012
00013 #include "../io/IO.h"
00014 #include "Bluetooth.h"
00015 #include "BluetoothSocket.h"
00016 #include "../debug/Log.h"
00017
00018 namespace oasys {
00019
00020 int BluetoothSocket::abort_on_error_ = 0;
00021
00022 BluetoothSocket::BluetoothSocket(int socktype,
00023 proto_t proto,
00024 const char* logbase)
00025 : Logger("BluetoothSocket", logbase)
00026 {
00027 state_ = INIT;
00028 memset(&local_addr_,0,sizeof(bdaddr_t));
00029 channel_ = 0;
00030 memset(&remote_addr_,0,sizeof(bdaddr_t));
00031 fd_ = -1;
00032 socktype_ = socktype;
00033 proto_ = (proto_t) proto;
00034 logfd_ = true;
00035 sa_ = NULL;
00036 slen_ = -1;
00037 reuse_addr_ = false;
00038 silent_connect_ = false;
00039 }
00040
00041 BluetoothSocket::BluetoothSocket(int socktype, proto_t proto, int sock,
00042 bdaddr_t remote_addr, u_int8_t remote_channel,
00043 const char* logbase)
00044 : Logger("BluetoothSocket", logbase)
00045 {
00046 sa_ = NULL;
00047 fd_ = sock;
00048 proto_ = (proto_t) proto;
00049 logpathf("%s/%s/%d",logbase,prototoa((proto_t)proto_),sock);
00050 socktype_ = socktype;
00051 state_ = ESTABLISHED;
00052 bacpy(&local_addr_,BDADDR_ANY);
00053 channel_ = remote_channel;
00054 set_remote_addr(remote_addr);
00055
00056 silent_connect_ = false;
00057 configure();
00058 }
00059
00060 BluetoothSocket::~BluetoothSocket()
00061 {
00062 if (sa_ != NULL) delete sa_;
00063 sa_ = NULL;
00064 close();
00065 }
00066
00067 void
00068 BluetoothSocket::init_socket()
00069 {
00070
00071 ASSERT(state_ == INIT || state_ == FINI);
00072 ASSERT(fd_ == -1);
00073 state_ = INIT;
00074
00075 fd_ = socket(PF_BLUETOOTH, socktype_, (int) proto_);
00076 if (fd_ == -1) {
00077 logf(LOG_ERR, "error creating socket: %s", strerror(errno));
00078 if(errno==EBADFD) close();
00079 return;
00080 }
00081
00082 if (logfd_)
00083 Logger::logpath_appendf("/%s/%d",
00084 prototoa((proto_t)proto_),
00085 fd_);
00086
00087 logf(LOG_DEBUG, "created socket %d of protocol %s", fd_,
00088 prototoa((proto_t)proto_));
00089
00090 configure();
00091 }
00092
00093 int
00094 BluetoothSocket::bind(bdaddr_t local_addr, u_int8_t local_channel)
00095 {
00096 if (fd_ == -1) init_socket();
00097
00098 set_local_addr(local_addr);
00099 channel_ = local_channel;
00100
00101 char buff[18];
00102 if (!silent_connect_)
00103 logf(LOG_DEBUG, "binding to %s(%d)", Bluetooth::batostr(&local_addr,buff),
00104 local_channel);
00105
00106 init_sa((int)LOCAL);
00107
00108 if(::bind(fd_,sa_,slen_) != 0) {
00109 log_level_t level = LOG_ERR;
00110 if(errno == EADDRINUSE) level = LOG_DEBUG;
00111 if (!silent_connect_)
00112 logf(level, "failed to bind to %s(%d): %s",
00113 Bluetooth::batostr(&local_addr_,buff), channel_,
00114 strerror(errno));
00115 if(errno==EBADFD) close();
00116 return -1;
00117 }
00118
00119 return 0;
00120 }
00121
00122 int
00123 BluetoothSocket::bind()
00124 {
00125 return bind(local_addr_,channel_);
00126 }
00127
00128 int
00129 BluetoothSocket::connect(bdaddr_t remote_addr, u_int8_t remote_channel)
00130 {
00131
00132
00133
00134 if (fd_ == -1) init_socket();
00135
00136 set_remote_addr(remote_addr);
00137 channel_ = remote_channel;
00138
00139 char buff[18];
00140 log_debug("connecting to %s(%d)",Bluetooth::batostr(&remote_addr_,buff),
00141 channel_);
00142
00143 init_sa((int)REMOTE);
00144 rc_->rc_channel=channel_;
00145 bacpy(&rc_->rc_bdaddr,&remote_addr);
00146
00147 set_state(CONNECTING);
00148
00149 if (::connect(fd_,sa_,slen_) < 0) {
00150 if (errno == EISCONN && !silent_connect_)
00151 log_debug("already connected to %s-%u",
00152 Bluetooth::batostr(&remote_addr_,buff), channel_);
00153 else if (errno == EINPROGRESS && !silent_connect_) {
00154 log_debug("delayed connect to %s-%u",
00155 Bluetooth::batostr(&remote_addr_,buff), channel_);
00156 } else if(errno==EBADFD) {
00157 if (!silent_connect_) log_err("EBADFD");
00158 close();
00159 } else {
00160 if (!silent_connect_)
00161 log_debug("error connecting to %s(%d): %s",
00162 Bluetooth::batostr(&remote_addr_,buff), channel_,
00163 strerror(errno));
00164 }
00165 return -1;
00166 }
00167
00168 set_state(ESTABLISHED);
00169
00170 return 0;
00171 }
00172
00173 int
00174 BluetoothSocket::async_connect_result()
00175 {
00176 ASSERT(state_ == CONNECTING);
00177
00178 int result;
00179 socklen_t len = sizeof(result);
00180 logf(LOG_DEBUG, "getting connect result");
00181 if (::getsockopt(fd_, SOL_SOCKET, SO_ERROR, &result, &len) != 0) {
00182 logf(LOG_ERR, "error getting connect result: %s", strerror(errno));
00183 return errno;
00184 }
00185
00186 if (result == 0) {
00187 state_ = ESTABLISHED;
00188 }
00189
00190 return result;
00191 }
00192
00193 int
00194 BluetoothSocket::connect()
00195 {
00196 return connect(remote_addr_,channel_);
00197 }
00198
00199 void
00200 BluetoothSocket::configure()
00201 {
00202 ASSERT(fd_ != -1);
00203
00204 if (params_.reuseaddr_) {
00205 int y = 1;
00206 logf(LOG_DEBUG, "setting SO_REUSEADDR");
00207 if (::setsockopt(fd_, SOL_SOCKET, SO_REUSEADDR, &y, sizeof y) != 0) {
00208 logf(LOG_WARN, "error setting SO_REUSEADDR: %s",
00209 strerror(errno));
00210 }
00211 }
00212
00213 if (params_.recv_bufsize_ > 0) {
00214 logf(LOG_DEBUG, "setting SO_RCVBUF to %d",
00215 params_.recv_bufsize_);
00216 if (::setsockopt(fd_, SOL_SOCKET, SO_RCVBUF,
00217 ¶ms_.recv_bufsize_,
00218 sizeof(params_.recv_bufsize_)) < 0)
00219 {
00220 logf(LOG_WARN, "error setting SO_RCVBUF to %d: %s",
00221 params_.recv_bufsize_, strerror(errno));
00222 }
00223 }
00224
00225 if (params_.send_bufsize_ > 0) {
00226 logf(LOG_DEBUG, "setting SO_SNDBUF to %d",
00227 params_.send_bufsize_);
00228 if (::setsockopt(fd_, SOL_SOCKET, SO_SNDBUF,
00229 ¶ms_.send_bufsize_,
00230 sizeof(params_.send_bufsize_)) < 0)
00231 {
00232 logf(LOG_WARN, "error setting SO_SNDBUF to %d: %s",
00233 params_.send_bufsize_, strerror(errno));
00234 }
00235 }
00236
00237 init_sa((int)ZERO);
00238 }
00239
00240 int
00241 BluetoothSocket::close()
00242 {
00243 logf(LOG_DEBUG, "closing socket in state %s", statetoa(state_));
00244
00245 if (fd_ == -1) {
00246 ASSERT(state_ == INIT || state_ == FINI);
00247 return 0;
00248 }
00249
00250 if (::close(fd_) != 0) {
00251 logf(LOG_ERR, "error closing socket in state %s: %s",
00252 statetoa(state_), strerror(errno));
00253 return -1;
00254 }
00255
00256 set_state(FINI);
00257 fd_ = -1;
00258 return 0;
00259 }
00260
00261 int
00262 BluetoothSocket::shutdown(int how)
00263 {
00264 const char* howstr;
00265
00266 switch (how) {
00267 case SHUT_RD: howstr = "R"; break;
00268 case SHUT_WR: howstr = "W"; break;
00269 case SHUT_RDWR: howstr = "RW"; break;
00270
00271 default:
00272 logf(LOG_ERR, "shutdown invalid mode %d", how);
00273 return -1;
00274 }
00275
00276 logf(LOG_DEBUG, "shutdown(%s) state %s", howstr, statetoa(state_));
00277
00278 if (state_ == INIT || state_ == FINI) {
00279 ASSERT(fd_ == -1);
00280 return 0;
00281 }
00282
00283 if (::shutdown(fd_, how) != 0) {
00284 logf(LOG_ERR, "error in shutdown(%s) state %s: %s",
00285 howstr, statetoa(state_), strerror(errno));
00286 }
00287 if (state_ == ESTABLISHED) {
00288 if (how == SHUT_RD) { set_state(RDCLOSED); }
00289 if (how == SHUT_WR) { set_state(WRCLOSED); }
00290 if (how == SHUT_RDWR) { set_state(CLOSED); }
00291
00292 } else if (state_ == RDCLOSED && how == SHUT_WR) {
00293 set_state(CLOSED);
00294
00295 } else if (state_ == WRCLOSED && how == SHUT_RD) {
00296 set_state(CLOSED);
00297
00298 } else {
00299 logf(LOG_ERR, "invalid state %s for shutdown(%s)",
00300 statetoa(state_), howstr);
00301 return -1;
00302 }
00303
00304 return 0;
00305 }
00306
00307 const char*
00308 BluetoothSocket::statetoa(state_t state)
00309 {
00310 switch (state) {
00311 case INIT: return "INIT";
00312 case LISTENING: return "LISTENING";
00313 case CONNECTING: return "CONNECTING";
00314 case ESTABLISHED: return "ESTABLISHED";
00315 case RDCLOSED: return "RDCLOSED";
00316 case WRCLOSED: return "WRCLOSED";
00317 case CLOSED: return "CLOSED";
00318 case FINI: return "FINI";
00319 }
00320 ASSERT(0);
00321 return NULL;
00322 }
00323
00324 void
00325 BluetoothSocket::set_state(state_t state)
00326 {
00327 logf(LOG_DEBUG, "state %s -> %s", statetoa(state_),
00328 statetoa(state));
00329 state_ = state;
00330 }
00331
00332 const char*
00333 BluetoothSocket::prototoa(proto_t proto)
00334 {
00335 switch (proto) {
00336 case L2CAP: return "L2CAP";
00337 case HCI: return "HCI";
00338 case SCO: return "SCO";
00339 case RFCOMM: return "RFCOMM";
00340 case BNEP: return "BNEP";
00341 case CMTP: return "CMTP";
00342 case HIDP: return "HIDP";
00343 case AVDTP: return "AVDTP";
00344 }
00345 ASSERT(0);
00346 return NULL;
00347 }
00348
00349 void
00350 BluetoothSocket::set_proto(proto_t proto)
00351 {
00352 logf(LOG_DEBUG, "protocol %s -> %s", prototoa((proto_t)proto_),
00353 prototoa((proto_t)proto));
00354 proto_ = proto;
00355 }
00356
00357 int
00358 BluetoothSocket::send(const char* bp, size_t len, int flags)
00359 {
00360 return IO::send(fd_, bp, len, flags, get_notifier(), logpath_);
00361 }
00362
00363 int
00364 BluetoothSocket::recv(char* bp, size_t len, int flags)
00365 {
00366 return IO::recv(fd_, bp, len, flags, get_notifier(), logpath_);
00367 }
00368
00369 int
00370 BluetoothSocket::fd()
00371 {
00372 return fd_;
00373 }
00374
00375 bdaddr_t
00376 BluetoothSocket::local_addr()
00377 {
00378 if (!bacmp(BDADDR_ANY,&local_addr_)) get_local();
00379 return local_addr_;
00380 }
00381
00382 void
00383 BluetoothSocket::local_addr(bdaddr_t& addr)
00384 {
00385 if (!bacmp(&addr,&local_addr_)) get_local();
00386 bacpy(&addr,&local_addr_);
00387 }
00388
00389 u_int8_t
00390 BluetoothSocket::channel()
00391 {
00392 if (channel_ == 0) get_local();
00393 return channel_;
00394 }
00395
00396 bdaddr_t
00397 BluetoothSocket::remote_addr()
00398 {
00399 if (!bacmp(BDADDR_ANY,&remote_addr_)) get_remote();
00400 return remote_addr_;
00401 }
00402
00403 void
00404 BluetoothSocket::remote_addr(bdaddr_t& addr)
00405 {
00406 if (!bacmp(&addr,&remote_addr_)) get_remote();
00407 bacpy(&addr,&remote_addr_);
00408 }
00409
00410 void
00411 BluetoothSocket::set_local_addr(bdaddr_t& addr)
00412 {
00413 bacpy(&local_addr_,&addr);
00414 }
00415
00416 void
00417 BluetoothSocket::set_channel(u_int8_t channel)
00418 {
00419
00420 ASSERT(channel >= 1 && channel <= 30);
00421 channel_ = channel;
00422 }
00423
00424 void
00425 BluetoothSocket::set_remote_addr(bdaddr_t& addr)
00426 {
00427 bacpy(&remote_addr_,&addr);
00428 }
00429
00430 void
00431 BluetoothSocket::get_local()
00432 {
00433 if (fd_ < 0)
00434 return;
00435
00436 init_sa((int)ZERO);
00437 socklen_t slen = sizeof(struct sockaddr);
00438 if(::getsockname(fd_, sa_, &slen) == 0) {
00439 switch (proto_) {
00440 case L2CAP:
00441 case HCI:
00442 case SCO:
00443 break;
00444 case RFCOMM:
00445 rc_ = (struct sockaddr_rc *) sa_;
00446 bacpy(&local_addr_,&rc_->rc_bdaddr);
00447 channel_ = rc_->rc_channel;
00448 break;
00449
00450 case BNEP:
00451 case CMTP:
00452 case HIDP:
00453 case AVDTP:
00454 default:
00455 break;
00456 }
00457 }
00458 }
00459
00460 bdaddr_t*
00461 BluetoothSocket::sa_baddr()
00462 {
00463 ASSERT(sa_ != NULL);
00464 switch (proto_) {
00465 case L2CAP:
00466 case HCI:
00467 case SCO:
00468 break;
00469 case RFCOMM:
00470 rc_ = (struct sockaddr_rc*) sa_;
00471 return &rc_->rc_bdaddr;
00472 case BNEP:
00473 case CMTP:
00474 case HIDP:
00475 case AVDTP:
00476 default:
00477 break;
00478 }
00479 ASSERT(0);
00480 return NULL;
00481 }
00482
00483 u_int8_t
00484 BluetoothSocket::sa_channel()
00485 {
00486 ASSERT(sa_ != NULL);
00487 switch (proto_) {
00488 case L2CAP:
00489 case HCI:
00490 case SCO:
00491 break;
00492 case RFCOMM:
00493 rc_ = (struct sockaddr_rc*) sa_;
00494 return rc_->rc_channel;
00495 case BNEP:
00496 case CMTP:
00497 case HIDP:
00498 case AVDTP:
00499 default:
00500 break;
00501 }
00502 ASSERT(0);
00503 return 0;
00504 }
00505
00506 void
00507 BluetoothSocket::get_remote()
00508 {
00509 if (fd_ < 0)
00510 return;
00511
00512 init_sa((int)ZERO);
00513 socklen_t slen = sizeof(struct sockaddr);
00514 if(::getpeername(fd_, sa_, &slen) == 0) {
00515 switch (proto_) {
00516 case L2CAP:
00517 case HCI:
00518 case SCO:
00519 break;
00520 case RFCOMM:
00521 rc_ = (struct sockaddr_rc *) sa_;
00522 bacpy(&remote_addr_,&rc_->rc_bdaddr);
00523 channel_ = rc_->rc_channel;
00524 break;
00525 case BNEP:
00526 case CMTP:
00527 case HIDP:
00528 case AVDTP:
00529 default:
00530 break;
00531 }
00532 }
00533 }
00534
00535 void
00536 BluetoothSocket::init_sa(int sa_type)
00537 {
00538 if (sa_ == NULL) {
00539 sa_ = new sockaddr();
00540 }
00541 memset(sa_,0,sizeof(struct sockaddr));
00542 if( sa_type == (int) ZERO ) return;
00543
00544 switch (proto_) {
00545 case L2CAP:
00546 case HCI:
00547 case SCO:
00548 break;
00549 case RFCOMM:
00550
00551 ASSERT(channel_ >= 1 && channel_ <= 30);
00552 slen_ = sizeof(struct sockaddr_rc);
00553 rc_ = (struct sockaddr_rc*) sa_;
00554 rc_->rc_family = AF_BLUETOOTH;
00555 if( sa_type == (int) LOCAL ) {
00556 bacpy(&rc_->rc_bdaddr,&local_addr_);
00557 rc_->rc_channel = channel_;
00558 } else {
00559 bacpy(&rc_->rc_bdaddr,&remote_addr_);
00560 rc_->rc_channel = channel_;
00561 }
00562 return;
00563 case BNEP:
00564 case CMTP:
00565 case HIDP:
00566 case AVDTP:
00567 default:
00568 break;
00569 }
00570 ASSERT(0);
00571 }
00572
00573 int
00574 BluetoothSocket::poll_sockfd(int events, int* revents, int timeout_ms)
00575 {
00576 short s_events = events;
00577 short s_revents;
00578
00579 int cc = IO::poll_single(fd_, s_events, &s_revents, timeout_ms,
00580 get_notifier(), logpath_);
00581
00582 if (revents != 0) {
00583 *revents = s_revents;
00584 }
00585
00586 return cc;
00587 }
00588
00589 int RFCOMMChannel::rc_channel_ = -1;
00590 SpinLock RFCOMMChannel::lock_ = SpinLock();
00591
00592 int
00593 RFCOMMChannel::next() {
00594 ScopeLock l(&lock_,"RFCOMMChannel::next");
00595 ++rc_channel_;
00596 rc_channel_ %= 30;
00597 int next = rc_channel_ + 1;
00598 return next;
00599 }
00600
00601 }
00602 #endif