IBR-DTNSuite  0.10
StreamConnection.cpp
Go to the documentation of this file.
1 /*
2  * StreamConnection.cpp
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 
23 #include "ibrdtn/data/Exceptions.h"
26 #include "ibrdtn/data/Exceptions.h"
28 #include <ibrcommon/Logger.h>
29 
30 using namespace dtn::data;
31 
32 namespace dtn
33 {
34  namespace streams
35  {
36  StreamConnection::StreamConnection(StreamConnection::Callback &cb, iostream &stream, const dtn::data::Length buffer_size)
37  : std::iostream(&_buf), _callback(cb), _buf(*this, stream, buffer_size), _shutdown_reason(CONNECTION_SHUTDOWN_NOTSET)
38  {
39  }
40 
42  {
43  }
44 
46  {
47  // create a new header
49 
50  // set timeout
51  header._keepalive = static_cast<uint16_t>(timeout);
52 
53  // set flags
54  header._flags = flags;
55 
56  // do the handshake
57  _peer = _buf.handshake(header);
58 
59  // signal the complete handshake
60  _callback.eventConnectionUp(_peer);
61  }
62 
64  {
65  _buf.reject();
66  }
67 
69  {
70  _buf.keepalive();
71  }
72 
74  {
76  {
77  // wait for the last ACKs
78  _buf.wait();
79  }
80 
81  // skip if another shutdown is in progress
82  {
83  ibrcommon::MutexLock l(_shutdown_reason_lock);
84  if (_shutdown_reason != CONNECTION_SHUTDOWN_NOTSET)
85  {
86  _buf.abort();
87  return;
88  }
89  _shutdown_reason = csc;
90  }
91 
92  try {
93  switch (csc)
94  {
97  _buf.abort();
98  _callback.eventTimeout();
99  break;
101  _buf.abort();
102  _callback.eventError();
103  break;
106  _callback.eventShutdown(csc);
107  break;
109  _buf.abort();
110  _callback.eventTimeout();
111  break;
114  _buf.abort();
115  _callback.eventShutdown(csc);
116  break;
118  _buf.abort();
119  _callback.eventShutdown(csc);
120  break;
121  }
122  } catch (const StreamConnection::StreamErrorException&) {
123  _callback.eventError();
124  }
125 
126  _buf.close();
127  _callback.eventConnectionDown();
128  }
129 
130  void StreamConnection::eventShutdown(StreamConnection::ConnectionShutdownCases csc)
131  {
132  _callback.eventShutdown(csc);
133  }
134 
135  void StreamConnection::eventBundleAck(const dtn::data::Length &ack)
136  {
137  _callback.eventBundleAck(ack);
138  }
139 
140  void StreamConnection::eventBundleRefused()
141  {
142  IBRCOMMON_LOGGER_DEBUG_TAG("StreamConnection", 20) << "bundle has been refused" << IBRCOMMON_LOGGER_ENDL;
143  _callback.eventBundleRefused();
144  }
145 
146  void StreamConnection::eventBundleForwarded()
147  {
148  IBRCOMMON_LOGGER_DEBUG_TAG("StreamConnection", 20) << "bundle has been forwarded" << IBRCOMMON_LOGGER_ENDL;
149  _callback.eventBundleForwarded();
150  }
151 
152  void StreamConnection::connectionTimeout()
153  {
154  // call superclass
155  _callback.eventTimeout();
156  }
157 
159  {
160  _buf.enableIdleTimeout(seconds);
161  }
162 
164  {
165  _buf._monitor = val;
166  }
167 
169  {
170  _buf._monitor_stats[0] = 0;
171  _buf._monitor_stats[1] = 0;
172  }
173 
175  {
176  return _buf._monitor_stats[index];
177  }
178  }
179 }