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 "Bluetooth.h"
00021 #include "BluetoothServer.h"
00022 #include "debug/Log.h"
00023
00024 #include <errno.h>
00025 #include <sys/types.h>
00026 #include <sys/socket.h>
00027 #include <netinet/in.h>
00028
00029 namespace oasys {
00030
00031 BluetoothServer::BluetoothServer(int socktype,
00032 BluetoothSocket::proto_t proto,
00033 char* logbase)
00034 : BluetoothSocket(socktype, proto, logbase)
00035 {
00036 }
00037
00038 int
00039 BluetoothServer::listen()
00040 {
00041
00042
00043
00044
00045 logf(LOG_DEBUG, "listening");
00046 ASSERT(fd_ != -1);
00047
00048 if (::listen(fd_, SOMAXCONN) == -1) {
00049 logf(LOG_ERR, "error in listen(): %s",strerror(errno));
00050 return -1;
00051 }
00052
00053 set_state(LISTENING);
00054 return 0;
00055 }
00056
00057 int
00058 BluetoothServer::accept(int *fd, bdaddr_t *addr, u_int8_t *channel)
00059 {
00060 ASSERTF(state_ == LISTENING,
00061 "accept() expected state LISTENING, not %s", statetoa(state_));
00062
00063 struct sockaddr sa;
00064 socklen_t sl = sizeof(sa);
00065 memset(&sa,0,sl);
00066
00067 int ret = ::accept(fd_,&sa,&sl);
00068 if (ret == -1) {
00069 logf(LOG_ERR, "error in accept(): %s",strerror(errno));
00070 return ret;
00071 }
00072
00073 *fd = ret;
00074
00075 switch(proto_) {
00076 case RFCOMM:
00077 rc_ = (struct sockaddr_rc*) &sa;
00078 bacpy(addr,&rc_->rc_bdaddr);
00079 *channel = rc_->rc_channel;
00080 break;
00081 default:
00082 ASSERTF(0,"not implemented for %s",prototoa((proto_t)proto_));
00083 break;
00084 }
00085
00086 monitor(IO::ACCEPT, 0);
00087
00088 return 0;
00089 }
00090
00091 int
00092 BluetoothServer::timeout_accept(int *fd, bdaddr_t *addr, u_int8_t *channel,
00093 int timeout_ms)
00094 {
00095 int ret = poll_sockfd(POLLIN, NULL, timeout_ms);
00096
00097 if (ret != 1) return ret;
00098 ASSERT(ret == 1);
00099
00100 ret = accept(fd, addr, channel);
00101
00102 if (ret < 0) {
00103 return IOERROR;
00104 }
00105
00106 monitor(IO::ACCEPT, 0);
00107
00108 return 0;
00109 }
00110
00111 void
00112 BluetoothServerThread::run()
00113 {
00114 int fd;
00115 bdaddr_t addr;
00116 u_int8_t channel;
00117
00118 while (1) {
00119
00120
00121 if (should_stop())
00122 break;
00123
00124
00125
00126 int ret;
00127 if (accept_timeout_ == -1) {
00128 ret = accept(&fd, &addr, &channel);
00129 } else {
00130 ret = timeout_accept(&fd, &addr, &channel, accept_timeout_);
00131 if (ret == IOTIMEOUT)
00132 continue;
00133 }
00134
00135 if (ret != 0) {
00136 if (errno == EINTR || ret == IOINTR)
00137 continue;
00138
00139 logf(LOG_ERR, "error %d in accept(): %d %s",
00140 ret, errno, strerror(errno));
00141 close();
00142
00143 ASSERT(errno != 0);
00144
00145 break;
00146 }
00147
00148 logf(LOG_DEBUG, "accepted connection fd %d from %s(%d)",
00149 fd, bd2str(addr), channel);
00150
00151 set_remote_addr(addr);
00152
00153 accepted(fd, addr, channel);
00154 }
00155 }
00156
00157 int
00158 BluetoothServerThread::bind_listen_start(bdaddr_t local_addr,
00159 u_int8_t local_channel)
00160 {
00161 if(bind(local_addr, local_channel) != 0)
00162 return -1;
00163
00164 if(listen() != 0)
00165 return -1;
00166
00167 start();
00168
00169 return 0;
00170 }
00171
00172 }
00173 #endif