23 #include "ndn-cxx/impl/lp-field-tag.hpp"
30 #include <boost/asio/io_service.hpp>
42 if (m_receiveCallback) {
43 m_receiveCallback(block);
48 send(
const Block& block)
final
72 struct DummyClientFace::BroadcastLink
74 std::vector<DummyClientFace*> faces;
78 :
Error(
"Face has already been linked to another face")
84 , m_internalKeyChain(make_unique<KeyChain>())
85 , m_keyChain(*m_internalKeyChain)
87 this->construct(options);
92 , m_keyChain(keyChain)
94 this->construct(options);
99 , m_internalKeyChain(make_unique<KeyChain>())
100 , m_keyChain(*m_internalKeyChain)
102 this->construct(options);
107 , m_keyChain(keyChain)
109 this->construct(options);
118 DummyClientFace::construct(
const Options& options)
120 static_pointer_cast<Transport>(
getTransport())->onSendBlock.connect([
this] (
Block packet) {
124 Block block({frag.first, frag.second});
127 auto interest = make_shared<Interest>(block);
129 auto nack = make_shared<lp::Nack>(std::move(*interest));
131 addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*nack, lpPacket);
135 addTagFromField<lp::NextHopFaceIdTag, lp::NextHopFaceIdField>(*interest, lpPacket);
136 addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*interest, lpPacket);
141 auto data = make_shared<Data>(block);
142 addTagFromField<lp::CachePolicyTag, lp::CachePolicyField>(*data, lpPacket);
143 addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*data, lpPacket);
148 if (options.enablePacketLogging)
149 this->enablePacketLogging();
151 if (options.enableRegistrationReply)
152 this->enableRegistrationReply(options.registrationReplyFaceId);
154 m_processEventsOverride = options.processEventsOverride;
156 enableBroadcastLink();
160 DummyClientFace::enableBroadcastLink()
163 if (m_bcastLink !=
nullptr) {
164 for (
auto otherFace : m_bcastLink->faces) {
165 if (otherFace != this) {
166 otherFace->receive(interest);
171 this->onSendData.connect([
this] (
const Data& data) {
172 if (m_bcastLink !=
nullptr) {
173 for (
auto otherFace : m_bcastLink->faces) {
174 if (otherFace != this) {
175 otherFace->receive(data);
180 this->onSendNack.connect([
this] (
const lp::Nack& nack) {
181 if (m_bcastLink !=
nullptr) {
182 for (
auto otherFace : m_bcastLink->faces) {
183 if (otherFace != this) {
184 otherFace->receive(nack);
192 DummyClientFace::enablePacketLogging()
194 onSendInterest.connect([
this] (
const Interest& interest) {
195 this->sentInterests.push_back(interest);
197 onSendData.connect([
this] (
const Data& data) {
198 this->sentData.push_back(data);
200 onSendNack.connect([
this] (
const lp::Nack& nack) {
201 this->sentNacks.push_back(nack);
206 DummyClientFace::enableRegistrationReply(uint64_t faceId)
208 onSendInterest.connect([=] (
const Interest& interest) {
209 static const Name localhostRibPrefix(
"/localhost/nfd/rib");
210 static const name::Component registerVerb(
"register");
211 const auto& name = interest.getName();
212 if (name.size() <= 4 || !localhostRibPrefix.isPrefixOf(name))
216 if (!params.hasFaceId()) {
217 params.setFaceId(faceId);
219 if (!params.hasOrigin()) {
222 if (!params.hasCost() && name[3] == registerVerb) {
228 resp.
setBody(params.wireEncode());
230 shared_ptr<Data> data = make_shared<Data>(name);
231 data->setContent(resp.wireEncode());
232 m_keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
233 this->getIoService().post([
this, data] { this->receive(*data); });
242 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, interest);
243 addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest);
244 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest);
246 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.
wireEncode());
250 DummyClientFace::receive(
const Data& data)
254 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, data);
255 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
257 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.
wireEncode());
268 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
269 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
271 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.
wireEncode());
277 if (m_bcastLink !=
nullptr && other.m_bcastLink !=
nullptr) {
278 if (m_bcastLink != other.m_bcastLink) {
283 else if (m_bcastLink ==
nullptr && other.m_bcastLink !=
nullptr) {
284 m_bcastLink = other.m_bcastLink;
285 m_bcastLink->faces.push_back(
this);
287 else if (m_bcastLink !=
nullptr && other.m_bcastLink ==
nullptr) {
288 other.m_bcastLink = m_bcastLink;
289 m_bcastLink->faces.push_back(&other);
292 m_bcastLink = other.m_bcastLink = make_shared<BroadcastLink>();
293 m_bcastLink->faces.push_back(
this);
294 m_bcastLink->faces.push_back(&other);
299 DummyClientFace::unlink()
301 if (m_bcastLink ==
nullptr) {
305 auto it = std::find(m_bcastLink->faces.begin(), m_bcastLink->faces.end(),
this);
306 BOOST_ASSERT(it != m_bcastLink->faces.end());
307 m_bcastLink->faces.erase(it);
309 if (m_bcastLink->faces.size() == 1) {
310 m_bcastLink->faces[0]->m_bcastLink =
nullptr;
311 m_bcastLink->faces.clear();
313 m_bcastLink =
nullptr;
319 if (m_processEventsOverride !=
nullptr) {
320 m_processEventsOverride(timeout);
323 this->Face::doProcessEvents(timeout, keepThread);
Represents a TLV element of the NDN packet format.
void encode()
Encode sub-elements into TLV-VALUE.
Represents a Data packet.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Prepend wire encoding to encoder.
Provide a communication channel with local or remote NDN forwarder.
shared_ptr< Transport > getTransport() const
Returns the underlying transport.
Represents an Interest packet.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Prepend wire encoding to encoder.
Provides a "TLV-oriented" delivery service.
Represents a Network Nack.
const Interest & getInterest() const
const NackHeader & getHeader() const
Packet & add(const typename FIELD::ValueType &value)
Add a FIELD with value.
Block wireEncode() const
Encode packet into wire format.
ControlResponse & setBody(const Block &body)
ControlResponse & setCode(uint32_t code)
Options for DummyClientFace.
A client-side face for unit testing.
void receive(const Interest &interest)
Cause the Face to receive an Interest packet.
Signal< DummyClientFace, Interest > onSendInterest
Emits whenever an Interest is sent.
Signal< DummyClientFace, lp::Nack > onSendNack
Emits whenever a Nack is sent.
void unlink()
Unlink the broadcast media if previously linked.
Signal< DummyClientFace, Data > onSendData
Emits whenever a Data packet is sent.
~DummyClientFace() override
DummyClientFace(const Options &options=Options())
Create a dummy face with internal IO service.
Provides a lightweight signal / event system.
mgmt::ControlResponse ControlResponse
boost::chrono::milliseconds milliseconds