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();
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()
208 onSendInterest.connect([
this] (
const Interest& interest) {
209 static const Name localhostRegistration(
"/localhost/nfd/rib");
210 if (!localhostRegistration.isPrefixOf(interest.getName()))
216 if (interest.getName().get(3) == name::Component(
"register")) {
222 resp.
setBody(params.wireEncode());
224 shared_ptr<Data> data = make_shared<Data>(interest.getName());
225 data->setContent(resp.wireEncode());
227 m_keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
229 this->getIoService().post([
this, data] { this->receive(*data); });
238 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, interest);
239 addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest);
240 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest);
242 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.
wireEncode());
246 DummyClientFace::receive(
const Data& data)
250 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, data);
251 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
253 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.
wireEncode());
264 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
265 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
267 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.
wireEncode());
273 if (m_bcastLink !=
nullptr && other.m_bcastLink !=
nullptr) {
274 if (m_bcastLink != other.m_bcastLink) {
279 else if (m_bcastLink ==
nullptr && other.m_bcastLink !=
nullptr) {
280 m_bcastLink = other.m_bcastLink;
281 m_bcastLink->faces.push_back(
this);
283 else if (m_bcastLink !=
nullptr && other.m_bcastLink ==
nullptr) {
284 other.m_bcastLink = m_bcastLink;
285 m_bcastLink->faces.push_back(&other);
288 m_bcastLink = other.m_bcastLink = make_shared<BroadcastLink>();
289 m_bcastLink->faces.push_back(
this);
290 m_bcastLink->faces.push_back(&other);
295 DummyClientFace::unlink()
297 if (m_bcastLink ==
nullptr) {
301 auto it = std::find(m_bcastLink->faces.begin(), m_bcastLink->faces.end(),
this);
302 BOOST_ASSERT(it != m_bcastLink->faces.end());
303 m_bcastLink->faces.erase(it);
305 if (m_bcastLink->faces.size() == 1) {
306 m_bcastLink->faces[0]->m_bcastLink =
nullptr;
307 m_bcastLink->faces.clear();
309 m_bcastLink =
nullptr;
315 if (m_processEventsOverride !=
nullptr) {
316 m_processEventsOverride(timeout);
319 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 TLV-block 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
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