blob: d2130180f0a7306be00e0841f0adb15239f4dc3e [file] [log] [blame]
Yingdi Yu31ad44c2014-08-28 14:55:42 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012-2014 University of California, Los Angeles
4 *
5 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
7 *
8 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation, either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
20 * @author Chaoyi Bian <bcy@pku.edu.cn>
21 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
22 * @author Yingdi Yu <yingdi@cs.ucla.edu>
23 */
24
25#ifndef CHRONOSYNC_SOCKET_HPP
26#define CHRONOSYNC_SOCKET_HPP
27
28#include <ndn-cxx/face.hpp>
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080029#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
30#include <unordered_map>
Yingdi Yu31ad44c2014-08-28 14:55:42 -070031
32#include "logic.hpp"
33
34namespace chronosync {
35
36/**
37 * @brief A simple interface to interact with client code
38 *
39 * Though it is called Socket, it is not a real socket. It just trying to provide
40 * a simplified interface for data publishing and fetching.
41 *
42 * This interface simplify data publishing. Client can simply dump raw data
43 * into this interface without handling the ChronoSync specific details, such
44 * as sequence number and session id.
45 *
46 * This interface also simplify data fetching. Client only needs to provide a
47 * data fetching strategy (through a updateCallback).
48 */
49class Socket : noncopyable
50{
51public:
52 class Error : public std::runtime_error
53 {
54 public:
55 explicit
56 Error(const std::string& what)
57 : std::runtime_error(what)
58 {
59 }
60 };
61
62 Socket(const Name& syncPrefix,
63 const Name& userPrefix,
64 ndn::Face& face,
Yingdi Yucd339022014-11-05 17:51:19 -080065 const UpdateCallback& updateCallback,
66 const Name& signingId = DEFAULT_NAME,
67 ndn::shared_ptr<ndn::Validator> validator = DEFAULT_VALIDATOR);
Yingdi Yu31ad44c2014-08-28 14:55:42 -070068
Qiuhan Ding03b9de32015-01-30 14:03:12 -080069 ~Socket();
70
71 /**
72 * @brief Add a sync node under same logic
73 *
74 * This method will add a new sync node in logic and then register this prefix.
75 * If pass an empty prefix, it will return directly without doing anything
76 * If the prefix is already registered, return directly
77 *
78 * @param prefix Prefix of the new node
79 * @param signingId Signing ID for the packet sent out by the new node
80 */
Yingdi Yu31ad44c2014-08-28 14:55:42 -070081 void
Qiuhan Dinge246b622014-12-03 21:57:48 -080082 addSyncNode(const Name& prefix, const Name& signingId = DEFAULT_NAME);
Yingdi Yu31ad44c2014-08-28 14:55:42 -070083
84 /**
Qiuhan Ding03b9de32015-01-30 14:03:12 -080085 * @brief Remove a sync node under same logic
86 *
87 * This method will remove a sync node in logic, unregister this prefix
88 * and then clear the in memory storage about this prefix.
89 * logic will be reset after removal of this node
90 *
91 * @param prefix Prefix of the node to remove
92 */
93 void
94 removeSyncNode(const Name& prefix);
95
96 /**
Yingdi Yu31ad44c2014-08-28 14:55:42 -070097 * @brief Publish a data packet in the session and trigger synchronization updates
98 *
99 * This method will create a data packet with the supplied content.
100 * The packet name is the local session + seqNo.
101 * The seqNo is automatically maintained by internal Logic.
102 *
Qiuhan Dinge246b622014-12-03 21:57:48 -0800103 * @throws It will throw error, if the prefix does not exist in m_logic
104 *
105 * @param buf Pointer to the bytes in content
106 * @param len size of the bytes in content
107 * @param freshness FreshnessPeriod of the data packet.
108 */
109 void
110 publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
111 const Name& prefix = DEFAULT_PREFIX);
112
113 /**
114 * @brief Publish a data packet in the session and trigger synchronization updates
115 *
116 * This method will create a data packet with the supplied content.
117 * The packet name is the local session + seqNo.
118 * The seqNo is automatically maintained by internal Logic.
119 *
120 * @throws It will throw error, if the prefix does not exist in m_logic
121 *
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700122 * @param content Block that will be set as the content of the data packet.
123 * @param freshness FreshnessPeriod of the data packet.
124 */
125 void
Qiuhan Dinge246b622014-12-03 21:57:48 -0800126 publishData(const Block& content, const ndn::time::milliseconds& freshness,
127 const Name& prefix = DEFAULT_PREFIX);
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700128
129 /**
130 * @brief Retrive a data packet with a particular seqNo from a session
131 *
132 * @param sessionName The name of the target session.
133 * @param seq The seqNo of the data packet.
134 * @param onValidated The callback when the retrieved packet has been validated.
135 * @param nRetries The number of retries.
136 */
137 void
138 fetchData(const Name& sessionName, const SeqNo& seq,
139 const ndn::OnDataValidated& onValidated,
140 int nRetries = 0);
141
142 /**
143 * @brief Retrive a data packet with a particular seqNo from a session
144 *
145 * @param sessionName The name of the target session.
146 * @param seq The seqNo of the data packet.
147 * @param onValidated The callback when the retrieved packet has been validated.
148 * @param nRetries The number of retries.
149 */
150 void
151 fetchData(const Name& sessionName, const SeqNo& seq,
152 const ndn::OnDataValidated& onValidated,
153 const ndn::OnDataValidationFailed& onValidationFailed,
154 const ndn::OnTimeout& onTimeout,
155 int nRetries = 0);
156
157 /// @brief Get the root digest of current sync tree
158 ndn::ConstBufferPtr
159 getRootDigest() const;
160
161 Logic&
162 getLogic()
163 {
164 return m_logic;
165 }
166
167private:
168 void
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800169 onInterest(const Name& prefix, const Interest& interest);
170
171 void
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700172 onData(const Interest& interest, Data& data,
173 const ndn::OnDataValidated& dataCallback,
174 const ndn::OnDataValidationFailed& failCallback);
175
176 void
177 onDataTimeout(const Interest& interest, int nRetries,
178 const ndn::OnDataValidated& dataCallback,
179 const ndn::OnDataValidationFailed& failCallback);
180
181 void
182 onDataValidationFailed(const shared_ptr<const Data>& data,
183 const std::string& failureInfo);
184
Yingdi Yucd339022014-11-05 17:51:19 -0800185public:
186 static const ndn::Name DEFAULT_NAME;
Qiuhan Dinge246b622014-12-03 21:57:48 -0800187 static const ndn::Name DEFAULT_PREFIX;
Yingdi Yucd339022014-11-05 17:51:19 -0800188 static const ndn::shared_ptr<ndn::Validator> DEFAULT_VALIDATOR;
189
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700190private:
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800191 typedef std::unordered_map<ndn::Name, const ndn::RegisteredPrefixId*> RegisteredPrefixList;
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700192
193 Name m_userPrefix;
194 ndn::Face& m_face;
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700195 Logic m_logic;
196
Yingdi Yucd339022014-11-05 17:51:19 -0800197 ndn::Name m_signingId;
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700198 ndn::KeyChain m_keyChain;
Yingdi Yucd339022014-11-05 17:51:19 -0800199 ndn::shared_ptr<ndn::Validator> m_validator;
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800200
201 RegisteredPrefixList m_registeredPrefixList;
202 ndn::util::InMemoryStoragePersistent m_ims;
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700203};
204
205} // namespace chronosync
206
207#endif // CHRONOSYNC_SOCKET_HPP