blob: e0c62a1475fe587fed2d974c52af6e43a5fbe607 [file] [log] [blame]
Alexander Afanasyeva9034b02014-01-26 18:32:02 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi2d491752017-07-14 21:32:05 +00002/*
Junxiao Shi38b24c72017-01-05 02:59:31 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
Davide Pesavento1d7e7af2015-10-10 23:54:08 +02004 * 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.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP
27#define NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080028
Davide Pesavento47ab0292015-11-02 18:45:39 +010029#include "channel.hpp"
Junxiao Shi38b24c72017-01-05 02:59:31 +000030#include "face-system.hpp"
Davide Pesaventoe5eebad2017-04-06 20:23:26 -040031
Junxiao Shi38b24c72017-01-05 02:59:31 +000032#include <boost/range/adaptor/map.hpp>
33#include <boost/range/algorithm/copy.hpp>
Junxiao Shi2d491752017-07-14 21:32:05 +000034#include <ndn-cxx/encoding/nfd-constants.hpp>
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080035
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080036namespace nfd {
Junxiao Shi38b24c72017-01-05 02:59:31 +000037namespace face {
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080038
Junxiao Shi0ba6d642017-07-17 00:53:22 +000039/** \brief Parameters to ProtocolFactory constructor
40 *
41 * Every ProtocolFactory subclass is expected to have a constructor that accepts CtorParams,
42 * which in turn passes it to ProtocolFactory base class constructor. Parameters are passed as a
43 * struct rather than individually, so that a future change in list of parameters does not
44 * require updates to subclass constructors.
45 */
46struct ProtocolFactoryCtorParams
47{
48 FaceCreatedCallback addFace;
49 shared_ptr<ndn::net::NetworkMonitor> netmon;
50};
51
Junxiao Shi2d491752017-07-14 21:32:05 +000052/** \brief Provides support for an underlying protocol
Junxiao Shi38b24c72017-01-05 02:59:31 +000053 * \sa FaceSystem
54 *
55 * A protocol factory provides support for an underlying protocol and owns Channel objects.
56 * It can process a subsection of face_system config section and create channels and multicast
57 * faces accordingly.
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020058 */
Junxiao Shi38b24c72017-01-05 02:59:31 +000059class ProtocolFactory : noncopyable
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080060{
Junxiao Shib47247d2017-01-24 15:09:16 +000061public: // registry
Junxiao Shi0ba6d642017-07-17 00:53:22 +000062 using CtorParams = ProtocolFactoryCtorParams;
63
Junxiao Shi2d491752017-07-14 21:32:05 +000064 /** \brief Register a protocol factory type
Junxiao Shib47247d2017-01-24 15:09:16 +000065 * \tparam S subclass of ProtocolFactory
66 * \param id factory identifier
67 */
68 template<typename PF>
69 static void
70 registerType(const std::string& id = PF::getId())
71 {
72 Registry& registry = getRegistry();
73 BOOST_ASSERT(registry.count(id) == 0);
Junxiao Shi0ba6d642017-07-17 00:53:22 +000074 registry[id] = &make_unique<PF, const CtorParams&>;
Junxiao Shib47247d2017-01-24 15:09:16 +000075 }
76
Junxiao Shi2d491752017-07-14 21:32:05 +000077 /** \brief Create a protocol factory instance
Junxiao Shib47247d2017-01-24 15:09:16 +000078 * \retval nullptr if factory with \p id is not registered
79 */
80 static unique_ptr<ProtocolFactory>
Junxiao Shi0ba6d642017-07-17 00:53:22 +000081 create(const std::string& id, const CtorParams& params);
Junxiao Shib47247d2017-01-24 15:09:16 +000082
Junxiao Shi2d491752017-07-14 21:32:05 +000083 /** \brief Get registered protocol factory ids
Junxiao Shib47247d2017-01-24 15:09:16 +000084 */
85 static std::set<std::string>
86 listRegistered();
87
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080088public:
Junxiao Shi0ba6d642017-07-17 00:53:22 +000089 /** \brief Base class for all exceptions thrown by ProtocolFactory subclasses
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080090 */
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020091 class Error : public std::runtime_error
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080092 {
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020093 public:
94 explicit
95 Error(const std::string& what)
96 : std::runtime_error(what)
97 {
98 }
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080099 };
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800100
Junxiao Shib47247d2017-01-24 15:09:16 +0000101 virtual
102 ~ProtocolFactory() = default;
103
104#ifdef DOXYGEN
Junxiao Shi2d491752017-07-14 21:32:05 +0000105 /** \brief Get id for this ProtocolFactory
Junxiao Shib47247d2017-01-24 15:09:16 +0000106 *
107 * face_system.factory-id config section is processed by the protocol factory.
108 */
109 static const std::string&
110 getId();
111#endif
112
Junxiao Shi2d491752017-07-14 21:32:05 +0000113 /** \brief Process face_system subsection that corresponds to this ProtocolFactory type
Junxiao Shi38b24c72017-01-05 02:59:31 +0000114 * \param configSection the configuration section or boost::null to indicate it is omitted
115 * \param context provides access to data structures and contextual information
116 * \throw ConfigFile::Error invalid configuration
117 *
118 * This function updates \p providedSchemes
119 */
120 virtual void
121 processConfig(OptionalConfigSection configSection,
Junxiao Shic3443042017-01-26 17:21:35 +0000122 FaceSystem::ConfigContext& context) = 0;
Junxiao Shi38b24c72017-01-05 02:59:31 +0000123
Junxiao Shi2d491752017-07-14 21:32:05 +0000124 /** \brief Get FaceUri schemes accepted by this ProtocolFactory
Junxiao Shi38b24c72017-01-05 02:59:31 +0000125 */
126 const std::set<std::string>&
127 getProvidedSchemes()
128 {
129 return providedSchemes;
130 }
131
Eric Newberry944f38b2017-07-20 20:54:22 -0400132 /** \brief Parameters to ProtocolFactory::createFace
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800133 *
Eric Newberry944f38b2017-07-20 20:54:22 -0400134 * Parameters are passed as a struct rather than individually, so that a future change in the list
135 * of parameters does not require an update to the method signature in all subclasses.
136 */
137 struct CreateFaceParams
138 {
139 FaceUri remoteUri;
140 ndn::optional<FaceUri> localUri;
141 ndn::nfd::FacePersistency persistency;
Eric Newberry2642cd22017-07-13 21:34:53 -0400142 bool wantLocalFields;
143 bool wantLpReliability;
Eric Newberry944f38b2017-07-20 20:54:22 -0400144 };
145
146 /** \brief Try to create face using the supplied parameters
147 *
148 * \param params parameters to create face with
Eric Newberry78e32b02017-04-01 14:34:44 +0000149 * \param onCreated callback if face creation succeeds or face already exists;
150 * persistency and local fields settings are not updated on an existing face
Eric Newberryf40551a2016-09-05 15:41:16 -0700151 * \param onFailure callback if face creation fails
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800152 */
153 virtual void
Eric Newberry944f38b2017-07-20 20:54:22 -0400154 createFace(const CreateFaceParams& params,
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800155 const FaceCreatedCallback& onCreated,
Eric Newberryf40551a2016-09-05 15:41:16 -0700156 const FaceCreationFailedCallback& onFailure) = 0;
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600157
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200158 virtual std::vector<shared_ptr<const Channel>>
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600159 getChannels() const = 0;
Junxiao Shi38b24c72017-01-05 02:59:31 +0000160
161protected:
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000162 explicit
163 ProtocolFactory(const CtorParams& params);
164
Junxiao Shi38b24c72017-01-05 02:59:31 +0000165 template<typename ChannelMap>
166 static std::vector<shared_ptr<const Channel>>
167 getChannelsFromMap(const ChannelMap& channelMap)
168 {
169 std::vector<shared_ptr<const Channel>> channels;
170 boost::copy(channelMap | boost::adaptors::map_values, std::back_inserter(channels));
171 return channels;
172 }
173
Junxiao Shib47247d2017-01-24 15:09:16 +0000174private: // registry
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000175 using CreateFunc = std::function<unique_ptr<ProtocolFactory>(const CtorParams&)>;
176 using Registry = std::map<std::string, CreateFunc>; // indexed by factory id
Junxiao Shib47247d2017-01-24 15:09:16 +0000177
178 static Registry&
179 getRegistry();
180
Junxiao Shi38b24c72017-01-05 02:59:31 +0000181protected:
Junxiao Shi2d491752017-07-14 21:32:05 +0000182 std::set<std::string> providedSchemes; ///< FaceUri schemes provided by this ProtocolFactory
183
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000184 FaceCreatedCallback addFace; ///< callback when a new face is created
185
Junxiao Shi2d491752017-07-14 21:32:05 +0000186 /** \brief NetworkMonitor for listing available network interfaces and monitoring their changes
187 *
188 * ProtocolFactory subclass should check the NetworkMonitor has sufficient capabilities prior
189 * to usage.
Junxiao Shi38b24c72017-01-05 02:59:31 +0000190 */
Junxiao Shi2d491752017-07-14 21:32:05 +0000191 shared_ptr<ndn::net::NetworkMonitor> netmon;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800192};
193
Junxiao Shi38b24c72017-01-05 02:59:31 +0000194} // namespace face
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800195} // namespace nfd
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800196
Junxiao Shib47247d2017-01-24 15:09:16 +0000197/** \brief registers a protocol factory
198 *
199 * This macro should appear once in .cpp of each protocol factory.
200 */
201#define NFD_REGISTER_PROTOCOL_FACTORY(PF) \
202static class NfdAuto ## PF ## ProtocolFactoryRegistrationClass \
203{ \
204public: \
205 NfdAuto ## PF ## ProtocolFactoryRegistrationClass() \
206 { \
207 ::nfd::face::ProtocolFactory::registerType<PF>(); \
208 } \
209} g_nfdAuto ## PF ## ProtocolFactoryRegistrationVariable
210
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700211#endif // NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP