23 #include "../encoding/buffer-stream.hpp"
24 #include "../name-component.hpp"
25 #include "../lp/nack.hpp"
26 #include "../lp/nack-header.hpp"
33 SegmentFetcher::SegmentFetcher(Face& face,
34 shared_ptr<Validator> validator,
35 const CompleteCallback& completeCallback,
38 , m_scheduler(m_face.getIoService())
39 , m_validator(validator)
40 , m_completeCallback(completeCallback)
41 , m_errorCallback(errorCallback)
42 , m_buffer(make_shared<OBufferStream>())
47 SegmentFetcher::fetch(
Face& face,
53 shared_ptr<Validator> sharedValidator = shared_ptr<Validator>(&validator, [] (
Validator*) {});
55 fetch(face, baseInterest, sharedValidator, completeCallback, errorCallback);
59 SegmentFetcher::fetch(
Face& face,
61 shared_ptr<Validator> validator,
65 shared_ptr<SegmentFetcher> fetcher(
new SegmentFetcher(face, validator, completeCallback,
68 fetcher->fetchFirstSegment(baseInterest, fetcher);
72 SegmentFetcher::fetchFirstSegment(
const Interest& baseInterest,
73 shared_ptr<SegmentFetcher>
self)
76 interest.setChildSelector(1);
77 interest.setMustBeFresh(
true);
79 m_face.expressInterest(interest,
80 bind(&SegmentFetcher::afterSegmentReceived,
this, _1, _2,
true,
self),
81 bind(&SegmentFetcher::afterNackReceived,
this, _1, _2, 0,
self),
82 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
86 SegmentFetcher::fetchNextSegment(
const Interest& origInterest,
const Name& dataName,
88 shared_ptr<SegmentFetcher>
self)
91 interest.refreshNonce();
92 interest.setChildSelector(0);
93 interest.setMustBeFresh(
false);
95 m_face.expressInterest(interest,
96 bind(&SegmentFetcher::afterSegmentReceived,
this, _1, _2,
false,
self),
97 bind(&SegmentFetcher::afterNackReceived,
this, _1, _2, 0,
self),
98 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
102 SegmentFetcher::afterSegmentReceived(
const Interest& origInterest,
103 const Data& data,
bool isSegmentZeroExpected,
104 shared_ptr<SegmentFetcher>
self)
106 m_validator->validate(data,
107 bind(&SegmentFetcher::afterValidationSuccess,
this, _1,
108 isSegmentZeroExpected, origInterest,
self),
109 bind(&SegmentFetcher::afterValidationFailure,
this, _1));
114 SegmentFetcher::afterValidationSuccess(
const shared_ptr<const Data> data,
115 bool isSegmentZeroExpected,
117 shared_ptr<SegmentFetcher>
self)
119 name::Component currentSegment = data->getName().get(-1);
121 if (currentSegment.isSegment()) {
122 if (isSegmentZeroExpected && currentSegment.toSegment() != 0) {
123 fetchNextSegment(origInterest, data->getName(), 0,
self);
126 m_buffer->write(reinterpret_cast<const char*>(data->getContent().value()),
127 data->getContent().value_size());
129 const name::Component& finalBlockId = data->getMetaInfo().getFinalBlockId();
130 if (finalBlockId.empty() || (finalBlockId > currentSegment)) {
131 fetchNextSegment(origInterest, data->getName(), currentSegment.toSegment() + 1,
self);
134 return m_completeCallback(m_buffer->buf());
139 m_errorCallback(DATA_HAS_NO_SEGMENT,
"Data Name has no segment number.");
144 SegmentFetcher::afterValidationFailure(
const shared_ptr<const Data> data)
146 return m_errorCallback(SEGMENT_VALIDATION_FAIL,
"Segment validation fail");
151 SegmentFetcher::afterNackReceived(
const Interest& origInterest,
const lp::Nack& nack,
152 uint32_t reExpressCount, shared_ptr<SegmentFetcher>
self)
154 if (reExpressCount >= MAX_INTEREST_REEXPRESS) {
155 m_errorCallback(NACK_ERROR,
"Nack Error");
158 switch (nack.getReason()) {
160 reExpressInterest(origInterest, reExpressCount,
self);
163 m_scheduler.scheduleEvent(time::milliseconds(static_cast<uint32_t>(pow(2, reExpressCount + 1))),
164 bind(&SegmentFetcher::reExpressInterest,
this,
165 origInterest, reExpressCount,
self));
168 m_errorCallback(NACK_ERROR,
"Nack Error");
175 SegmentFetcher::reExpressInterest(
Interest interest, uint32_t reExpressCount,
176 shared_ptr<SegmentFetcher>
self)
178 interest.refreshNonce();
179 BOOST_ASSERT(interest.hasNonce());
181 bool isSegmentZeroExpected =
true;
182 if (!interest.getName().empty()) {
183 name::Component lastComponent = interest.getName().get(-1);
184 isSegmentZeroExpected = !lastComponent.isSegment();
187 m_face.expressInterest(interest,
188 bind(&SegmentFetcher::afterSegmentReceived,
this, _1, _2,
189 isSegmentZeroExpected,
self),
190 bind(&SegmentFetcher::afterNackReceived,
this, _1, _2,
191 ++reExpressCount,
self),
192 bind(m_errorCallback, INTEREST_TIMEOUT,
"Timeout"));
Copyright (c) 2013-2016 Regents of the University of California.
ndn security v2 Validator
function< void(uint32_t code, const std::string &msg)> ErrorCallback
Utility class to fetch latest version of the segmented data.
represents an Interest packet
function< void(const std::string &reason)> ErrorCallback
Name & appendSegment(uint64_t segmentNo)
Append segment number (sequential) using NDN naming conventions.
Provide a communication channel with local or remote NDN forwarder.
Name abstraction to represent an absolute name.
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
static const uint32_t MAX_INTEREST_REEXPRESS
Maximum number of times an interest will be reexpressed incase of NackCallback.
function< void(const ConstBufferPtr &data)> CompleteCallback