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,
39 const ErrorCallback& errorCallback)
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>
57 return fetch(
face, baseInterest, validatorPtr, completeCallback, errorCallback);
60 shared_ptr<SegmentFetcher>
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)
80 interest.setChildSelector(1);
81 interest.setMustBeFresh(
true);
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)
95 interest.refreshNonce();
96 interest.setChildSelector(0);
97 interest.setMustBeFresh(
false);
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()),
132 data.getContent().value_size());
133 afterSegmentValidated(data);
134 const auto& finalBlockId = data.getFinalBlock();
135 if (!finalBlockId || (*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.");
149 SegmentFetcher::afterValidationFailure(
const Data& data,
const security::v2::ValidationError& error)
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)
185 interest.refreshNonce();
186 BOOST_ASSERT(interest.hasNonce());
188 bool isSegmentZeroExpected =
true;
189 if (!interest.getName().empty()) {
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"));
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix of the name.
Copyright (c) 2011-2015 Regents of the University of California.
function< void(uint32_t code, const std::string &msg)> ErrorCallback
static shared_ptr< SegmentFetcher > fetch(Face &face, const Interest &baseInterest, security::v2::Validator &validator, const CompleteCallback &completeCallback, const ErrorCallback &errorCallback)
Initiates segment fetching.
Utility class to fetch latest version of the segmented data.
Represents an Interest packet.
represents a Network Nack
NackReason getReason() const
const Block & get(uint32_t type) const
Get the first sub element of specified TLV-TYPE.
bool isSegment() const
Check if the component is segment number per NDN naming conventions.
Provide a communication channel with local or remote NDN forwarder.
Represents an absolute name.
Represents a name component.
uint64_t toSegment() const
Interpret as segment number component using NDN naming conventions.
static const uint32_t MAX_INTEREST_REEXPRESS
Maximum number of times an interest will be reexpressed incase of NackCallback.
Name & appendSegment(uint64_t segmentNo)
Append a segment number (sequential) component.
Interface for validating data and interest packets.
function< void(const ConstBufferPtr &data)> CompleteCallback