28 #include <ibrcommon/net/lowpanstream.h>
29 #include <ibrcommon/net/lowpansocket.h>
31 #include <ibrcommon/Logger.h>
32 #include <ibrcommon/thread/MutexLock.h>
33 #include <ibrcommon/TimeMeasurement.h>
35 #include <sys/socket.h>
43 #define EXTENDED_MASK 0x08
44 #define SEQ_NUM_MASK 0x07
46 using namespace dtn::data;
54 LOWPANConvergenceLayer::LOWPANConvergenceLayer(
const ibrcommon::vinterface &net, uint16_t panid,
unsigned int mtu)
55 : _net(net), _panid(panid), m_maxmsgsize(mtu),
_running(false)
62 _addr_broadcast = ibrcommon::vaddress(
"0xffff", ss.str(), AF_IEEE802154);
81 struct sockaddr_ieee802154 address;
82 address.addr.addr_type = IEEE802154_ADDR_SHORT;
83 address.addr.pan_id = _panid;
86 ibrcommon::lowpansocket::getAddress(&address.addr, iface);
89 service <<
"ip=" << address.addr.short_addr <<
";port=" << _panid <<
";";
91 announcement.addService(
DiscoveryService(getDiscoveryProtocol(), service.str()));
101 ibrcommon::socketset socks = _vsocket.getAll();
102 if (socks.size() == 0)
return;
103 ibrcommon::lowpansocket &sock =
dynamic_cast<ibrcommon::lowpansocket&
>(**socks.begin());
106 ibrcommon::MutexLock l(m_writelock);
108 if (_addr_broadcast == addr) {
110 sock.setAutoAck(
false);
113 sock.sendto(buf, len, 0, _addr_broadcast);
116 sock.setAutoAck(
true);
119 sock.sendto(buf, len, 0, addr);
126 if (uri_list.empty())
return;
135 std::stringstream ss_pan; ss_pan << pan;
137 ibrcommon::vaddress addr( address, ss_pan.str(), AF_IEEE802154 );
139 IBRCOMMON_LOGGER_DEBUG_TAG(
"LOWPANConvergenceLayer", 55) <<
"LOWPANConvergenceLayer::queue"<< IBRCOMMON_LOGGER_ENDL;
141 ibrcommon::MutexLock lc(_connection_lock);
146 LOWPANConnection* LOWPANConvergenceLayer::getConnection(
const ibrcommon::vaddress &addr)
149 for(std::list<LOWPANConnection*>::iterator i = ConnectionList.begin(); i != ConnectionList.end(); ++i)
153 IBRCOMMON_LOGGER_DEBUG_TAG(
"LOWPANConvergenceLayer", 55) <<
"Connection address: " << conn.
_address.toString() << IBRCOMMON_LOGGER_ENDL;
162 ConnectionList.push_back(connection);
163 IBRCOMMON_LOGGER_DEBUG_TAG(
"LOWPANConvergenceLayer", 55) <<
"LOWPANConvergenceLayer::getConnection "<< connection->
_address.toString() << IBRCOMMON_LOGGER_ENDL;
170 ibrcommon::MutexLock lc(_connection_lock);
172 std::list<LOWPANConnection*>::iterator i;
173 for(i = ConnectionList.begin(); i != ConnectionList.end(); ++i)
177 ConnectionList.erase(i);
186 _vsocket.add(
new ibrcommon::lowpansocket(_panid, _net));
191 }
catch (
const ibrcommon::socket_exception &ex) {
192 IBRCOMMON_LOGGER_TAG(
"LOWPANConvergenceLayer", error) <<
"bind to " << _net.toString() <<
":" << _panid <<
" failed (" << ex.what() <<
")" << IBRCOMMON_LOGGER_ENDL;
211 if (_net != iface)
return;
213 IBRCOMMON_LOGGER_DEBUG_TAG(
"LOWPANConvergenceLayer", 60) <<
"LOWPAN IPND beacon send started" << IBRCOMMON_LOGGER_ENDL;
220 ipnd_buf[1] = (char)0x80;
228 IBRCOMMON_LOGGER_TAG(
"LOWPANConvergenceLayer", error) <<
"Discovery announcement to big (" << len <<
")" << IBRCOMMON_LOGGER_ENDL;
231 memcpy(&ipnd_buf[2], ss.str().c_str(), len);
234 send_cb(&ipnd_buf[0], len + 2, _addr_broadcast);
244 ibrcommon::socketset readfds;
245 _vsocket.select(&readfds, NULL, NULL, NULL);
247 for (ibrcommon::socketset::iterator iter = readfds.begin(); iter != readfds.end(); ++iter) {
248 ibrcommon::lowpansocket &sock =
dynamic_cast<ibrcommon::lowpansocket&
>(**iter);
250 std::vector<char> data(m_maxmsgsize);
254 ibrcommon::vaddress peeraddr;
257 ssize_t len = sock.recvfrom(&data[0], static_cast<size_t>(m_maxmsgsize), 0, peeraddr);
259 IBRCOMMON_LOGGER_DEBUG_TAG(
"LOWPANConvergenceLayer", 40) <<
"Received IEEE 802.15.4 frame from " << peeraddr.toString() << IBRCOMMON_LOGGER_ENDL;
272 ss.write(&data[2], len-2);
279 if (!beacon.isShort())
287 ibrcommon::MutexLock lc(_connection_lock);
293 connection->
getStream().queue(&data[0], len);
295 }
catch (
const ibrcommon::socket_exception&) {
311 return "LOWPANConvergenceLayer";
void decode(std::string &address, unsigned int &port) const
virtual void componentRun()
DiscoveryBeacon obtainBeacon() const
virtual const std::string getName() const
void onAdvertiseBeacon(const ibrcommon::vinterface &iface, const DiscoveryBeacon &beacon)
static dtn::data::EID local
const ibrcommon::vaddress _address
void remove(const LOWPANConnection *conn)
void onUpdateBeacon(const ibrcommon::vinterface &iface, DiscoveryBeacon &announcement)
dtn::net::DiscoveryAgent & getDiscoveryAgent()
void unregisterService(const ibrcommon::vinterface &iface, const dtn::net::DiscoveryBeaconHandler *handler)
virtual void send_cb(const char *buf, const size_t len, const ibrcommon::vaddress &addr)
virtual ~LOWPANConvergenceLayer()
virtual void componentDown()
std::list< URI > get(Node::Protocol proto) const
void onBeaconReceived(const DiscoveryBeacon &beacon)
dtn::core::Node::Protocol getDiscoveryProtocol() const
ibrcommon::lowpanstream & getStream()
void registerService(const ibrcommon::vinterface &iface, dtn::net::DiscoveryBeaconHandler *handler)
virtual void componentUp()
void queue(const dtn::core::Node &n, const dtn::net::BundleTransfer &job)
LOWPANConnectionSender _sender
static BundleCore & getInstance()
void queue(const dtn::net::BundleTransfer &job)