BluetoothServer.cc

Go to the documentation of this file.
00001 #include <config.h>
00002 #ifdef OASYS_BLUETOOTH_ENABLED
00003 
00004 #include "Bluetooth.h"
00005 #include "BluetoothServer.h"
00006 #include "debug/Log.h"
00007 
00008 #include <errno.h>
00009 #include <sys/types.h>
00010 #include <sys/socket.h>
00011 #include <netinet/in.h>
00012 
00013 namespace oasys {
00014 
00015 BluetoothServer::BluetoothServer(int socktype,
00016                                  BluetoothSocket::proto_t proto,
00017                                  char* logbase)
00018     : BluetoothSocket(socktype, proto, logbase)
00019 {
00020 }
00021 
00022 int
00023 BluetoothServer::listen()
00024 {
00025     // In Bluetooth, piconets are formed by one Master
00026     // connecting to up to seven Slaves.  The device
00027     // performing connect() is the Master ... thus the
00028     // device performing listen()/accept() is the Slave.
00029     logf(LOG_DEBUG, "listening");
00030     ASSERT(fd_ != -1);
00031 
00032     if (::listen(fd_, SOMAXCONN) == -1) {
00033         logf(LOG_ERR, "error in listen(): %s",strerror(errno));
00034         return -1;
00035     }
00036     
00037     set_state(LISTENING);
00038     return 0;
00039 }
00040     
00041 int
00042 BluetoothServer::accept(int *fd, bdaddr_t *addr, u_int8_t *channel)
00043 {
00044     ASSERT(state_ == LISTENING);
00045     
00046     init_sa(BluetoothSocket::ZERO); // zero out sockaddr
00047 
00048     int ret = poll_sockfd(POLLIN, NULL, -1); // wait forever
00049 
00050     if (ret == -1) {
00051         if (errno != EINTR)
00052             logf(LOG_ERR, "error in accept(): %s [%s:%d]",
00053                  strerror(errno),
00054                  __FILE__,__LINE__);
00055         return ret;
00056     } else if(ret != 1) return ret;
00057 
00058     ret = ::accept(fd_,sa_,(socklen_t*)&slen_);
00059     if (ret == -1) return ret;
00060     
00061     *fd = ret;
00062     bacpy(addr,sa_baddr());
00063     *channel = sa_channel();
00064 
00065     monitor(IO::ACCEPT, 0); // XXX/bowei
00066 
00067     return 0;
00068 }
00069 
00070 int
00071 BluetoothServer::timeout_accept(int *fd, bdaddr_t *addr,
00072                                 u_int8_t *channel, int timeout_ms)
00073 {
00074     int ret = poll_sockfd(POLLIN, NULL, timeout_ms);
00075 
00076     if (ret != 1) return ret;
00077     ASSERT(ret == 1);
00078 
00079     ret = accept(fd, addr, channel);
00080 
00081     if (ret < 0) {
00082         return IOERROR;
00083     }
00084 
00085     monitor(IO::ACCEPT, 0); // XXX/bowei
00086 
00087     return 0;
00088 }
00089 
00090 void
00091 BluetoothServerThread::run()
00092 {
00093     int fd;
00094     bdaddr_t addr;
00095     u_int8_t channel;
00096 
00097     while (1) {
00098         // check if someone has told us to quit by setting the
00099         // should_stop flag. if so, we're all done.
00100         if (should_stop())
00101             break;
00102 
00103         // check the accept_timeout parameter to see if we should
00104         // block or poll when calling accept
00105         int ret;
00106         if (accept_timeout_ == -1) {
00107             ret = accept(&fd, &addr, &channel);
00108         } else {
00109             ret = timeout_accept(&fd, &addr, &channel, accept_timeout_);
00110             if (ret == IOTIMEOUT)
00111                 continue;
00112         }
00113 
00114         if (ret != 0) {
00115             if (errno == EINTR || ret == IOINTR) 
00116                 continue;
00117 
00118             logf(LOG_ERR, "error in accept() [%d]: %d %s [%s:%d]",
00119                  ret, errno, strerror(errno),
00120                  __FILE__,__LINE__);
00121             close();
00122 
00123             ASSERT(errno != 0);
00124 
00125             break;
00126         }
00127         
00128         char buff[18];
00129         logf(LOG_DEBUG, "accepted connection fd %d from %s(%d)",
00130              fd, Bluetooth::batostr(&addr,buff), channel);
00131 
00132         set_remote_addr(addr);
00133 
00134         set_remote_addr(addr);
00135 
00136         accepted(fd, addr, channel);
00137     }
00138 }
00139 
00140 int
00141 BluetoothServerThread::bind_listen_start(bdaddr_t local_addr,
00142                                   u_int8_t local_channel)
00143 {
00144     if(bind(local_addr, local_channel) != 0)
00145         return -1;
00146 
00147     if(listen() != 0)
00148         return -1;
00149 
00150     start();
00151 
00152     return 0;
00153 }
00154 
00155 } // namespace oasys
00156 #endif /* OASYS_BLUETOOTH_ENABLED */

Generated on Fri Dec 22 14:47:57 2006 for DTN Reference Implementation by  doxygen 1.5.1