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