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> 36 SegmentFetcher::SegmentFetcher(Face& face,
37 shared_ptr<security::v2::Validator> validator,
38 const CompleteCallback& completeCallback,
41 , m_scheduler(m_face.getIoService())
42 , m_validator(validator)
43 , m_completeCallback(completeCallback)
44 , m_errorCallback(errorCallback)
45 , m_buffer(make_shared<OBufferStream>())
49 shared_ptr<SegmentFetcher>
50 SegmentFetcher::fetch(
Face& face,
57 return fetch(face, baseInterest, validatorPtr, completeCallback, errorCallback);
60 shared_ptr<SegmentFetcher>
61 SegmentFetcher::fetch(
Face& face,
63 shared_ptr<security::v2::Validator> validator,
67 shared_ptr<SegmentFetcher> fetcher(
new SegmentFetcher(face, validator, completeCallback,
70 fetcher->fetchFirstSegment(baseInterest, fetcher);
76 SegmentFetcher::fetchFirstSegment(
const Interest& baseInterest,
77 shared_ptr<SegmentFetcher>
self)
83 m_face.expressInterest(interest,
84 bind(&SegmentFetcher::afterSegmentReceivedCb,
this, _1, _2,
true,
self),
85 bind(&SegmentFetcher::afterNackReceivedCb,
this, _1, _2, 0,
self),
86 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
90 SegmentFetcher::fetchNextSegment(
const Interest& origInterest,
const Name& dataName,
92 shared_ptr<SegmentFetcher>
self)
99 m_face.expressInterest(interest,
100 bind(&SegmentFetcher::afterSegmentReceivedCb,
this, _1, _2,
false,
self),
101 bind(&SegmentFetcher::afterNackReceivedCb,
this, _1, _2, 0,
self),
102 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
106 SegmentFetcher::afterSegmentReceivedCb(
const Interest& origInterest,
107 const Data& data,
bool isSegmentZeroExpected,
108 shared_ptr<SegmentFetcher>
self)
110 afterSegmentReceived(data);
111 m_validator->validate(data,
112 bind(&SegmentFetcher::afterValidationSuccess,
this, _1,
113 isSegmentZeroExpected, origInterest,
self),
114 bind(&SegmentFetcher::afterValidationFailure,
this, _1, _2));
119 SegmentFetcher::afterValidationSuccess(
const Data& data,
120 bool isSegmentZeroExpected,
122 shared_ptr<SegmentFetcher>
self)
127 if (isSegmentZeroExpected && currentSegment.
toSegment() != 0) {
128 fetchNextSegment(origInterest, data.
getName(), 0,
self);
131 m_buffer->write(reinterpret_cast<const char*>(data.
getContent().
value()),
133 afterSegmentValidated(data);
135 if (finalBlockId.
empty() || (finalBlockId > currentSegment)) {
136 fetchNextSegment(origInterest, data.
getName(), currentSegment.
toSegment() + 1,
self);
139 return m_completeCallback(m_buffer->buf());
144 m_errorCallback(DATA_HAS_NO_SEGMENT,
"Data Name has no segment number.");
151 return m_errorCallback(SEGMENT_VALIDATION_FAIL,
"Segment validation fail " +
152 boost::lexical_cast<std::string>(error));
157 SegmentFetcher::afterNackReceivedCb(
const Interest& origInterest,
const lp::Nack& nack,
158 uint32_t reExpressCount, shared_ptr<SegmentFetcher>
self)
160 if (reExpressCount >= MAX_INTEREST_REEXPRESS) {
161 m_errorCallback(NACK_ERROR,
"Nack Error");
166 reExpressInterest(origInterest, reExpressCount,
self);
169 using ms = time::milliseconds;
170 m_scheduler.scheduleEvent(ms(static_cast<ms::rep>(std::pow(2, reExpressCount + 1))),
171 bind(&SegmentFetcher::reExpressInterest,
this,
172 origInterest, reExpressCount,
self));
175 m_errorCallback(NACK_ERROR,
"Nack Error");
182 SegmentFetcher::reExpressInterest(
Interest interest, uint32_t reExpressCount,
183 shared_ptr<SegmentFetcher>
self)
188 bool isSegmentZeroExpected =
true;
191 isSegmentZeroExpected = !lastComponent.
isSegment();
194 m_face.expressInterest(interest,
195 bind(&SegmentFetcher::afterSegmentReceivedCb,
this, _1, _2,
196 isSegmentZeroExpected,
self),
197 bind(&SegmentFetcher::afterNackReceivedCb,
this, _1, _2,
198 ++reExpressCount,
self),
199 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.