blob: 26a6ecdfeb03458a9df35b089b8fb39d6c2e0ce8 [file] [log] [blame]
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -07001/**
2 * @author: Jeff Thompson
3 * See COPYING for copyright and distribution information.
4 */
5
6#include "encoding/binary-xml-decoder.hpp"
7#include "c/encoding/binary-xml.h"
8#include "data.hpp"
9#include "Node.hpp"
10
11using namespace std;
12using namespace ndn::ptr_lib;
13
14namespace ndn {
15
Jeff Thompson557b81e2013-08-21 15:13:51 -070016Node::PitEntry::PitEntry(const Name &name, Closure *closure)
17: interest_(name), interestStructIsStale_(true), closure_(closure)
18{
19 if (interest_.getInterestLifetimeMilliseconds() >= 0.0)
20 timeoutTime_ = ::clock() + (clock_t)((interest_.getInterestLifetimeMilliseconds() / 1000.0) * (double)CLOCKS_PER_SEC);
21 else
22 // No timeout.
23 timeoutTime_ = 0;
24}
25
26const struct ndn_Interest &Node::PitEntry::getInterestStruct()
27{
28 if (interestStructIsStale_) {
29 nameComponents_.reserve(interest_.getName().getComponentCount());
30 excludeEntries_.reserve(interest_.getExclude().getEntryCount());
31 ndn_Interest_init
32 (&interestStruct_, &nameComponents_[0], nameComponents_.capacity(), &excludeEntries_[0], excludeEntries_.capacity());
33 interest_.get(interestStruct_);
34
35 interestStructIsStale_ = false;
36 }
37
38 return interestStruct_;
39}
40
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070041void Node::expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate)
42{
Jeff Thompson557b81e2013-08-21 15:13:51 -070043 shared_ptr<PitEntry> pitEntry(new PitEntry(name, closure));
44 if (interestTemplate) {
45 pitEntry->getInterest().setMinSuffixComponents(interestTemplate->getMinSuffixComponents());
46 pitEntry->getInterest().setMaxSuffixComponents(interestTemplate->getMaxSuffixComponents());
47 pitEntry->getInterest().getPublisherPublicKeyDigest() = interestTemplate->getPublisherPublicKeyDigest();
48 pitEntry->getInterest().getExclude() = interestTemplate->getExclude();
49 pitEntry->getInterest().setChildSelector(interestTemplate->getChildSelector());
50 pitEntry->getInterest().setAnswerOriginKind(interestTemplate->getAnswerOriginKind());
51 pitEntry->getInterest().setScope(interestTemplate->getScope());
52 pitEntry->getInterest().setInterestLifetimeMilliseconds(interestTemplate->getInterestLifetimeMilliseconds());
53 }
54 else
55 pitEntry->getInterest().setInterestLifetimeMilliseconds(4000.0); // default interest timeout value.
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070056
Jeff Thompson557b81e2013-08-21 15:13:51 -070057 pit_.push_back(pitEntry);
58
59 shared_ptr<vector<unsigned char> > encoding = pitEntry->getInterest().wireEncode();
60
61 // TODO: Check if we are already connected.
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070062 transport_->connect(*this);
63 transport_->send(*encoding);
64}
65
66void Node::processEvents()
67{
68 transport_->processEvents();
69}
70
71void Node::onReceivedElement(unsigned char *element, unsigned int elementLength)
72{
73 BinaryXmlDecoder decoder(element, elementLength);
74
75 if (decoder.peekDTag(ndn_BinaryXml_DTag_ContentObject)) {
76 shared_ptr<Data> data(new Data());
77 data->wireDecode(element, elementLength);
78
Jeff Thompson557b81e2013-08-21 15:13:51 -070079 int iPitEntry = getEntryIndexForExpressedInterest(data->getName());
80 if (iPitEntry >= 0) {
81 shared_ptr<Interest> interestCopy(new Interest(pit_[iPitEntry]->getInterest()));
82 UpcallInfo upcallInfo(this, interestCopy, 0, data);
83
84 // Remove the PIT entry before the calling the callback.
85 Closure *closure = pit_[iPitEntry]->getClosure();
86 pit_.erase(pit_.begin() + iPitEntry);
87 closure->upcall(UPCALL_DATA, upcallInfo);
88 }
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070089 }
90}
91
92void Node::shutdown()
93{
94 transport_->close();
95}
96
Jeff Thompson557b81e2013-08-21 15:13:51 -070097int Node::getEntryIndexForExpressedInterest(const Name &name)
98{
99 // TODO: Doesn't this belong in the Name class?
100 vector<struct ndn_NameComponent> nameComponents;
101 nameComponents.reserve(name.getComponentCount());
102 struct ndn_Name nameStruct;
103 ndn_Name_init(&nameStruct, &nameComponents[0], nameComponents.capacity());
104 name.get(nameStruct);
105
106 int iResult = -1;
107
108 for (unsigned int i = 0; i < pit_.size(); ++i) {
109 if (ndn_Interest_matchesName((struct ndn_Interest *)&pit_[i]->getInterestStruct(), &nameStruct)) {
110 if (iResult < 0 ||
111 pit_[i]->getInterest().getName().getComponentCount() > pit_[iResult]->getInterest().getName().getComponentCount())
112 iResult = i;
113 }
114 }
115
116 return iResult;
117}
118
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700119}