IBR-DTNSuite  0.10
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>
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 
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  while(_stream.good())
79  {
80  try {
82  dtn::data::Bundle bundle;
83  deserializer >> bundle;
84 
85  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "LOWPANConnection::run"<< IBRCOMMON_LOGGER_ENDL;
86 
87  // determine sender
88  std::stringstream ss; ss << "lowpan:" << _address.address() << "." << _address.service();
89  EID sender(ss.str());
90 
91  // raise default bundle received event
92  dtn::net::BundleReceivedEvent::raise(sender, bundle, false);
93 
94  } catch (const dtn::InvalidDataException &ex) {
95  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "Received a invalid bundle: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
96  } catch (const ibrcommon::IOException &ex) {
97  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "IOException: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
98  }
99  }
100  } catch (std::exception &ex) {
101  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnection", 10) << "Thread died: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
102  }
103  }
104 
106  {
107  _sender.stop();
108  }
109 
110  // class LOWPANConnectionSender
112  : _stream(stream)
113  {
114  }
115 
117  {
118  }
119 
121  {
122  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 85) << "queue"<< IBRCOMMON_LOGGER_ENDL;
123  _queue.push(job);
124  }
125 
127  {
128  try {
129  while(_stream.good())
130  {
131  dtn::net::BundleTransfer job = _queue.getnpop(true);
132  dtn::data::DefaultSerializer serializer(_stream);
133 
134  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 85) << "run"<< IBRCOMMON_LOGGER_ENDL;
135 
137 
138  // read the bundle out of the storage
139  const dtn::data::Bundle bundle = storage.get(job.getBundle());
140 
141  // Put bundle into stringstream
142  serializer << bundle; _stream.flush();
143  // raise bundle event
144  job.complete();
145  }
146  // FIXME: Exit strategy when sending on socket failed. Like destroying the connection object
147  // Also check what needs to be done when the node is not reachable (transfer requeue...)
148 
149  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 45) << "stream destroyed"<< IBRCOMMON_LOGGER_ENDL;
150  } catch (std::exception &ex) {
151  IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConnectionSender", 40) << "Thread died: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
152  }
153  }
154 
156  {
157  _queue.abort();
158  }
159  }
160 }