IBR-DTNSuite  0.10
DatagramConnection.h
Go to the documentation of this file.
1 /*
2  * DatagramConnection.h
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #ifndef DATAGRAMCONNECTION_H_
23 #define DATAGRAMCONNECTION_H_
24 
25 #include "net/ConvergenceLayer.h"
26 #include "net/DatagramService.h"
28 #include <ibrcommon/thread/Queue.h>
30 #include <streambuf>
31 #include <iostream>
32 #include <vector>
33 #include <stdint.h>
34 
35 namespace dtn
36 {
37  namespace net
38  {
39  class DatagramConnection;
40 
42  {
43  public:
45  virtual void callback_send(DatagramConnection &connection, const char &flags, const unsigned int &seqno, const std::string &destination, const char *buf, const dtn::data::Length &len) throw (DatagramException) = 0;
46  virtual void callback_ack(DatagramConnection &connection, const unsigned int &seqno, const std::string &destination) throw (DatagramException) = 0;
47 
48  virtual void connectionUp(const DatagramConnection *conn) = 0;
49  virtual void connectionDown(const DatagramConnection *conn) = 0;
50  };
51 
53  {
54  public:
55  static const std::string TAG;
56 
57  DatagramConnection(const std::string &identifier, const DatagramService::Parameter &params, DatagramConnectionCallback &callback);
58  virtual ~DatagramConnection();
59 
60  void run() throw ();
61  void setup() throw ();
62  void finally() throw ();
63 
64  virtual void __cancellation() throw ();
65 
66  void shutdown();
67 
68  const std::string& getIdentifier() const;
69 
74  void queue(const dtn::net::BundleTransfer &job);
75 
81  void queue(const char &flags, const unsigned int &seqno, const char *buf, const dtn::data::Length &len);
82 
87  void ack(const unsigned int &seqno);
88 
93  void setPeerEID(const dtn::data::EID &peer);
94 
95  private:
96  enum SEND_FLOW {
97  SEND_IDLE,
98  SEND_WAIT_ACK,
99  SEND_NEXT,
100  SEND_ERROR
101  } _send_state;
102 
103  enum RECV_FLOW {
104  RECV_IDLE,
105  RECV_HEAD,
106  RECV_TRANSMISSION,
107  RECV_ERROR
108  } _recv_state;
109 
110  class Stream : public std::basic_streambuf<char, std::char_traits<char> >, public std::iostream
111  {
112  public:
113  Stream(DatagramConnection &conn, const dtn::data::Length &maxmsglen);
114  virtual ~Stream();
115 
121  void queue(const char *buf, const dtn::data::Length &len) throw (DatagramException);
122 
127  void close();
128 
129  protected:
130  virtual int sync();
131  virtual std::char_traits<char>::int_type overflow(std::char_traits<char>::int_type = std::char_traits<char>::eof());
132  virtual std::char_traits<char>::int_type underflow();
133 
134  private:
135  // buffer size and maximum message size
136  const dtn::data::Length _buf_size;
137 
138  // will be set to true if the next segment is the last
139  // of the bundle
140  bool _last_segment;
141 
142  // buffer for incoming data to queue
143  // the underflow method will block until
144  // this buffer contains any data
145  std::vector<char> _queue_buf;
146 
147  // the number of bytes available in the queue buffer
148  dtn::data::Length _queue_buf_len;
149 
150  // conditional to lock the queue buffer and the
151  // corresponding length variable
152  ibrcommon::Conditional _queue_buf_cond;
153 
154  // outgoing data from the upper layer is stored
155  // here first and processed by the overflow() method
156  std::vector<char> _out_buf;
157 
158  // incoming data to deliver data to the upper layer
159  // is stored in this buffer by the underflow() method
160  std::vector<char> _in_buf;
161 
162  // this variable is set to true to shutdown
163  // this stream
164  bool _abort;
165 
166  // callback to the corresponding connection object
167  DatagramConnection &_callback;
168  };
169 
170  class Sender : public ibrcommon::JoinableThread
171  {
172  public:
173  Sender(DatagramConnection &conn, Stream &stream);
174  ~Sender();
175 
176  void run() throw ();
177  void finally() throw ();
178  void __cancellation() throw ();
179 
180  ibrcommon::Queue<dtn::net::BundleTransfer> queue;
181 
182  private:
183  DatagramConnection::Stream &_stream;
184 
185  // callback to the corresponding connection object
186  DatagramConnection &_connection;
187  };
188 
189  void stream_send(const char *buf, const dtn::data::Length &len, bool last) throw (DatagramException);
190 
191  void adjust_rtt(double value);
192 
193  DatagramConnectionCallback &_callback;
194  const std::string _identifier;
195  DatagramConnection::Stream _stream;
196  DatagramConnection::Sender _sender;
197 
198  ibrcommon::Conditional _ack_cond;
199  unsigned int _last_ack;
200  unsigned int _next_seqno;
201 
202  // stores the head of each connection
203  // the head is hold back until at least a second
204  // or the last segment was received
205  std::vector<char> _head_buf;
206  dtn::data::Length _head_len;
207 
208  const DatagramService::Parameter _params;
209 
210  double _avg_rtt;
211 
212  dtn::data::EID _peer_eid;
213  };
214  } /* namespace data */
215 } /* namespace dtn */
216 #endif /* DATAGRAMCONNECTION_H_ */