blob: 59a75adceb7bdc02c0b29baf8365849845bdc0ac [file] [log] [blame]
Wentao Shang38d79682014-01-15 15:55:52 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Wentao Shang <wentao@cs.ucla.edu>
19 */
20
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080021#include "face.hpp"
22
Wentao Shang38d79682014-01-15 15:55:52 -080023class Consumer
24{
25public:
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070026 Consumer(const std::string& data_name,
27 size_t pipe_size, size_t total_seg,
28 int scope = -1, bool mustBeFresh = true)
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070029 : m_data_name(data_name)
30 , m_pipe_size(pipe_size)
31 , m_total_seg(total_seg)
32 , m_next_seg(0)
33 , m_total_size(0)
34 , m_output(false)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070035 , m_scope(scope)
36 , m_mustBeFresh(mustBeFresh)
Wentao Shang38d79682014-01-15 15:55:52 -080037 {
38 }
39
40 inline void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070041 enable_output()
Wentao Shang38d79682014-01-15 15:55:52 -080042 {
43 m_output = true;
44 }
45
46 void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070047 run();
48
Wentao Shang38d79682014-01-15 15:55:52 -080049private:
50 void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070051 on_data(const ndn::Interest& interest, ndn::Data& data);
Wentao Shang38d79682014-01-15 15:55:52 -080052
53 void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070054 on_timeout(const ndn::Interest& interest);
55
Wentao Shang38d79682014-01-15 15:55:52 -080056 ndn::Face m_face;
57 ndn::Name m_data_name;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070058 size_t m_pipe_size;
59 size_t m_total_seg;
60 size_t m_next_seg;
61 size_t m_total_size;
Wentao Shang38d79682014-01-15 15:55:52 -080062 bool m_output; // set to false by default
Alexander Afanasyevc1ebbe92014-01-16 22:24:34 -080063
64 int m_scope;
65 bool m_mustBeFresh;
Wentao Shang38d79682014-01-15 15:55:52 -080066};
67
68void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070069Consumer::run()
Wentao Shang38d79682014-01-15 15:55:52 -080070{
71 try
72 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070073 for (size_t i = 0; i < m_pipe_size; i++)
74 {
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070075 ndn::Interest interest(ndn::Name(m_data_name).appendSegment(m_next_seg++));
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070076 interest.setInterestLifetime(ndn::time::milliseconds(4000));
77 if (m_scope >= 0)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070078 interest.setScope(m_scope);
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070079 interest.setMustBeFresh(m_mustBeFresh);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070080
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070081 m_face.expressInterest(interest,
82 ndn::bind(&Consumer::on_data, this, _1, _2),
83 ndn::bind(&Consumer::on_timeout, this, _1));
84 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070085
Wentao Shang38d79682014-01-15 15:55:52 -080086 // processEvents will block until the requested data received or timeout occurs
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070087 m_face.processEvents();
Wentao Shang38d79682014-01-15 15:55:52 -080088 }
89 catch (std::exception& e)
90 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070091 std::cerr << "ERROR: " << e.what() << std::endl;
Wentao Shang38d79682014-01-15 15:55:52 -080092 }
93}
94
95void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070096Consumer::on_data(const ndn::Interest& interest, ndn::Data& data)
Wentao Shang38d79682014-01-15 15:55:52 -080097{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070098 const ndn::Block& content = data.getContent();
99 const ndn::Name& name = data.getName();
Wentao Shang38d79682014-01-15 15:55:52 -0800100
101 if (m_output)
102 {
103 std::cout.write(reinterpret_cast<const char*>(content.value()), content.value_size());
104 }
105
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700106 m_total_size += content.value_size();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700107
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700108 if (name[-1].toSegment() + 1 == m_total_seg)
Wentao Shang38d79682014-01-15 15:55:52 -0800109 {
110 std::cerr << "Last segment received." << std::endl;
111 std::cerr << "Total # bytes of content received: " << m_total_size << std::endl;
112 }
113 else
114 {
115 // Send interest for next segment
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700116 ndn::Interest interest(ndn::Name(m_data_name).appendSegment(m_next_seg++));
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700117 if (m_scope >= 0)
118 interest.setScope(m_scope);
119 interest.setInterestLifetime(ndn::time::milliseconds(4000));
120 interest.setMustBeFresh(m_mustBeFresh);
121
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700122 m_face.expressInterest(interest,
123 ndn::bind(&Consumer::on_data, this, _1, _2),
124 ndn::bind(&Consumer::on_timeout, this, _1));
Wentao Shang38d79682014-01-15 15:55:52 -0800125 }
126}
127
128
129void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700130Consumer::on_timeout(const ndn::Interest& interest)
Wentao Shang38d79682014-01-15 15:55:52 -0800131{
132 //XXX: currently no retrans
133 std::cerr << "TIMEOUT: last interest sent for segment #" << (m_next_seg - 1) << std::endl;
134}
135
136
137int
138usage(const std::string &filename)
139{
140 std::cerr << "Usage: \n " << filename << " [-p pipe_size] [-c total_segment] [-o] /ndn/name\n";
141 return 1;
142}
143
144
145int
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700146main(int argc, char **argv)
Wentao Shang38d79682014-01-15 15:55:52 -0800147{
148 std::string name;
149 int pipe_size = 1;
150 int total_seg = std::numeric_limits<int>::max();
151 bool output = false;
152
153 int opt;
154 while ((opt = getopt(argc, argv, "op:c:")) != -1)
155 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700156 switch(opt)
157 {
Wentao Shang38d79682014-01-15 15:55:52 -0800158 case 'p':
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700159 pipe_size = atoi(optarg);
160 if (pipe_size <= 0)
161 pipe_size = 1;
162 std::cerr << "main(): set pipe size = " << pipe_size << std::endl;
163 break;
164 case 'c':
165 total_seg = atoi(optarg);
166 if (total_seg <= 0)
167 total_seg = 1;
168 std::cerr << "main(): set total seg = " << total_seg << std::endl;
169 break;
170 case 'o':
171 output = true;
172 break;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700173 default:
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700174 return usage(argv[0]);
Wentao Shang38d79682014-01-15 15:55:52 -0800175 }
176 }
177
178 if (optind < argc)
179 {
180 name = argv[optind];
181 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700182
Wentao Shang38d79682014-01-15 15:55:52 -0800183 if (name.empty())
184 {
185 return usage(argv[0]);
186 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700187
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700188 Consumer consumer(name, pipe_size, total_seg);
Wentao Shang38d79682014-01-15 15:55:52 -0800189
190 if (output)
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700191 consumer.enable_output();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700192
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700193 consumer.run();
Wentao Shang38d79682014-01-15 15:55:52 -0800194
195 return 0;
196}