00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _CLCONNECTION_H_
00018 #define _CLCONNECTION_H_
00019
00020 #include <list>
00021 #include <oasys/debug/Log.h>
00022 #include <oasys/thread/Atomic.h>
00023 #include <oasys/thread/MsgQueue.h>
00024 #include <oasys/thread/Thread.h>
00025 #include <oasys/util/SparseBitmap.h>
00026 #include <oasys/util/StreamBuffer.h>
00027
00028 #include "ConnectionConvergenceLayer.h"
00029 #include "bundling/Bundle.h"
00030 #include "bundling/BundleEvent.h"
00031
00032 namespace dtn {
00033
00038 class CLConnection : public CLInfo,
00039 public oasys::Thread,
00040 public oasys::Logger {
00041 public:
00042 friend class ConnectionConvergenceLayer;
00043 typedef ConnectionConvergenceLayer::LinkParams LinkParams;
00044
00048 CLConnection(const char* classname,
00049 const char* logpath,
00050 ConnectionConvergenceLayer* cl,
00051 LinkParams* params,
00052 bool active_connector);
00053
00057 virtual ~CLConnection();
00058
00062 void set_contact(const ContactRef& contact) { contact_ = contact; }
00063
00064 protected:
00068 void run();
00069
00072 virtual void contact_up();
00073 virtual void break_contact(ContactEvent::reason_t reason);
00074 virtual void process_command();
00075 virtual bool find_contact(const EndpointID& peer_eid);
00077
00081 void set_nexthop(const std::string& nexthop) {
00082 nexthop_ = nexthop;
00083 }
00084
00088 virtual void connect() = 0;
00089
00096 virtual void accept() { NOTREACHED; }
00097
00101 virtual void disconnect() = 0;
00102
00107 virtual void initialize_pollfds() = 0;
00108
00112 virtual void handle_bundles_queued() = 0;
00113
00117 virtual void handle_cancel_bundle(Bundle* b) = 0;
00118
00129 virtual bool send_pending_data() = 0;
00130
00134 virtual void handle_poll_activity() = 0;
00135
00139 virtual void handle_poll_timeout() = 0;
00140
00145 typedef enum {
00146 CLMSG_INVALID = 0,
00147 CLMSG_BUNDLES_QUEUED = 1,
00148 CLMSG_CANCEL_BUNDLE = 2,
00149 CLMSG_BREAK_CONTACT = 3,
00150 } clmsg_t;
00151
00155 const char* clmsg_to_str(clmsg_t type) {
00156 switch(type) {
00157 case CLMSG_INVALID: return "CLMSG_INVALID";
00158 case CLMSG_BUNDLES_QUEUED: return "CLMSG_BUNDLES_QUEUED";
00159 case CLMSG_CANCEL_BUNDLE: return "CLMSG_CANCEL_BUNDLE";
00160 case CLMSG_BREAK_CONTACT: return "CLMSG_BREAK_CONTACT";
00161 default: PANIC("bogus clmsg_t");
00162 }
00163 }
00164
00169 struct CLMsg {
00170 CLMsg()
00171 : type_(CLMSG_INVALID),
00172 bundle_("ConnectionConvergenceLayer::CLMsg") {}
00173
00174 CLMsg(clmsg_t type)
00175 : type_(type),
00176 bundle_("ConnectionConvergenceLayer::CLMsg") {}
00177
00178 CLMsg(clmsg_t type, const BundleRef& bundle)
00179 : type_(type),
00180 bundle_(bundle.object(), "ConnectionConvergenceLayer::CLMsg") {}
00181
00182 clmsg_t type_;
00183 BundleRef bundle_;
00184 };
00185
00189 typedef oasys::SparseBitmap<u_int32_t> DataBitmap;
00190
00195 class InFlightBundle {
00196 public:
00197 InFlightBundle(Bundle* b)
00198 : bundle_(b, "CLConnection::InFlightBundle"),
00199 total_length_(0),
00200 send_complete_(false),
00201 transmit_event_posted_(false)
00202 {}
00203
00204 BundleRef bundle_;
00205 BlockInfoVec* blocks_;
00206
00207 u_int32_t total_length_;
00208 bool send_complete_;
00209 bool transmit_event_posted_;
00210
00211 DataBitmap sent_data_;
00212 DataBitmap ack_data_;
00213
00214 private:
00215
00216
00217 InFlightBundle(const InFlightBundle& copy);
00218 };
00219
00223 typedef std::list<InFlightBundle*> InFlightList;
00224
00230 class IncomingBundle {
00231 public:
00232 IncomingBundle(Bundle* b)
00233 : bundle_(b, "CLConnection::IncomingBundle"),
00234 total_length_(0),
00235 acked_length_(0) {}
00236
00237 BundleRef bundle_;
00238
00239 u_int32_t total_length_;
00240 u_int32_t acked_length_;
00241
00242 DataBitmap rcvd_data_;
00243 DataBitmap ack_data_;
00244 private:
00245
00246
00247 IncomingBundle(const IncomingBundle& copy);
00248 };
00249
00253 typedef std::list<IncomingBundle*> IncomingList;
00254
00255 ContactRef contact_;
00256 bool contact_up_;
00257 oasys::SpinLock cmdqueue_lock_;
00258 oasys::MsgQueue<CLMsg> cmdqueue_;
00259 ConnectionConvergenceLayer* cl_;
00260
00261 LinkParams* params_;
00262
00263 bool active_connector_;
00264 std::string nexthop_;
00265 int num_pollfds_;
00266 static const int MAXPOLL = 8;
00267 struct pollfd pollfds_[MAXPOLL];
00268 int poll_timeout_;
00269 oasys::StreamBuffer sendbuf_;
00270 oasys::StreamBuffer recvbuf_;
00271 InFlightList inflight_;
00272 IncomingList incoming_;
00273 volatile bool contact_broken_;
00274 oasys::atomic_t num_pending_;
00275 };
00276
00277 }
00278
00279 #endif