blob: 06b3f02906e7ed7340407ff6a7e395d8f65de029 [file] [log] [blame]
spirosmastorakis2f769c22016-03-12 11:46:04 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3* Copyright (c) 2016 Regents of the University of California.
4*
5* This file is part of the nTorrent codebase.
6*
7* nTorrent 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* nTorrent 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 nTorrent, e.g., in COPYING.md file. If not, see
17* <http://www.gnu.org/licenses/>.
18*
19* See AUTHORS for complete list of nTorrent authors and contributors.
20*/
21
22#include "sequential-data-fetcher.hpp"
23#include "util/io-util.hpp"
24
25namespace ndn {
26namespace ntorrent {
27
28SequentialDataFetcher::SequentialDataFetcher(const ndn::Name& torrentFileName,
29 const std::string& dataPath)
30 : m_dataPath(dataPath)
31 , m_torrentFileName(torrentFileName)
32{
33 m_manager = make_shared<TorrentManager>(m_torrentFileName, m_dataPath);
34}
35
36SequentialDataFetcher::~SequentialDataFetcher()
37{
38}
39
40void
41SequentialDataFetcher::start()
42{
43 m_manager->Initialize();
44 // downloading logic
45 this->implementSequentialLogic();
46}
47
48void
49SequentialDataFetcher::pause()
50{
51 // TODO(Spyros): Implement asyncrhonous pause of the torrent downloading
52 // For now, do nothing...
53 throw(Error("Not implemented yet"));
54}
55
56void
57SequentialDataFetcher::resume()
58{
59 // TODO(Spyros): Implement asyncrhonous re-establishment of the torrent downloading
60 // For now, do nothing...
61 throw(Error("Not implemented yet"));
62}
63
64std::vector<ndn::Name>
65SequentialDataFetcher::downloadTorrentFile()
66{
67 std::vector<ndn::Name> returnedNames;
68 returnedNames = m_manager->downloadTorrentFile(".appdata/torrent_files/");
Mickey Sweatt67133bf2016-04-25 12:37:35 -070069 if (!returnedNames.empty() && IoUtil::NAME_TYPE::FILE_MANIFEST == IoUtil::findType(returnedNames[0])) {
70 std::cout << "Torrent File Received: "
71 << m_torrentFileName.getSubName(0, m_torrentFileName.size() - 1) << std::endl;
72 }
spirosmastorakis2f769c22016-03-12 11:46:04 -080073 return returnedNames;
74}
75
76void
77SequentialDataFetcher::downloadManifestFiles(const std::vector<ndn::Name>& manifestsName)
78{
79 std::vector<ndn::Name> packetsName;
80 for (auto i = manifestsName.begin(); i != manifestsName.end(); i++) {
81 m_manager->download_file_manifest(*i,
82 ".appdata/manifests/",
83 bind(&SequentialDataFetcher::onManifestReceived, this, _1),
84 bind(&SequentialDataFetcher::onDataRetrievalFailure, this, _1, _2));
Mickey Sweattb7ee19c2016-04-21 12:18:15 -070085 m_manager->processEvents();
spirosmastorakis2f769c22016-03-12 11:46:04 -080086 }
87}
88
89void
90SequentialDataFetcher::downloadPackets(const std::vector<ndn::Name>& packetsName)
91{
92 for (auto i = packetsName.begin(); i != packetsName.end(); i++) {
93 m_manager->download_data_packet(*i,
94 bind(&SequentialDataFetcher::onDataPacketReceived, this, _1),
95 bind(&SequentialDataFetcher::onDataRetrievalFailure, this, _1, _2));
96 }
Mickey Sweatt67133bf2016-04-25 12:37:35 -070097 m_manager->processEvents();
spirosmastorakis2f769c22016-03-12 11:46:04 -080098}
99
100void
101SequentialDataFetcher::implementSequentialLogic() {
102 std::vector<ndn::Name> returnedNames;
103 returnedNames = this->downloadTorrentFile();
104 if (returnedNames.empty()) {
105 // we have downloaded the entire torrent (including manifests, data packets, etc..)
106 return;
107 }
108 // check the first returned name whether it is the name of a file manifest or a data packet
109 const Name& nameToCheck = returnedNames[0];
110 if (IoUtil::findType(nameToCheck) == IoUtil::DATA_PACKET) {
111 // In this case, the returned names correspond to data packets
112 this->downloadPackets(returnedNames);
113 }
114 else {
115 // In this case, the returned names correspond to file manifests
116 this->downloadManifestFiles(returnedNames);
117 }
118}
119
120void
121SequentialDataFetcher::onDataPacketReceived(const ndn::Data& data)
122{
123 // Data Packet Received
124 std::cout << "Data Packet Received: " << data.getName();
125}
126
127void
128SequentialDataFetcher::onManifestReceived(const std::vector<Name>& packetNames)
129{
130 std::cout << "Manifest File Received: "
131 << packetNames[0].getSubName(0, packetNames[0].size()- 3) << std::endl;
132 this->downloadPackets(packetNames);
133}
134
135void
136SequentialDataFetcher::onDataRetrievalFailure(const ndn::Interest& interest,
137 const std::string& errorCode)
138{
Mickey Sweatt67133bf2016-04-25 12:37:35 -0700139 // std::cerr << "Data Retrieval Failed: " << interest.getName() << std::endl;
Mickey Sweattb7ee19c2016-04-21 12:18:15 -0700140
spirosmastorakis2f769c22016-03-12 11:46:04 -0800141 // Data retrieval failure
142 uint32_t nameType = IoUtil::findType(interest.getName());
143 if (nameType == IoUtil::TORRENT_FILE) {
144 // this should never happen
Mickey Sweatt67133bf2016-04-25 12:37:35 -0700145 // std::cerr << "Torrent File Segment Downloading Failed: " << interest.getName();
spirosmastorakis2f769c22016-03-12 11:46:04 -0800146 this->downloadTorrentFile();
147 }
148 else if (nameType == IoUtil::FILE_MANIFEST) {
Mickey Sweatt67133bf2016-04-25 12:37:35 -0700149 // std::cerr << "Manifest File Segment Downloading Failed: " << interest.getName();
spirosmastorakis2f769c22016-03-12 11:46:04 -0800150 this->downloadManifestFiles({ interest.getName() });
151 }
152 else if (nameType == IoUtil::DATA_PACKET) {
Mickey Sweatt67133bf2016-04-25 12:37:35 -0700153 // std::cerr << "Data Packet Downloading Failed: " << interest.getName();
spirosmastorakis2f769c22016-03-12 11:46:04 -0800154 this->downloadPackets({ interest.getName() });
155 }
156 else {
157 // This should never happen
Mickey Sweatt67133bf2016-04-25 12:37:35 -0700158 // std::cerr << "Unknown Packet Type Downloading Failed: " << interest.getName();
spirosmastorakis2f769c22016-03-12 11:46:04 -0800159 }
160}
161
162} // namespace ntorrent
163} // namespace ndn