face: Refactored code to set interest filter
Change-Id: I1f9637a79c03a9e24608403d963bbfc4d9bcab1c
diff --git a/src/management/ndnd-control.cpp b/src/management/ndnd-control.cpp
new file mode 100644
index 0000000..6f48231
--- /dev/null
+++ b/src/management/ndnd-control.cpp
@@ -0,0 +1,264 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "common.hpp"
+#include "../node.hpp"
+#include "../security/signature-sha256-with-rsa.hpp"
+#include "../util/random.hpp"
+
+#include "ndnd-forwarding-entry.hpp"
+#include "ndnd-face-instance.hpp"
+#include "ndnd-status-response.hpp"
+
+namespace ndn {
+namespace ndnd {
+
+Control::Control(Node& face)
+ : m_face(face)
+ , m_faceId(-1)
+{
+}
+
+void
+Control::selfRegisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ if (!m_ndndId.hasValue())
+ {
+ if (m_filterRequests.empty())
+ {
+ m_face.expressInterest(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"),
+ bind(&Control::onNdnidFetched, this, _1, _2),
+ bind(onFail));
+ }
+ m_filterRequests.push_back(FilterRequest(prefixToRegister, onSuccess, onFail));
+ }
+ else
+ startPrefixAction(ForwardingEntry("selfreg", prefixToRegister),
+ bind(&Control::recordSelfRegisteredFaceId, this, _1, onSuccess),
+ onFail);
+}
+
+
+void
+Control::selfDeregisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ if (!m_ndndId.hasValue() || m_faceId == -1)
+ {
+ if (static_cast<bool>(onFail))
+ onFail();
+ return;
+ }
+
+ startPrefixAction(ForwardingEntry("unreg", prefixToRegister, m_faceId),
+ bind(onSuccess), onFail);
+}
+
+
+void
+Control::onNdnidFetched(const shared_ptr<const Interest>& interest,
+ const shared_ptr<Data>& data)
+{
+ if (data->getName().size() > interest->getName().size())
+ {
+ m_ndndId = data->getName()[interest->getName().size()];
+
+ for (FilterRequestList::iterator i = m_filterRequests.begin();
+ i != m_filterRequests.end();
+ ++i)
+ {
+ startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
+ bind(&Control::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
+ i->m_onFailure);
+ }
+ }
+ else
+ {
+ for (FilterRequestList::iterator i = m_filterRequests.begin();
+ i != m_filterRequests.end();
+ ++i)
+ {
+ if (static_cast<bool>(i->m_onFailure))
+ i->m_onFailure();
+ }
+ }
+ m_filterRequests.clear();
+}
+
+void
+Control::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
+ const SuccessCallback& onSuccess)
+{
+ m_faceId = entry.getFaceId();
+ if (static_cast<bool>(onSuccess))
+ onSuccess();
+}
+
+void
+Control::startFaceAction(const FaceInstance& entry,
+ const FaceOperationSucceedCallback& onSuccess,
+ const FailCallback& onFailure)
+{
+ // Set the ForwardingEntry as the content of a Data packet and sign.
+ Data data;
+ data.setName(Name().appendVersion(ndn::random::generateWord32()));
+ data.setContent(entry.wireEncode());
+
+ // Create an empty signature, since nobody going to verify it for now
+ // @todo In the future, we may require real signatures to do the registration
+ SignatureSha256WithRsa signature;
+ signature.setValue(Block(Tlv::SignatureValue));
+ data.setSignature(signature);
+
+ // Create an interest where the name has the encoded Data packet.
+ Name interestName;
+ interestName.append("ndnx");
+ interestName.append(m_ndndId);
+ interestName.append(entry.getAction());
+ interestName.append(data.wireEncode());
+
+ Interest interest(interestName);
+ interest.setScope(1);
+ interest.setInterestLifetime(1000);
+ interest.setMustBeFresh(true);
+
+ m_face.expressInterest(interest,
+ bind(&Control::processFaceActionResponse, this, _2, onSuccess, onFailure),
+ bind(onFailure));
+}
+
+void
+Control::startPrefixAction(const ForwardingEntry& entry,
+ const PrefixOperationSucceedCallback& onSuccess,
+ const FailCallback& onFailure)
+{
+ // Set the ForwardingEntry as the content of a Data packet and sign.
+ Data data;
+ data.setName(Name().appendVersion(random::generateWord32()));
+ data.setContent(entry.wireEncode());
+
+ // Create an empty signature, since nobody going to verify it for now
+ // @todo In the future, we may require real signatures to do the registration
+ SignatureSha256WithRsa signature;
+ signature.setValue(Block(Tlv::SignatureValue));
+ data.setSignature(signature);
+
+ // Create an interest where the name has the encoded Data packet.
+ Name interestName;
+ interestName.append("ndnx");
+ interestName.append(m_ndndId);
+ interestName.append(entry.getAction());
+ interestName.append(data.wireEncode());
+
+ Interest interest(interestName);
+ interest.setScope(1);
+ interest.setInterestLifetime(1000);
+ interest.setMustBeFresh(true);
+
+ m_face.expressInterest(interest,
+ bind(&Control::processPrefixActionResponse, this, _2, onSuccess, onFailure),
+ bind(onFailure));
+}
+
+void
+Control::processFaceActionResponse(const shared_ptr<Data>& data,
+ const FaceOperationSucceedCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ Block content = data->getContent();
+ content.parse();
+
+ if (content.getAll().empty())
+ {
+ if (static_cast<bool>(onFail))
+ onFail();
+ return;
+ }
+
+ Block::element_iterator val = content.getAll().begin();
+
+ switch(val->type())
+ {
+ case Tlv::FaceManagement::FaceInstance:
+ {
+ FaceInstance entry;
+ entry.wireDecode(*val);
+
+ if (static_cast<bool>(onSuccess))
+ onSuccess(entry);
+ return;
+ }
+ case Tlv::FaceManagement::StatusResponse:
+ {
+ StatusResponse resp;
+ resp.wireDecode(*val);
+
+ if (static_cast<bool>(onFail))
+ onFail();
+ return;
+ }
+ default:
+ {
+ if (static_cast<bool>(onFail))
+ onFail();
+ return;
+ }
+ }
+}
+
+void
+Control::processPrefixActionResponse(const shared_ptr<Data>& data,
+ const PrefixOperationSucceedCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ Block content = data->getContent();
+ content.parse();
+
+ if (content.getAll().empty())
+ {
+ if (static_cast<bool>(onFail))
+ onFail();
+ return;
+ }
+
+ Block::element_iterator val = content.getAll().begin();
+
+ switch(val->type())
+ {
+ case Tlv::FaceManagement::ForwardingEntry:
+ {
+ ForwardingEntry entry;
+ entry.wireDecode(*val);
+
+ if (static_cast<bool>(onSuccess))
+ onSuccess(entry);
+ return;
+ }
+ case Tlv::FaceManagement::StatusResponse:
+ {
+ StatusResponse resp;
+ resp.wireDecode(*val);
+
+ // std::cerr << "StatusReponse: " << resp << std::endl;
+
+ if (static_cast<bool>(onFail))
+ onFail();
+ return;
+ }
+ default:
+ {
+ if (static_cast<bool>(onFail))
+ onFail();
+ return;
+ }
+ }
+}
+
+} // namespace ndnd
+} // namespace ndn