Go to the documentation of this file.00001 #include "net/LOWPANConvergenceLayer.h"
00002 #include "net/BundleReceivedEvent.h"
00003 #include "core/BundleEvent.h"
00004 #include "net/TransferCompletedEvent.h"
00005 #include "net/TransferAbortedEvent.h"
00006 #include "routing/RequeueBundleEvent.h"
00007 #include <ibrcommon/net/UnicastSocketLowpan.h>
00008 #include "core/BundleCore.h"
00009
00010 #include <ibrcommon/data/BLOB.h>
00011 #include <ibrcommon/Logger.h>
00012 #include <ibrcommon/thread/MutexLock.h>
00013
00014 #include <ibrdtn/utils/Utils.h>
00015 #include <ibrdtn/data/Serializer.h>
00016
00017 #include <sys/socket.h>
00018 #include <poll.h>
00019 #include <errno.h>
00020
00021 #include <sys/types.h>
00022 #include <netinet/in.h>
00023 #include <arpa/inet.h>
00024 #include <unistd.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <fcntl.h>
00029 #include <limits.h>
00030
00031 #include <iostream>
00032
00033
00034 using namespace dtn::data;
00035
00036 namespace dtn
00037 {
00038 namespace net
00039 {
00040 const int LOWPANConvergenceLayer::DEFAULT_PANID = 0x780;
00041
00042 LOWPANConvergenceLayer::LOWPANConvergenceLayer(ibrcommon::NetInterface net, int panid, bool, unsigned int mtu)
00043 : _socket(NULL), _net(net), _panid(panid), m_maxmsgsize(mtu), _running(false)
00044 {
00045 _socket = new ibrcommon::UnicastSocketLowpan();
00046 }
00047
00048 LOWPANConvergenceLayer::~LOWPANConvergenceLayer()
00049 {
00050 componentDown();
00051 delete _socket;
00052 }
00053
00054 dtn::core::Node::Protocol LOWPANConvergenceLayer::getDiscoveryProtocol() const
00055 {
00056 return dtn::core::Node::CONN_ZIGBEE;
00057 }
00058
00059 void LOWPANConvergenceLayer::update(std::string &name, std::string ¶ms)
00060 {
00061 name = "lowpancl";
00062
00063 stringstream service; service << "short address=" << _net.getAddress() << ";panid=" << _panid << ";";
00064 params = service.str();
00065 }
00066
00067 bool LOWPANConvergenceLayer::onInterface(const ibrcommon::NetInterface &net) const
00068 {
00069 if (_net == net) return true;
00070 return false;
00071 }
00072
00073 void LOWPANConvergenceLayer::queue(const dtn::core::Node &node, const ConvergenceLayer::Job &job)
00074 {
00075 std::stringstream ss;
00076 dtn::data::DefaultSerializer serializer(ss);
00077
00078 dtn::core::BundleStorage &storage = dtn::core::BundleCore::getInstance().getStorage();
00079
00080 try {
00081
00082 const dtn::data::Bundle bundle = storage.get(job._bundle);
00083
00084 unsigned int size = serializer.getLength(bundle);
00085
00086 if (size > m_maxmsgsize)
00087 {
00088 throw ConnectionInterruptedException();
00089 }
00090
00091 cout << "CL LOWPAN was asked to connect to " << hex << node.getAddress() << " in PAN " << hex << node.getPort() << endl;
00092
00093 serializer << bundle;
00094 string data = ss.str();
00095
00096
00097 ibrcommon::lowpansocket::peer p = _socket->getPeer(node.getAddress(), node.getPort());
00098
00099
00100 ibrcommon::MutexLock l(m_writelock);
00101
00102
00103 int ret = p.send(data.c_str(), data.length());
00104
00105 if (ret == -1)
00106 {
00107
00108 dtn::routing::RequeueBundleEvent::raise(job._destination, job._bundle);
00109
00110 return;
00111 }
00112
00113
00114 dtn::net::TransferCompletedEvent::raise(job._destination, bundle);
00115 dtn::core::BundleEvent::raise(bundle, dtn::core::BUNDLE_FORWARDED);
00116 } catch (const dtn::core::BundleStorage::NoBundleFoundException&) {
00117
00118 dtn::net::TransferAbortedEvent::raise(EID(node.getURI()), job._bundle, dtn::net::TransferAbortedEvent::REASON_BUNDLE_DELETED);
00119 }
00120 }
00121
00122 LOWPANConvergenceLayer& LOWPANConvergenceLayer::operator>>(dtn::data::Bundle &bundle)
00123 {
00124 ibrcommon::MutexLock l(m_readlock);
00125
00126 char data[m_maxmsgsize];
00127
00128
00129 int len = _socket->receive(data, m_maxmsgsize);
00130
00131 if (len > 0)
00132 {
00133
00134 stringstream ss;
00135 ss.write(data, len);
00136
00137
00138 dtn::data::DefaultDeserializer(ss, dtn::core::BundleCore::getInstance()) >> bundle;
00139 }
00140
00141 return (*this);
00142 }
00143
00144 void LOWPANConvergenceLayer::componentUp()
00145 {
00146 try {
00147 try {
00148 ibrcommon::UnicastSocketLowpan &sock = dynamic_cast<ibrcommon::UnicastSocketLowpan&>(*_socket);
00149 sock.bind(_panid, _net);
00150 } catch (std::bad_cast) {
00151
00152 }
00153 } catch (ibrcommon::lowpansocket::SocketException ex) {
00154 IBRCOMMON_LOGGER(error) << "Failed to add LOWPAN ConvergenceLayer on " << _net.getAddress() << ":" << _panid << IBRCOMMON_LOGGER_ENDL;
00155 IBRCOMMON_LOGGER(error) << " Error: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00156 }
00157 }
00158
00159 void LOWPANConvergenceLayer::componentDown()
00160 {
00161 _running = false;
00162 _socket->shutdown();
00163 join();
00164 }
00165
00166 void LOWPANConvergenceLayer::componentRun()
00167 {
00168 _running = true;
00169
00170 while (_running)
00171 {
00172 try {
00173 dtn::data::Bundle bundle;
00174 (*this) >> bundle;
00175
00176
00177 EID sender;
00178
00179
00180 dtn::net::BundleReceivedEvent::raise(sender, bundle);
00181
00182 } catch (dtn::InvalidDataException ex) {
00183 IBRCOMMON_LOGGER(warning) << "Received a invalid bundle: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00184 } catch (ibrcommon::IOException ex) {
00185
00186 }
00187 yield();
00188 }
00189 }
00190
00191 bool LOWPANConvergenceLayer::__cancellation()
00192 {
00193
00194 return false;
00195 }
00196
00197 const std::string LOWPANConvergenceLayer::getName() const
00198 {
00199 return "LOWPANConvergenceLayer";
00200 }
00201 }
00202 }