26 #include <ibrcommon/Logger.h>
34 #include <netinet/in.h>
42 : _version(version), _flags(BEACON_NO_FLAGS), _canonical_eid(eid), _sn(0), _period(1)
55 return (_flags & DiscoveryBeacon::BEACON_SHORT);
58 return !(_flags & DiscoveryBeacon::BEACON_CONTAINS_EID);
71 return _canonical_eid;
91 for (service_list::const_iterator iter = _services.begin(); iter != _services.end(); ++iter)
93 if ((*iter).getName() == name)
104 for (service_list::iterator iter = _services.begin(); iter != _services.end(); ++iter)
106 if ((*iter).getName() == name)
117 _services.push_back(service);
144 switch (announcement._version)
148 if (services.empty())
150 const unsigned char flags = DiscoveryBeacon::BEACON_SHORT | announcement._flags;
162 for (dtn::net::DiscoveryBeacon::service_list::const_iterator iter = services.begin(); iter != services.end(); ++iter)
164 beacon_len += (*iter).getLength();
169 for (dtn::net::DiscoveryBeacon::service_list::const_iterator iter = services.begin(); iter != services.end(); ++iter)
179 unsigned char flags = 0;
185 flags |= DiscoveryBeacon::BEACON_CONTAINS_EID;
188 if (!services.empty())
190 flags |= DiscoveryBeacon::BEACON_SERVICE_BLOCK;
193 if ( announcement._period > 1 )
195 flags |= DiscoveryBeacon::BEACON_CONTAINS_PERIOD;
201 const uint16_t sn = htons(announcement._sn);
202 stream.write( (
const char*)&sn, 2 );
204 if ( flags & DiscoveryBeacon::BEACON_CONTAINS_EID )
210 if ( flags & DiscoveryBeacon::BEACON_SERVICE_BLOCK )
214 for (dtn::net::DiscoveryBeacon::service_list::const_iterator iter = services.begin(); iter != services.end(); ++iter)
221 if ( flags & DiscoveryBeacon::BEACON_CONTAINS_PERIOD )
224 stream << announcement._period;
234 uint8_t interval = 10;
236 uint16_t inet_port = htons(4556);
237 std::string eid = announcement._canonical_eid.
getString();
238 uint16_t eid_len = htons((uint16_t)eid.length());
239 unsigned int add_zeros = (4 - (eid.length() % 4)) % 4;
240 uint16_t length = htons(static_cast<uint16_t>(12 + eid.length() + add_zeros));
243 stream << (
unsigned char)cl_type;
244 stream.write((
char*)&interval, 1);
245 stream.write((
char*)&length, 2);
256 stream.write(&zero, 1);
257 stream.write(&zero, 1);
258 stream.write(&zero, 1);
259 stream.write(&zero, 1);
261 stream.write((
char*)&inet_port, 2);
262 stream.write((
char*)&eid_len, 2);
265 for (
unsigned int i = 0; i < add_zeros; ++i)
267 stream.write((
char*)&zero, 1);
279 unsigned char version = 0;
290 version = (
unsigned char)stream.get();
297 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 60) <<
"beacon version 1 received" << IBRCOMMON_LOGGER_ENDL;
302 stream.
get((
char&)announcement._flags);
305 if (DiscoveryBeacon::BEACON_SHORT == announcement._flags)
311 stream >> beacon_len;
312 int remain = beacon_len.
get<
int>();
316 remain -=
static_cast<int>(eid.getLength());
318 announcement._canonical_eid =
dtn::data::EID((
const std::string&)eid);
331 services.push_back(service);
332 remain -=
static_cast<int>(service.getLength());
339 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 60) <<
"beacon version 2 received" << IBRCOMMON_LOGGER_ENDL;
341 stream.get((
char&)announcement._flags);
343 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 85) <<
"beacon flags: " << hex << (int)announcement._flags << IBRCOMMON_LOGGER_ENDL;
346 stream.read((
char*)&sn, 2);
349 uint16_t sequencenumber = ntohs(sn);
351 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 85) <<
"beacon sequence number: " << sequencenumber << IBRCOMMON_LOGGER_ENDL;
353 if (announcement._flags & DiscoveryBeacon::BEACON_CONTAINS_EID)
358 announcement._canonical_eid =
dtn::data::EID((
const std::string&)eid);
360 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 85) <<
"beacon eid: " << (std::string)eid << IBRCOMMON_LOGGER_ENDL;
363 if (announcement._flags & DiscoveryBeacon::BEACON_SERVICE_BLOCK)
370 stream >> num_services;
372 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 85) <<
"beacon services (" << num_services.
toString() <<
"): " << IBRCOMMON_LOGGER_ENDL;
377 for (
unsigned int i = 0; num_services > i; ++i)
382 services.push_back(service);
384 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 85) <<
"\t " << service.
getName() <<
" [" << service.getParameters() <<
"]" << IBRCOMMON_LOGGER_ENDL;
388 if (announcement._flags & DiscoveryBeacon::BEACON_BLOOMFILTER)
391 stream >> announcement._bloomfilter;
395 if (announcement._flags & DiscoveryBeacon::BEACON_CONTAINS_PERIOD)
398 stream >> announcement._period;
413 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 60) <<
"beacon IPDiscovery (DTN2) frame received" << IBRCOMMON_LOGGER_ENDL;
415 stream.read((
char*)&cl_type, 1);
416 stream.read((
char*)&interval, 1);
417 stream.read((
char*)&length, 2);
418 stream.read((
char*)&inet_addr, 4);
419 stream.read((
char*)&inet_port, 2);
420 stream.read((
char*)&eid_len, 2);
422 std::vector<char> eid(eid_len);
423 stream.read(&eid[0], eid.size());
426 announcement._canonical_eid =
dtn::data::EID(std::string(eid.begin(), eid.end()));
432 IBRCOMMON_LOGGER_DEBUG_TAG(
"DiscoveryBeacon", 60) <<
"unknown beacon received" << IBRCOMMON_LOGGER_ENDL;
446 ss <<
"ANNOUNCE: " << _canonical_eid.
getString();
const DiscoveryService & getService(const std::string &name) const
service_list & getServices()
std::list< DiscoveryService > service_list
std::ostream & operator<<(std::ostream &stream, const DiscoveryBeacon &announcement)
const std::string & getName() const
void setEID(const dtn::data::EID &eid)
virtual ~DiscoveryBeacon()
const dtn::data::EID & getEID() const
std::string toString() const
const dtn::data::Number & getPeriod() const
void setPeriod(const dtn::data::Number &period)
std::string toString() const
std::string getString() const
dtn::data::SDNV< Size > Number
DiscoveryBeacon(const Protocol version=DISCO_VERSION_00, const dtn::data::EID &eid=dtn::data::EID())
std::istream & operator>>(std::istream &stream, DiscoveryBeacon &announcement)
void addService(const DiscoveryService &service)
void setSequencenumber(uint16_t sequence)