23 #include "../encoding/buffer-stream.hpp" 24 #include "../name-component.hpp" 25 #include "../lp/nack.hpp" 26 #include "../lp/nack-header.hpp" 28 #include <boost/lexical_cast.hpp> 35 SegmentFetcher::SegmentFetcher(Face& face,
36 shared_ptr<security::v2::Validator> validator,
37 const CompleteCallback& completeCallback,
40 , m_scheduler(m_face.getIoService())
41 , m_validator(validator)
42 , m_completeCallback(completeCallback)
43 , m_errorCallback(errorCallback)
44 , m_buffer(make_shared<OBufferStream>())
49 SegmentFetcher::fetch(
Face& face,
56 fetch(face, baseInterest, validatorPtr, completeCallback, errorCallback);
60 SegmentFetcher::fetch(
Face& face,
62 shared_ptr<security::v2::Validator> validator,
66 shared_ptr<SegmentFetcher> fetcher(
new SegmentFetcher(face, validator, completeCallback,
69 fetcher->fetchFirstSegment(baseInterest, fetcher);
73 SegmentFetcher::fetchFirstSegment(
const Interest& baseInterest,
74 shared_ptr<SegmentFetcher>
self)
80 m_face.expressInterest(interest,
81 bind(&SegmentFetcher::afterSegmentReceived,
this, _1, _2,
true,
self),
82 bind(&SegmentFetcher::afterNackReceived,
this, _1, _2, 0,
self),
83 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
87 SegmentFetcher::fetchNextSegment(
const Interest& origInterest,
const Name& dataName,
89 shared_ptr<SegmentFetcher>
self)
96 m_face.expressInterest(interest,
97 bind(&SegmentFetcher::afterSegmentReceived,
this, _1, _2,
false,
self),
98 bind(&SegmentFetcher::afterNackReceived,
this, _1, _2, 0,
self),
99 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
103 SegmentFetcher::afterSegmentReceived(
const Interest& origInterest,
104 const Data& data,
bool isSegmentZeroExpected,
105 shared_ptr<SegmentFetcher>
self)
107 m_validator->validate(data,
108 bind(&SegmentFetcher::afterValidationSuccess,
this, _1,
109 isSegmentZeroExpected, origInterest,
self),
110 bind(&SegmentFetcher::afterValidationFailure,
this, _1, _2));
115 SegmentFetcher::afterValidationSuccess(
const Data& data,
116 bool isSegmentZeroExpected,
118 shared_ptr<SegmentFetcher>
self)
123 if (isSegmentZeroExpected && currentSegment.
toSegment() != 0) {
124 fetchNextSegment(origInterest, data.
getName(), 0,
self);
127 m_buffer->write(reinterpret_cast<const char*>(data.
getContent().
value()),
131 if (finalBlockId.
empty() || (finalBlockId > currentSegment)) {
132 fetchNextSegment(origInterest, data.
getName(), currentSegment.
toSegment() + 1,
self);
135 return m_completeCallback(m_buffer->buf());
140 m_errorCallback(DATA_HAS_NO_SEGMENT,
"Data Name has no segment number.");
147 return m_errorCallback(SEGMENT_VALIDATION_FAIL,
"Segment validation fail " +
148 boost::lexical_cast<std::string>(error));
153 SegmentFetcher::afterNackReceived(
const Interest& origInterest,
const lp::Nack& nack,
154 uint32_t reExpressCount, shared_ptr<SegmentFetcher>
self)
156 if (reExpressCount >= MAX_INTEREST_REEXPRESS) {
157 m_errorCallback(NACK_ERROR,
"Nack Error");
162 reExpressInterest(origInterest, reExpressCount,
self);
165 m_scheduler.scheduleEvent(time::milliseconds(static_cast<uint32_t>(pow(2, reExpressCount + 1))),
166 bind(&SegmentFetcher::reExpressInterest,
this,
167 origInterest, reExpressCount,
self));
170 m_errorCallback(NACK_ERROR,
"Nack Error");
177 SegmentFetcher::reExpressInterest(
Interest interest, uint32_t reExpressCount,
178 shared_ptr<SegmentFetcher>
self)
183 bool isSegmentZeroExpected =
true;
186 isSegmentZeroExpected = !lastComponent.
isSegment();
189 m_face.expressInterest(interest,
190 bind(&SegmentFetcher::afterSegmentReceived,
this, _1, _2,
191 isSegmentZeroExpected,
self),
192 bind(&SegmentFetcher::afterNackReceived,
this, _1, _2,
193 ++reExpressCount,
self),
194 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
const Name & getName() const
Copyright (c) 2013-2017 Regents of the University of California.
Interest & setMustBeFresh(bool mustBeFresh)
function< void(uint32_t code, const std::string &msg)> ErrorCallback
void refreshNonce()
Refresh nonce.
Utility class to fetch latest version of the segmented data.
represents an Interest packet
const MetaInfo & getMetaInfo() const
Get MetaInfo.
function< void(const std::string &reason)> ErrorCallback
represents a Network Nack
NackReason getReason() const
bool isSegment() const
Check if the component is segment number per NDN naming conventions.
uint64_t toSegment() const
Interpret as segment number component using NDN naming conventions.
Interest & setChildSelector(int childSelector)
Interest & setName(const Name &name)
Provide a communication channel with local or remote NDN forwarder.
Represents an absolute name.
size_t value_size() const
Get size of TLV-VALUE aka TLV-LENGTH.
const Name & getName() const
Get name.
Component holds a read-only name component value.
Validation error code and optional detailed error message.
const Block & getContent() const
Get Content.
bool empty() const
Check if name is empty.
const uint8_t * value() const
Get pointer to TLV-VALUE.
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix of the name.
static const uint32_t MAX_INTEREST_REEXPRESS
Maximum number of times an interest will be reexpressed incase of NackCallback.
Represents a Data packet.
const Component & get(ssize_t i) const
Get the component at the given index.
Name & appendSegment(uint64_t segmentNo)
Append a segment number (sequential) component.
Interface for validating data and interest packets.
function< void(const ConstBufferPtr &data)> CompleteCallback
bool hasNonce() const
Check if Nonce set.