00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef _STREAM_CONVERGENCE_LAYER_H_
00039 #define _STREAM_CONVERGENCE_LAYER_H_
00040
00041 #include "ConnectionConvergenceLayer.h"
00042 #include "CLConnection.h"
00043
00044 namespace dtn {
00045
00097 class StreamConvergenceLayer : public ConnectionConvergenceLayer {
00098 public:
00102 StreamConvergenceLayer(const char* logpath, const char* cl_name,
00103 u_int8_t cl_version);
00104
00105 protected:
00109 typedef enum {
00110 SEGMENT_ACK_ENABLED = 0x1,
00111 REACTIVE_FRAG_ENABLED = 0x2,
00112 } contact_header_flags_t;
00113
00119 struct ContactHeader {
00120 u_int32_t magic;
00121 u_int8_t version;
00122 u_int8_t flags;
00123 u_int16_t keepalive_interval;
00124 } __attribute__((packed));
00125
00129 typedef enum {
00130 START_BUNDLE = 0x1,
00131 END_BUNDLE = 0x2,
00132 DATA_SEGMENT = 0x3,
00133
00134 ACK_SEGMENT = 0x4,
00135
00136 KEEPALIVE = 0x5,
00137 SHUTDOWN = 0x6,
00138 } stream_cl_header_type_t;
00139
00143 class StreamLinkParams : public ConnectionConvergenceLayer::LinkParams {
00144 public:
00145 bool segment_ack_enabled_;
00146 u_int keepalive_interval_;
00147 u_int segment_length_;
00148
00149 protected:
00150
00151 StreamLinkParams(bool init_defaults);
00152 };
00153
00157 u_int8_t cl_version_;
00158
00162 class Connection : public CLConnection {
00163 public:
00167 Connection(const char* classname,
00168 const char* logpath,
00169 ConvergenceLayer* cl,
00170 StreamLinkParams* params,
00171 bool active_connector);
00172
00174 bool send_pending_data();
00175 void handle_send_bundle(Bundle* bundle);
00176 void handle_cancel_bundle(Bundle* bundle);
00177 void handle_poll_timeout();
00179
00180 protected:
00185 virtual void send_data() = 0;
00186
00188 void initiate_contact();
00189 void process_data();
00191
00192 private:
00194 void note_data_rcvd();
00195 void note_data_sent();
00196 bool send_pending_acks();
00197 bool start_next_bundle();
00198 bool send_next_segment(InFlightBundle* inflight);
00199 bool send_data_todo(InFlightBundle* inflight);
00200 bool finish_bundle(InFlightBundle* inflight);
00201 void check_completed(InFlightBundle* inflight);
00202 void send_keepalive();
00203
00204 void handle_contact_initiation();
00205 bool handle_start_bundle();
00206 bool handle_end_bundle();
00207 bool handle_data_segment();
00208 bool handle_data_todo();
00209 bool handle_ack_segment();
00210 bool handle_keepalive();
00211 bool handle_shutdown();
00213
00218 StreamLinkParams* stream_lparams()
00219 {
00220 StreamLinkParams* ret = dynamic_cast<StreamLinkParams*>(params_);
00221 ASSERT(ret != NULL);
00222 return ret;
00223 }
00224
00225 protected:
00226 InFlightBundle* current_inflight_;
00227 size_t send_segment_todo_;
00228 size_t recv_segment_todo_;
00229 struct timeval data_rcvd_;
00230 struct timeval data_sent_;
00231 struct timeval keepalive_sent_;
00232 };
00233
00235 typedef ConnectionConvergenceLayer::LinkParams LinkParams;
00236
00238 void dump_link(Link* link, oasys::StringBuffer* buf);
00240
00242 bool parse_link_params(LinkParams* params,
00243 int argc, const char** argv,
00244 const char** invalidp);
00245 bool finish_init_link(Link* link, LinkParams* params);
00247
00248 };
00249
00250 }
00251
00252 #endif