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