blob: 144e0dcf941070ee85a7038f514edb163412baae [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#ifndef NFD_DAEMON_FACE_TRANSPORT_HPP
27#define NFD_DAEMON_FACE_TRANSPORT_HPP
28
29#include "common.hpp"
30
31#include "face-counters.hpp"
32#include "face-log.hpp"
33
34namespace nfd {
35namespace face {
36
37class LpFace;
38class LinkService;
39
40/** \brief indicates the state of a transport
41 */
42enum class TransportState {
43 NONE,
44 UP, ///< the transport is up
45 DOWN, ///< the transport is down temporarily, and is being recovered
46 CLOSING, ///< the transport is requested to be closed
47 FAILED, ///< the transport is being closed due to a failure
48 CLOSED ///< the transport is closed, and can be safely deallocated
49};
50
51std::ostream&
52operator<<(std::ostream& os, TransportState state);
53
54/** \brief the lower part of an LpFace
55 * \sa LpFace
56 */
57class Transport : noncopyable
58{
59public:
60 /** \brief identifies an endpoint on the link
61 */
62 typedef uint64_t EndpointId;
63
64 /** \brief stores a packet along with the remote endpoint
65 */
66 class Packet
67 {
68 public:
69 Packet() = default;
70
71 explicit
72 Packet(Block&& packet);
73
74 public:
75 /** \brief the packet as a TLV block
76 */
77 Block packet;
78
79 /** \brief identifies the remote endpoint
80 *
81 * This ID is only meaningful in the context of the same Transport.
82 * Incoming packets from the same remote endpoint have the same EndpointId,
83 * and incoming packets from different remote endpoints have different EndpointIds.
84 */
85 EndpointId remoteEndpoint;
86 };
87
88 Transport();
89
90 virtual
91 ~Transport();
92
93public:
94 /** \brief set Face and LinkService for Transport
95 * \pre setFaceAndLinkService has not been called
96 */
97 void
98 setFaceAndLinkService(LpFace& face, LinkService& service);
99
100 /** \return Face to which this Transport is attached
101 */
102 const LpFace*
103 getFace() const;
104
105 /** \return LinkService to which this Transport is attached
106 */
107 const LinkService*
108 getLinkService() const;
109
110 /** \return LinkService to which this Transport is attached
111 */
112 LinkService*
113 getLinkService();
114
115public: // upper interface
116 /** \brief request the transport to be closed
117 *
118 * This operation is effective only if transport is in UP or DOWN state,
119 * otherwise it has no effect.
120 * The transport changes state to CLOSING, and performs cleanup procedure.
121 * The state will be changed to CLOSED when cleanup is complete, which may
122 * happen synchronously or asynchronously.
123 */
124 void
125 close();
126
127 /** \brief send a link-layer packet
128 */
129 void
130 send(Packet&& packet);
131
132protected: // upper interface to be invoked by subclass
133 /** \brief receive a link-layer packet
134 */
135 void
136 receive(Packet&& packet);
137
138public: // static properties
139 /** \return a FaceUri representing local endpoint
140 */
141 FaceUri
142 getLocalUri() const;
143
144 /** \return a FaceUri representing remote endpoint
145 */
146 FaceUri
147 getRemoteUri() const;
148
149 /** \return whether face is local or non-local for scope control purpose
150 */
151 ndn::nfd::FaceScope
152 getScope() const;
153
154 /** \return face persistency setting
155 */
156 ndn::nfd::FacePersistency
157 getPersistency() const;
158
159 /** \brief changes face persistency setting
160 */
161 void
162 setPersistency(ndn::nfd::FacePersistency persistency);
163
164 /** \return whether face is point-to-point or multi-access
165 */
166 ndn::nfd::LinkType
167 getLinkType() const;
168
169public: // dynamic properties
170 /** \return transport state
171 */
172 TransportState
173 getState() const;
174
175 /** \brief signals when transport state changes
176 */
177 signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;
178
179protected: // properties to be set by subclass
180 void
181 setLocalUri(const FaceUri& uri);
182
183 void
184 setRemoteUri(const FaceUri& uri);
185
186 void
187 setScope(ndn::nfd::FaceScope scope);
188
189 void
190 setLinkType(ndn::nfd::LinkType linkType);
191
192 /** \brief set transport state
193 *
194 * Only the following transitions are valid:
195 * UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
196 *
197 * \throw std::runtime_error transition is invalid.
198 */
199 void
200 setState(TransportState newState);
201
202protected: // to be overridden by subclass
203 /** \brief invoked before persistency is changed
204 * \throw std::invalid_argument new persistency is not supported
205 * \throw std::runtime_error transition is disallowed
206 *
207 * Base class implementation does nothing.
208 */
209 virtual void
210 beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
211 {
212 }
213
214 /** \brief performs Transport specific operations to close the transport
215 *
216 * When the cleanup procedure is complete, this method should change state to CLOSED.
217 * This can happen synchronously or asynchronously.
218 */
219 virtual void
220 doClose() = 0;
221
222private: // to be overridden by subclass
223 /** \brief performs Transport specific operations to send a packet
224 * \param packet the packet, which must be a well-formed TLV block
225 */
226 virtual void
227 doSend(Packet&& packet) = 0;
228
229private:
230 LpFace* m_face;
231 LinkService* m_service;
232 FaceUri m_localUri;
233 FaceUri m_remoteUri;
234 ndn::nfd::FaceScope m_scope;
235 ndn::nfd::FacePersistency m_persistency;
236 ndn::nfd::LinkType m_linkType;
237 TransportState m_state;
238 LinkLayerCounters* m_counters; // TODO#3177 change into LinkCounters
239};
240
241inline const LpFace*
242Transport::getFace() const
243{
244 return m_face;
245}
246
247inline const LinkService*
248Transport::getLinkService() const
249{
250 return m_service;
251}
252
253inline LinkService*
254Transport::getLinkService()
255{
256 return m_service;
257}
258
259inline FaceUri
260Transport::getLocalUri() const
261{
262 return m_localUri;
263}
264
265inline FaceUri
266Transport::getRemoteUri() const
267{
268 return m_remoteUri;
269}
270
271inline ndn::nfd::FaceScope
272Transport::getScope() const
273{
274 return m_scope;
275}
276
277inline ndn::nfd::FacePersistency
278Transport::getPersistency() const
279{
280 return m_persistency;
281}
282
283inline void
284Transport::setPersistency(ndn::nfd::FacePersistency persistency)
285{
286 this->beforeChangePersistency(persistency);
287 m_persistency = persistency;
288}
289
290inline ndn::nfd::LinkType
291Transport::getLinkType() const
292{
293 return m_linkType;
294}
295
296inline TransportState
297Transport::getState() const
298{
299 return m_state;
300}
301
302inline void
303Transport::setLocalUri(const FaceUri& uri)
304{
305 m_localUri = uri;
306}
307
308inline void
309Transport::setRemoteUri(const FaceUri& uri)
310{
311 m_remoteUri = uri;
312}
313
314inline void
315Transport::setScope(ndn::nfd::FaceScope scope)
316{
317 m_scope = scope;
318}
319
320inline void
321Transport::setLinkType(ndn::nfd::LinkType linkType)
322{
323 m_linkType = linkType;
324}
325
326std::ostream&
327operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);
328
329template<typename T>
330typename std::enable_if<std::is_base_of<Transport, T>::value &&
331 !std::is_same<Transport, T>::value, std::ostream&>::type
332operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
333{
334 return os << FaceLogHelper<Transport>(flh.obj);
335}
336
337} // namespace face
338} // namespace nfd
339
340#endif // NFD_DAEMON_FACE_TRANSPORT_HPP