IBR-DTN  1.0.0
LOWPANConnection.cpp
Go to the documentation of this file.
1 /*
2  * LOWPANConnection.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 
22 #include "net/LOWPANConnection.h"
24 #include "core/BundleEvent.h"
25 #include "core/BundleCore.h"
26 
27 #include <ibrcommon/Logger.h>
28 #include <ibrcommon/thread/MutexLock.h>
29 
30 #include <ibrdtn/utils/Utils.h>
31 #include <ibrdtn/data/Serializer.h>
32 
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 
38 #include <iostream>
39 #include <list>
40 
41 using namespace dtn::data;
42 
43 namespace dtn
44 {
45  namespace net
46  {
47  LOWPANConnection::LOWPANConnection(const ibrcommon::vaddress &address, LOWPANConvergenceLayer &cl)
48  : _address(address), _sender(_stream), _stream(cl, address), _cl(cl)
49  {
50  }
51 
53  {
54  }
55 
56  ibrcommon::lowpanstream& LOWPANConnection::getStream()
57  {
58  return _stream;
59  }
60 
61  void LOWPANConnection::setup() throw ()
62  {
63  _sender.start();
64  }
65 
66  void LOWPANConnection::finally() throw ()
67  {
68  _sender.stop();
69  _sender.join();
70 
71  // remove this connection from the connection list
72  _cl.remove(this);
73  }
74 
75  void LOWPANConnection::run() throw ()
76  {
77  try {
78  // create a filter context
80  context.setProtocol(_cl.getDiscoveryProtocol());
81 
82  while(_stream.good())
83  {
84  try {
86  dtn::data::Bundle bundle;
87  deserializer >> bundle;
88 
89  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "LOWPANConnection::run"<< IBRCOMMON_LOGGER_ENDL;
90 
91  // determine sender
92  std::stringstream ss; ss << "lowpan:" << _address.address() << "." << _address.service();
93  EID sender(ss.str());
94 
95  // push bundle through the filter routines
96  context.setBundle(bundle);
97  context.setPeer(sender);
99 
100  if (ret == BundleFilter::ACCEPT) {
101  // raise default bundle received event
102  dtn::net::BundleReceivedEvent::raise(sender, bundle, false);
103  }
104  } catch (const dtn::InvalidDataException &ex) {
105  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "Received a invalid bundle: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
106  } catch (const ibrcommon::IOException &ex) {
107  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "IOException: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
108  }
109  }
110  } catch (std::exception &ex) {
111  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "Thread died: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
112  }
113  }
114 
116  {
117  _sender.stop();
118  }
119 
120  // class LOWPANConnectionSender
121  LOWPANConnectionSender::LOWPANConnectionSender(ibrcommon::lowpanstream &stream)
122  : _stream(stream)
123  {
124  }
125 
127  {
128  }
129 
131  {
132  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 85) << "queue"<< IBRCOMMON_LOGGER_ENDL;
133  _queue.push(job);
134  }
135 
137  {
138  try {
139  // create a filter context
140  dtn::core::FilterContext context;
142 
143  while(_stream.good())
144  {
145  dtn::net::BundleTransfer job = _queue.poll();
146  dtn::data::DefaultSerializer serializer(_stream);
147 
148  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 85) << "run"<< IBRCOMMON_LOGGER_ENDL;
149 
151 
152  // read the bundle out of the storage
153  dtn::data::Bundle bundle = storage.get(job.getBundle());
154 
155  // push bundle through the filter routines
156  context.setPeer(job.getNeighbor());
157  context.setBundle(bundle);
159 
160  if (ret != BundleFilter::ACCEPT) {
162  continue;
163  }
164 
165  // Put bundle into stringstream
166  serializer << bundle; _stream.flush();
167  // raise bundle event
168  job.complete();
169  }
170  // FIXME: Exit strategy when sending on socket failed. Like destroying the connection object
171  // Also check what needs to be done when the node is not reachable (transfer requeue...)
172 
173  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 45) << "stream destroyed"<< IBRCOMMON_LOGGER_ENDL;
174  } catch (std::exception &ex) {
175  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 40) << "Thread died: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
176  }
177  }
178 
180  {
181  _queue.abort();
182  }
183  }
184 }
const ibrcommon::vaddress _address
void remove(const LOWPANConnection *conn)
void setBundle(const dtn::data::Bundle &data)
BundleFilter::ACTION filter(BundleFilter::TABLE table, const FilterContext &context, dtn::data::Bundle &bundle) const
Definition: BundleCore.cpp:598
void setProtocol(const dtn::core::Node::Protocol &protocol)
void setPeer(const dtn::data::EID &endpoint)
const dtn::data::EID & getNeighbor() const
virtual dtn::data::Bundle get(const dtn::data::BundleID &id)=0
dtn::core::Node::Protocol getDiscoveryProtocol() const
void abort(const TransferAbortedEvent::AbortReason reason)
const dtn::data::MetaBundle & getBundle() const
ibrcommon::lowpanstream & getStream()
LOWPANConnectionSender(ibrcommon::lowpanstream &_stream)
dtn::storage::BundleStorage & getStorage()
Definition: BundleCore.cpp:237
LOWPANConnectionSender _sender
static void raise(const dtn::data::EID &peer, const dtn::data::Bundle &bundle, const bool local=false)
static BundleCore & getInstance()
Definition: BundleCore.cpp:82
void queue(const dtn::net::BundleTransfer &job)