blob: d84758af2d8298e958a06820912ca31ee2bfc218 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Wentao Shang38d79682014-01-15 15:55:52 -08004 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07005 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Wentao Shang38d79682014-01-15 15:55:52 -08006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Wentao Shang38d79682014-01-15 15:55:52 -080020 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070021 * @author Wentao Shang <http://irl.cs.ucla.edu/~wentao/>
Wentao Shang38d79682014-01-15 15:55:52 -080022 */
23
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080024#include "face.hpp"
25
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070026namespace ndn {
27
Wentao Shang38d79682014-01-15 15:55:52 -080028class Consumer
29{
30public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070031 Consumer(const std::string& dataName,
32 size_t pipeSize, size_t nTotalSegments,
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070033 int scope = -1, bool mustBeFresh = true)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070034 : m_dataName(dataName)
35 , m_pipeSize(pipeSize)
36 , m_nTotalSegments(nTotalSegments)
37 , m_nextSegment(0)
38 , m_totalSize(0)
39 , m_isOutputEnabled(false)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070040 , m_scope(scope)
41 , m_mustBeFresh(mustBeFresh)
Wentao Shang38d79682014-01-15 15:55:52 -080042 {
43 }
44
45 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070046 enableOutput()
Wentao Shang38d79682014-01-15 15:55:52 -080047 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070048 m_isOutputEnabled = true;
Wentao Shang38d79682014-01-15 15:55:52 -080049 }
50
51 void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070052 run();
53
Wentao Shang38d79682014-01-15 15:55:52 -080054private:
55 void
Alexander Afanasyev24b75c82014-05-31 15:59:31 +030056 onData(Data& data);
Wentao Shang38d79682014-01-15 15:55:52 -080057
58 void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059 onTimeout(const Interest& interest);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070060
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070061 Face m_face;
62 Name m_dataName;
63 size_t m_pipeSize;
64 size_t m_nTotalSegments;
65 size_t m_nextSegment;
66 size_t m_totalSize;
67 bool m_isOutputEnabled; // set to false by default
Alexander Afanasyevc1ebbe92014-01-16 22:24:34 -080068
69 int m_scope;
70 bool m_mustBeFresh;
Wentao Shang38d79682014-01-15 15:55:52 -080071};
72
73void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070074Consumer::run()
Wentao Shang38d79682014-01-15 15:55:52 -080075{
76 try
77 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070078 for (size_t i = 0; i < m_pipeSize; i++)
79 {
80 Interest interest(Name(m_dataName).appendSegment(m_nextSegment++));
81 interest.setInterestLifetime(time::milliseconds(4000));
82 if (m_scope >= 0)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070083 interest.setScope(m_scope);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070084 interest.setMustBeFresh(m_mustBeFresh);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070085
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070086 m_face.expressInterest(interest,
Alexander Afanasyev24b75c82014-05-31 15:59:31 +030087 bind(&Consumer::onData, this, _2),
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070088 bind(&Consumer::onTimeout, this, _1));
89 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070090
Wentao Shang38d79682014-01-15 15:55:52 -080091 // processEvents will block until the requested data received or timeout occurs
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070092 m_face.processEvents();
Wentao Shang38d79682014-01-15 15:55:52 -080093 }
94 catch (std::exception& e)
95 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070096 std::cerr << "ERROR: " << e.what() << std::endl;
Wentao Shang38d79682014-01-15 15:55:52 -080097 }
98}
99
100void
Alexander Afanasyev24b75c82014-05-31 15:59:31 +0300101Consumer::onData(Data& data)
Wentao Shang38d79682014-01-15 15:55:52 -0800102{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700103 const Block& content = data.getContent();
104 const Name& name = data.getName();
Wentao Shang38d79682014-01-15 15:55:52 -0800105
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700106 if (m_isOutputEnabled)
Wentao Shang38d79682014-01-15 15:55:52 -0800107 {
108 std::cout.write(reinterpret_cast<const char*>(content.value()), content.value_size());
109 }
110
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700111 m_totalSize += content.value_size();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700112
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113 if (name[-1].toSegment() + 1 == m_nTotalSegments)
Wentao Shang38d79682014-01-15 15:55:52 -0800114 {
115 std::cerr << "Last segment received." << std::endl;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 std::cerr << "Total # bytes of content received: " << m_totalSize << std::endl;
Wentao Shang38d79682014-01-15 15:55:52 -0800117 }
118 else
119 {
120 // Send interest for next segment
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700121 Interest interest(Name(m_dataName).appendSegment(m_nextSegment++));
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700122 if (m_scope >= 0)
123 interest.setScope(m_scope);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700124 interest.setInterestLifetime(time::milliseconds(4000));
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700125 interest.setMustBeFresh(m_mustBeFresh);
126
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700127 m_face.expressInterest(interest,
Alexander Afanasyev24b75c82014-05-31 15:59:31 +0300128 bind(&Consumer::onData, this, _2),
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700129 bind(&Consumer::onTimeout, this, _1));
Wentao Shang38d79682014-01-15 15:55:52 -0800130 }
131}
132
133
134void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700135Consumer::onTimeout(const Interest& interest)
Wentao Shang38d79682014-01-15 15:55:52 -0800136{
137 //XXX: currently no retrans
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700138 std::cerr << "TIMEOUT: last interest sent for segment #" << (m_nextSegment - 1) << std::endl;
Wentao Shang38d79682014-01-15 15:55:52 -0800139}
140
141
142int
143usage(const std::string &filename)
144{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700145 std::cerr << "Usage: \n "
146 << filename << " [-p pipeSize] [-c nTotalSegmentsment] [-o] /ndn/name\n";
Wentao Shang38d79682014-01-15 15:55:52 -0800147 return 1;
148}
149
150
151int
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152main(int argc, char** argv)
Wentao Shang38d79682014-01-15 15:55:52 -0800153{
154 std::string name;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 int pipeSize = 1;
156 int nTotalSegments = std::numeric_limits<int>::max();
Wentao Shang38d79682014-01-15 15:55:52 -0800157 bool output = false;
158
159 int opt;
160 while ((opt = getopt(argc, argv, "op:c:")) != -1)
161 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700162 switch (opt)
163 {
Wentao Shang38d79682014-01-15 15:55:52 -0800164 case 'p':
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700165 pipeSize = atoi(optarg);
166 if (pipeSize <= 0)
167 pipeSize = 1;
168 std::cerr << "main(): set pipe size = " << pipeSize << std::endl;
169 break;
170 case 'c':
171 nTotalSegments = atoi(optarg);
172 if (nTotalSegments <= 0)
173 nTotalSegments = 1;
174 std::cerr << "main(): set total seg = " << nTotalSegments << std::endl;
175 break;
176 case 'o':
177 output = true;
178 break;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700179 default:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700180 return usage(argv[0]);
Wentao Shang38d79682014-01-15 15:55:52 -0800181 }
182 }
183
184 if (optind < argc)
185 {
186 name = argv[optind];
187 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700188
Wentao Shang38d79682014-01-15 15:55:52 -0800189 if (name.empty())
190 {
191 return usage(argv[0]);
192 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700193
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700194 Consumer consumer(name, pipeSize, nTotalSegments);
Wentao Shang38d79682014-01-15 15:55:52 -0800195
196 if (output)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700197 consumer.enableOutput();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700198
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700199 consumer.run();
Wentao Shang38d79682014-01-15 15:55:52 -0800200
201 return 0;
202}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700203
204} // namespace ndn
205
206int
207main(int argc, char** argv)
208{
209 return ndn::main(argc, argv);
210}