|
IBR-DTNSuite 0.6
|
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; // FIXME CONN_LOWPAN instead? 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 const std::list<dtn::core::Node::URI> uri_list = node.get(dtn::core::Node::CONN_ZIGBEE); 00089 if (uri_list.empty()) return; 00090 00091 std::stringstream ss; 00092 dtn::data::DefaultSerializer serializer(ss); 00093 00094 dtn::core::BundleStorage &storage = dtn::core::BundleCore::getInstance().getStorage(); 00095 00096 try { 00097 // read the bundle out of the storage 00098 const dtn::data::Bundle bundle = storage.get(job._bundle); 00099 00100 unsigned int size = serializer.getLength(bundle); 00101 00102 if (size > m_maxmsgsize) 00103 { 00104 throw ConnectionInterruptedException(); 00105 } 00106 00107 const dtn::core::Node::URI &uri = uri_list.front(); 00108 00109 std::string address = "0"; 00110 unsigned int pan = 0x00; 00111 00112 // read values 00113 uri.decode(address, pan); 00114 00115 cout << "CL LOWPAN was asked to connect to " << hex << address << " in PAN " << hex << pan << endl; 00116 00117 serializer << bundle; 00118 string data = ss.str(); 00119 00120 // get a lowpan peer //FIXME should be getPan not getPort 00121 ibrcommon::lowpansocket::peer p = _socket->getPeer(address, pan); 00122 00123 // set write lock 00124 ibrcommon::MutexLock l(m_writelock); 00125 00126 // send converted line back to client. 00127 int ret = p.send(data.c_str(), data.length()); 00128 00129 if (ret == -1) 00130 { 00131 // CL is busy, requeue bundle 00132 dtn::routing::RequeueBundleEvent::raise(job._destination, job._bundle); 00133 00134 return; 00135 } 00136 00137 // raise bundle event 00138 dtn::net::TransferCompletedEvent::raise(job._destination, bundle); 00139 dtn::core::BundleEvent::raise(bundle, dtn::core::BUNDLE_FORWARDED); 00140 } catch (const dtn::core::BundleStorage::NoBundleFoundException&) { 00141 // send transfer aborted event 00142 dtn::net::TransferAbortedEvent::raise(EID(node.getEID()), job._bundle, dtn::net::TransferAbortedEvent::REASON_BUNDLE_DELETED); 00143 } 00144 } 00145 00146 LOWPANConvergenceLayer& LOWPANConvergenceLayer::operator>>(dtn::data::Bundle &bundle) 00147 { 00148 ibrcommon::MutexLock l(m_readlock); 00149 00150 char data[m_maxmsgsize]; 00151 00152 // data waiting 00153 int len = _socket->receive(data, m_maxmsgsize); 00154 00155 if (len > 0) 00156 { 00157 // read all data into a stream 00158 stringstream ss; 00159 ss.write(data, len); 00160 00161 // get the bundle 00162 dtn::data::DefaultDeserializer(ss, dtn::core::BundleCore::getInstance()) >> bundle; 00163 } 00164 00165 return (*this); 00166 } 00167 00168 void LOWPANConvergenceLayer::componentUp() 00169 { 00170 try { 00171 try { 00172 ibrcommon::UnicastSocketLowpan &sock = dynamic_cast<ibrcommon::UnicastSocketLowpan&>(*_socket); 00173 sock.bind(_panid, _net); 00174 } catch (const std::bad_cast&) { 00175 00176 } 00177 } catch (const ibrcommon::lowpansocket::SocketException &ex) { 00178 IBRCOMMON_LOGGER(error) << "Failed to add LOWPAN ConvergenceLayer on " << _net.toString() << ":" << _panid << IBRCOMMON_LOGGER_ENDL; 00179 IBRCOMMON_LOGGER(error) << " Error: " << ex.what() << IBRCOMMON_LOGGER_ENDL; 00180 } 00181 } 00182 00183 void LOWPANConvergenceLayer::componentDown() 00184 { 00185 _running = false; 00186 _socket->shutdown(); 00187 join(); 00188 } 00189 00190 void LOWPANConvergenceLayer::componentRun() 00191 { 00192 _running = true; 00193 00194 while (_running) 00195 { 00196 try { 00197 dtn::data::Bundle bundle; 00198 (*this) >> bundle; 00199 00200 // determine sender 00201 EID sender; 00202 00203 // raise default bundle received event 00204 dtn::net::BundleReceivedEvent::raise(sender, bundle); 00205 00206 } catch (const dtn::InvalidDataException &ex) { 00207 IBRCOMMON_LOGGER(warning) << "Received a invalid bundle: " << ex.what() << IBRCOMMON_LOGGER_ENDL; 00208 } catch (const ibrcommon::IOException&) { 00209 00210 } 00211 yield(); 00212 } 00213 } 00214 00215 bool LOWPANConvergenceLayer::__cancellation() 00216 { 00217 // since this is an receiving thread we have to cancel the hard way 00218 return false; 00219 } 00220 00221 const std::string LOWPANConvergenceLayer::getName() const 00222 { 00223 return "LOWPANConvergenceLayer"; 00224 } 00225 } 00226 }