blob: c912f269c496534f0659bbabb4fe8eec38f66217 [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
21
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080022#include "face.hpp"
23
Wentao Shang38d79682014-01-15 15:55:52 -080024class Consumer
25{
26public:
Alexander Afanasyev89a889c2014-01-17 16:13:38 -080027 Consumer (const std::string &data_name, int pipe_size, int total_seg, int scope = -1, bool mustBeFresh = true)
Wentao Shang38d79682014-01-15 15:55:52 -080028 : m_data_name (data_name), m_pipe_size (pipe_size), m_total_seg (total_seg),
29 m_next_seg (0), m_total_size (0), m_output (false)
Alexander Afanasyevc1ebbe92014-01-16 22:24:34 -080030 , m_scope(scope)
31 , m_mustBeFresh(mustBeFresh)
Wentao Shang38d79682014-01-15 15:55:52 -080032 {
33 }
34
35 inline void
36 enable_output ()
37 {
38 m_output = true;
39 }
40
41 void
42 run ();
43
44private:
45 void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080046 on_data (const ndn::Interest& interest, ndn::Data& data);
Wentao Shang38d79682014-01-15 15:55:52 -080047
48 void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080049 on_timeout (const ndn::Interest& interest);
Wentao Shang38d79682014-01-15 15:55:52 -080050
51 ndn::Face m_face;
52 ndn::Name m_data_name;
53 int m_pipe_size;
54 int m_total_seg;
55 int m_next_seg;
56 int m_total_size;
57 bool m_output; // set to false by default
Alexander Afanasyevc1ebbe92014-01-16 22:24:34 -080058
59 int m_scope;
60 bool m_mustBeFresh;
Wentao Shang38d79682014-01-15 15:55:52 -080061};
62
63void
64Consumer::run ()
65{
66 try
67 {
68 for (int i = 0; i < m_pipe_size; i++)
69 {
70 ndn::Interest inst (ndn::Name(m_data_name).appendSegment (m_next_seg++));
Alexander Afanasyevc1ebbe92014-01-16 22:24:34 -080071 inst.setInterestLifetime (4000);
72 if (m_scope >= 0)
73 inst.setScope (m_scope);
74 inst.setMustBeFresh (m_mustBeFresh);
Wentao Shang38d79682014-01-15 15:55:52 -080075
76 m_face.expressInterest (inst,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080077 ndn::bind (&Consumer::on_data, this, _1, _2),
78 ndn::bind (&Consumer::on_timeout, this, _1));
Wentao Shang38d79682014-01-15 15:55:52 -080079 }
80
81 // processEvents will block until the requested data received or timeout occurs
82 m_face.processEvents ();
83 }
84 catch (std::exception& e)
85 {
86 std::cerr << "ERROR: " << e.what () << std::endl;
87 }
88}
89
90void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080091Consumer::on_data (const ndn::Interest& interest, ndn::Data& data)
Wentao Shang38d79682014-01-15 15:55:52 -080092{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080093 const ndn::Block& content = data.getContent ();
94 const ndn::Name& name = data.getName ();
Wentao Shang38d79682014-01-15 15:55:52 -080095
96 if (m_output)
97 {
98 std::cout.write(reinterpret_cast<const char*>(content.value()), content.value_size());
99 }
100
101 m_total_size += content.value_size ();
102
103 if ((int) (name.rbegin ()->toSegment ()) + 1 == m_total_seg)
104 {
105 std::cerr << "Last segment received." << std::endl;
106 std::cerr << "Total # bytes of content received: " << m_total_size << std::endl;
107 }
108 else
109 {
110 // Send interest for next segment
111 ndn::Interest inst (ndn::Name(m_data_name).appendSegment (m_next_seg++));
Alexander Afanasyevc1ebbe92014-01-16 22:24:34 -0800112 if (m_scope >= 0)
113 inst.setScope (m_scope);
114 inst.setInterestLifetime (4000);
115 inst.setMustBeFresh (m_mustBeFresh);
Wentao Shang38d79682014-01-15 15:55:52 -0800116
117 m_face.expressInterest (inst,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800118 ndn::bind (&Consumer::on_data, this, _1, _2),
119 ndn::bind (&Consumer::on_timeout, this, _1));
Wentao Shang38d79682014-01-15 15:55:52 -0800120 }
121}
122
123
124void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800125Consumer::on_timeout (const ndn::Interest& interest)
Wentao Shang38d79682014-01-15 15:55:52 -0800126{
127 //XXX: currently no retrans
128 std::cerr << "TIMEOUT: last interest sent for segment #" << (m_next_seg - 1) << std::endl;
129}
130
131
132int
133usage(const std::string &filename)
134{
135 std::cerr << "Usage: \n " << filename << " [-p pipe_size] [-c total_segment] [-o] /ndn/name\n";
136 return 1;
137}
138
139
140int
141main (int argc, char **argv)
142{
143 std::string name;
144 int pipe_size = 1;
145 int total_seg = std::numeric_limits<int>::max();
146 bool output = false;
147
148 int opt;
149 while ((opt = getopt(argc, argv, "op:c:")) != -1)
150 {
151 switch (opt)
152 {
153 case 'p':
154 pipe_size = atoi (optarg);
155 if (pipe_size <= 0)
156 pipe_size = 1;
157 std::cerr << "main (): set pipe size = " << pipe_size << std::endl;
158 break;
159 case 'c':
160 total_seg = atoi (optarg);
161 if (total_seg <= 0)
162 total_seg = 1;
163 std::cerr << "main (): set total seg = " << total_seg << std::endl;
164 break;
165 case 'o':
166 output = true;
167 break;
168 default:
169 return usage(argv[0]);
170 }
171 }
172
173 if (optind < argc)
174 {
175 name = argv[optind];
176 }
177
178 if (name.empty())
179 {
180 return usage(argv[0]);
181 }
182
183 Consumer consumer (name, pipe_size, total_seg);
184
185 if (output)
186 consumer.enable_output ();
187
188 consumer.run ();
189
190 return 0;
191}