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