BluetoothConvergenceLayer.h

Go to the documentation of this file.
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     // forward declarations;
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     }; // Listener
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     }; // Connection
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         // 0 indicates no polling
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     }; // NeighborDiscovery
00360 
00361 }; // BluetoothConvergenceLayer
00362 
00363 } // namespace dtn
00364 
00365 #endif /* OASYS_BLUETOOTH_ENABLED */
00366 #endif /* _BT_CONVERGENCE_LAYER_H_ */

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