blob: 0085f584cc64594ab4247609b0e70fdb59c48dbd [file] [log] [blame]
Alexander Afanasyevabc0d912015-08-13 16:49:02 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
4 *
5 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
7 *
8 * ndnSIM 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,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndnSIM 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 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20#include "ndn-stack-helper.hpp"
21
22#include "ns3/net-device.h"
23#include "ns3/node.h"
24
25#include <ndn-cxx/name.hpp>
26#include <map>
27
28namespace ns3 {
29namespace ndn {
30
31/**
32 * @ingroup ndn-helpers
33 * @brief Helper class to simplify writing basic simulation scenarios
34 *
35 * The following code with scenario helper creates a 3-node topology,
36 * with manual routes between nodes and 2 applications, installed on first and last node
37 * of the topology:
38 *
39 * ScenarioHelper helper;
40 * helper.createTopology({
41 * {"1", "2"},
42 * {"2", "3"}
43 * });
44 *
45 * helper.addRoutes({
46 * {"1", "2", "/prefix", 1},
47 * {"2", "3", "/prefix", 1}
48 * });
49 *
50 * helper.addApps({
51 * {"1", "ns3::ndn::ConsumerCbr",
52 * {{"Prefix", "/prefix"}, {"Frequency", "1"}},
53 * "0s", "100s"},
54 * {"3", "ns3::ndn::Producer",
55 * {{"Prefix", "/prefix"}, {"PayloadSize", "1024"}},
56 * "0s", "100s"}
57 * });
58 *
59 */
60class ScenarioHelper
61{
62public:
63 /**
64 * @brief Route information for addRoutes method
65 *
66 * It is preferred to use initializer list to indirectly pass RouteInfo's to addRoutes
67 * method.
68 */
69 struct RouteInfo
70 {
71 std::string node1;
72 std::string node2;
73 Name prefix;
74 int32_t metric;
75 };
76
77 /*
78 * @brief Application information for addApps method
79 *
80 * It is preferred to use initializer list to indirectly pass AppInfo's to addApps
81 * method.
82 */
83 struct AppInfo
84 {
85 std::string node;
86 std::string name;
87 std::initializer_list<std::pair<std::string, std::string>> params;
88 std::string start;
89 std::string end;
90 };
91
92public:
93 ScenarioHelper();
94
95 /**
96 * @brief Create topology
97 * @throw std::logic_error if createTopology is called more than once
98 *
99 * Example:
100 *
101 * ScenarioHelper helper;
102 * helper.createTopology({
103 * {"1", "2"},
104 * {"2", "3"}
105 * });
106 */
107 void
108 createTopology(std::initializer_list<std::initializer_list<std::string>/*node clique*/> topology);
109
110 /**
111 * @brief Create routes between topology nodes
112 * @throw std::invalid_argument if the nodes or links between nodes do not exist
113 *
114 * Example:
115 *
116 * helper.addRoutes({
117 * {"1", "2", "/prefix", 1},
118 * {"2", "3", "/prefix", 1}
119 * });
120 */
121 void
122 addRoutes(std::initializer_list<RouteInfo> routes);
123
124 /**
125 * @brief Create and install application on nodes
126 * @throw std::invalid_argument if the nodes or links between nodes do not exist
127 *
128 * Example:
129 *
130 * helper.addApps({
131 * {"1", "ns3::ndn::ConsumerCbr",
132 * {{"Prefix", "/prefix"}, {"Frequency", "1"}},
133 * "0s", "100s"},
134 * {"3", "ns3::ndn::Producer",
135 * {{"Prefix", "/prefix"}, {"PayloadSize", "1024"}},
136 * "0s", "100s"}
137 * });
138 */
139 void
140 addApps(std::initializer_list<AppInfo> apps);
141
142public: // topology accessors
143 /**
144 * @brief Get node
145 * @throw std::invalid_argument if the node does not exist
146 */
147 Ptr<Node>
148 getNode(const std::string& nodeName);
149
150 /**
151 * @brief Get face on the @p node1 pointing towards @p node2
152 * @throw std::invalid_argument if the link does not exist
153 */
154 shared_ptr<Face>
155 getFace(const std::string& node1, const std::string& node2);
156
157private:
158 Ptr<Node>
159 getOrCreateNode(const std::string& nodeName);
160
161private:
162 bool m_isTopologyInitialized;
163 StackHelper ndnHelper;
164 std::map<std::string, std::map<std::string, Ptr<NetDevice>>> links;
165 std::map<std::string, Ptr<Node>> nodes;
166};
167
168} // namespace ndn
169} // namespace ns3