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