00001 #ifndef _BT_CONVERGENCE_LAYER_H_
00002 #define _BT_CONVERGENCE_LAYER_H_
00003
00004 #include <config.h>
00005 #ifdef OASYS_BLUETOOTH_ENABLED
00006
00007 #include <oasys/bluez/RFCOMMClient.h>
00008 #include <oasys/bluez/RFCOMMServer.h>
00009 #include <oasys/bluez/BluetoothSDP.h>
00010 #include <oasys/bluez/BluetoothInquiry.h>
00011
00012 #include <time.h>
00013 #include <set>
00014 #include <map>
00015 using namespace std;
00016
00017 #include <oasys/util/ScratchBuffer.h>
00018 #include <oasys/util/StreamBuffer.h>
00019 #include "bundling/BundleEvent.h"
00020 #include "ConvergenceLayer.h"
00021
00022 namespace dtn {
00023
00024 class BluetoothConvergenceLayer : public ConvergenceLayer {
00025 public:
00026
00030 static const u_int8_t BTCL_VERSION = 0x01;
00031
00035 typedef enum {
00036 BUNDLE_ACK_ENABLED = 0x1,
00037 } contact_header_flags_t;
00038
00042 struct BTCLHeader {
00043 u_int32_t magic;
00044 u_int8_t version;
00045 u_int8_t flags;
00046 u_int16_t partial_ack_len;
00047 u_int16_t keepalive_interval;
00048 u_int16_t xx__unused;
00049 u_int32_t payload_size_;
00050 } __attribute__((packed));
00051
00058 typedef enum {
00059 BUNDLE_DATA = 0x1,
00060 BUNDLE_ACK = 0x2,
00061 KEEPALIVE = 0x3,
00062 SHUTDOWN = 0x4,
00063 } btcl_header_type_t;
00064
00068 struct BundleDataHeader {
00069 u_int32_t bundle_id;
00070 u_char total_length[0];
00071 } __attribute__((packed));
00072
00076 struct BundleAckHeader {
00077 u_int32_t bundle_id;
00078 u_int32_t acked_length;
00079 } __attribute__((packed));
00080
00092 class Params : public CLInfo {
00093 public:
00094 bdaddr_t local_addr_;
00095 bdaddr_t remote_addr_;
00096 std::string hcidev_;
00097 bool bundle_ack_enabled_;
00098 u_int partial_ack_len_;
00099 u_int writebuf_len_;
00100 u_int readbuf_len_;
00101 u_int keepalive_interval_;
00102 u_int retry_interval_;
00103 u_int min_retry_interval_;
00104 u_int max_retry_interval_;
00105 u_int16_t idle_close_time;
00106 u_int rtt_timeout_;
00107 u_int neighbor_poll_interval_;
00108 };
00109
00110 protected:
00111
00112 class Listener;
00113 class Connection;
00114 class NeighborDiscovery;
00115
00116 public:
00126 class ConnectionManager : public Logger {
00127 public:
00128 ConnectionManager() :
00129 Logger("BluetoothConvergenceLayer::ConnectionManager",
00130 "/dtn/cl/bt/connmgr")
00131 {
00132 l_map_.clear();
00133 }
00134 ~ConnectionManager() {;}
00135
00139 Listener *listener(BluetoothConvergenceLayer*,Params*);
00140
00144 Connection *connection(BluetoothConvergenceLayer*,bdaddr_t&,Params*);
00145
00146 bool del_listener(Listener*);
00147
00148 protected:
00149 Listener* listener(bdaddr_t&);
00150 void addListener(Listener*);
00151 bool delListener(Listener*);
00152
00153 struct less_bdaddr_ {
00154 bool operator() (const bdaddr_t& a, const bdaddr_t& b) const {
00155 return (bacmp(&a,&b) < 0);
00156 }
00157 };
00158
00159 typedef std::map<bdaddr_t,Listener*,less_bdaddr_> adapter_map;
00160 typedef adapter_map::iterator adapter_map_i;
00161 adapter_map l_map_;
00162 adapter_map_i it_;
00163 };
00164
00165 BluetoothConvergenceLayer();
00166
00167 bool init_link(Link* link, int argc, const char* argv[]);
00168 void dump_link(Link* link, oasys::StringBuffer* buf);
00169 bool interface_up(Interface* iface, int argc, const char* argv[]);
00170 bool interface_down(Interface* iface);
00171 void dump_interface(Interface* iface, oasys::StringBuffer* buf);
00172 bool open_contact(const ContactRef& contact);
00173 bool close_contact(const ContactRef& contact);
00174 void send_bundle(const ContactRef&,Bundle*);
00175
00176 static Params defaults_;
00177 static ConnectionManager connections_;
00178
00179 protected:
00180 bool parse_params(Params* params, int argc, const char** argv,
00181 const char** invalidp);
00182 bool parse_nexthop(const char*, bdaddr_t*);
00183
00188 class Listener : public CLInfo,
00189 public oasys::RFCOMMServerThread
00190 {
00191 public:
00195 Listener(BluetoothConvergenceLayer *cl,
00196 BluetoothConvergenceLayer::Params* params);
00197
00201 void accepted(int fd, bdaddr_t addr, u_int8_t channel);
00202
00203 BluetoothConvergenceLayer::Params params_;
00204
00205 NeighborDiscovery* nd_;
00206
00207 protected:
00208 friend class Connection;
00209 friend class ConnectionManager;
00210 BluetoothConvergenceLayer* cl_;
00211 };
00212
00216 class Connection : public CLInfo,
00217 public oasys::Thread,
00218 public oasys::Logger {
00219 public:
00223 Connection(BluetoothConvergenceLayer* cl,
00224 bdaddr_t remote_addr,
00225 Params* params);
00226
00230 Connection(BluetoothConvergenceLayer* cl,
00231 int fd,
00232 bdaddr_t remote_addr,
00233 u_int8_t channel,
00234 Params* params);
00235
00239 ~Connection();
00240
00244 BluetoothConvergenceLayer::Params params_;
00245
00246 void set_contact(const ContactRef& c) { contact_ = c; }
00247
00251 bool passive() { return (!initiate_); }
00252
00256 void interrupt_from_io() { sock_->interrupt_from_io(); }
00257
00258 protected:
00259 friend class BluetoothConvergenceLayer;
00260 friend class NeighborDiscovery;
00261 friend class ConnectionManager;
00262 friend class Listener;
00263
00264 virtual void run();
00265 void recv_loop();
00266 void send_loop();
00267 void break_contact(ContactEvent::reason_t reason);
00268 bool connect();
00269 bool accept();
00270 bool send_contact_header();
00271 bool recv_contact_header(int timeout);
00272 bool send_address();
00273 bool recv_address(int timeout);
00274 bool send_bundle(Bundle* bundle);
00275 bool send_announce();
00276 bool recv_bundle();
00277 void recv_announce();
00278 bool handle_reply();
00279 int handle_ack();
00280 bool send_ack(u_int32_t bundle_id, size_t acked_len);
00281 bool send_keepalive();
00282 void note_data_rcvd();
00283
00286 struct InFlightBundle {
00287 InFlightBundle(Bundle* b)
00288 : bundle_(b, "BTCL::InFlightBundle"), acked_len_(0) {}
00289 InFlightBundle(const InFlightBundle& other)
00290 : bundle_(other.bundle_),
00291 xmit_start_time_(other.xmit_start_time_),
00292 xmit_finish_time_(other.xmit_finish_time_),
00293 acked_len_(other.acked_len_) {}
00294
00295 BundleRef bundle_;
00296 struct timeval xmit_start_time_;
00297 struct timeval xmit_finish_time_;
00298 size_t acked_len_;
00299 };
00300
00302 typedef std::list<InFlightBundle> InFlightList;
00303
00304 Listener* listener_;
00305 BluetoothConvergenceLayer* cl_;
00306 bool initiate_;
00307 oasys::RFCOMMClient* sock_;
00308 ContactRef contact_;
00309 oasys::StreamBuffer rcvbuf_;
00310 oasys::ScratchBuffer<u_char*> sndbuf_;
00311 BlockingBundleList* queue_;
00312 InFlightList inflight_;
00313 oasys::Notifier* event_notifier_;
00314 BundleRef announce_;
00315
00316 struct timeval data_rcvd_;
00317 struct timeval keepalive_sent_;
00318 };
00319
00320 class NeighborDiscovery : public oasys::BluetoothInquiry,
00321 public oasys::Thread
00322 {
00323 public:
00324 NeighborDiscovery(BluetoothConvergenceLayer *cl,
00325 Params* params,
00326 const char* logpath = "/dtn/cl/bt/neighbordiscovery") :
00327 Thread("NeighborDiscovery"),
00328 cl_(cl),
00329 params_(*params)
00330 {
00331 poll_interval_ = params->neighbor_poll_interval_;
00332 ASSERT(poll_interval_ > 0);
00333 Thread::set_flag(Thread::INTERRUPTABLE);
00334 set_logpath(logpath);
00335 }
00336
00337 ~NeighborDiscovery() {
00338 }
00339
00340 u_int poll_interval() {
00341 return poll_interval_;
00342 }
00343
00344
00345 void poll_interval(u_int poll_int) {
00346 poll_interval_ = poll_int;
00347 }
00348
00349 protected:
00350 friend class Connection;
00351
00352 void run();
00353 void send_announce(bdaddr_t remote);
00354
00355 u_int poll_interval_;
00356 BluetoothConvergenceLayer* cl_;
00357 Params params_;
00358
00359 };
00360
00361 };
00362
00363 }
00364
00365 #endif
00366 #endif