--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/click/examples/nsclick-defines.cc Thu Feb 07 10:47:31 2013 +0100
@@ -0,0 +1,66 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Sascha Jopen <jopen@cs.uni-bonn.de>
+ */
+
+
+#include "ns3/core-module.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/click-internet-stack-helper.h"
+#include <map>
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("NsclickRouting");
+
+int
+main (int argc, char *argv[])
+{
+#ifdef NS3_CLICK
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+ NS_LOG_INFO ("Create a node.");
+ NodeContainer n;
+ n.Create (1);
+
+//
+// Install Click on the nodes
+//
+ std::map<std::string, std::string> defines;
+// Strings, especially with blanks in it, have to be enclosed in quotation
+// marks, like in click configuration files.
+ defines["OUTPUT"] = "\"Hello World!\"";
+
+ ClickInternetStackHelper clickinternet;
+ clickinternet.SetClickFile (n, "src/click/examples/nsclick-defines.click");
+ clickinternet.SetRoutingTableElement (n, "rt");
+ clickinternet.SetDefines(n, defines);
+ clickinternet.Install (n);
+
+//
+// Now, do the actual simulation.
+//
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Stop (Seconds (20.0));
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+#else
+ NS_FATAL_ERROR ("Can't use ns-3-click without NSCLICK compiled in");
+#endif
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/click/examples/nsclick-defines.click Thu Feb 07 10:47:31 2013 +0100
@@ -0,0 +1,9 @@
+define($OUTPUT "This is a default value for OUTPUT");
+define($UNDEFINED "UNDEFINED is an undefined variable");
+
+// It is mandatory to use an IPRouteTable element with ns-3-click
+rt :: LinearIPLookup ();
+Idle -> rt;
+
+output :: Message($OUTPUT);
+undefined :: Message($UNDEFINED);
--- a/src/click/examples/wscript Thu Feb 07 10:47:08 2013 +0100
+++ b/src/click/examples/wscript Thu Feb 07 10:47:31 2013 +0100
@@ -20,3 +20,7 @@
obj = bld.create_ns3_program('nsclick-routing',
['click', 'csma', 'internet', 'applications'])
obj.source = 'nsclick-routing.cc'
+
+ obj = bld.create_ns3_program('nsclick-defines',
+ ['click'])
+ obj.source = 'nsclick-defines.cc'
--- a/src/click/helper/click-internet-stack-helper.cc Thu Feb 07 10:47:08 2013 +0100
+++ b/src/click/helper/click-internet-stack-helper.cc Thu Feb 07 10:47:31 2013 +0100
@@ -125,6 +125,21 @@
}
void
+ClickInternetStackHelper::SetDefines (NodeContainer c, std::map<std::string, std::string> defines)
+{
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ SetDefines (*i, defines);
+ }
+}
+
+void
+ClickInternetStackHelper::SetDefines (Ptr<Node> node, std::map<std::string, std::string> defines)
+{
+ m_nodeToDefinesMap.insert (std::make_pair (node, defines));
+}
+
+void
ClickInternetStackHelper::SetRoutingTableElement (NodeContainer c, std::string rt)
{
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
@@ -193,6 +208,13 @@
ipv4Routing->SetClickFile (it->second);
}
+ std::map<Ptr<Node>, std::map<std::string, std::string> >::const_iterator definesIt;
+ definesIt = m_nodeToDefinesMap.find (node);
+ if (definesIt != m_nodeToDefinesMap.end ())
+ {
+ ipv4Routing->SetDefines (definesIt->second);
+ }
+
it = m_nodeToRoutingTableElementMap.find (node);
if (it != m_nodeToRoutingTableElementMap.end ())
{
--- a/src/click/helper/click-internet-stack-helper.h Thu Feb 07 10:47:08 2013 +0100
+++ b/src/click/helper/click-internet-stack-helper.h Thu Feb 07 10:47:31 2013 +0100
@@ -143,6 +143,20 @@
void SetClickFile (Ptr<Node> node, std::string clickfile);
/**
+ * \brief Set defines to be used for a group of nodes.
+ * \param c NodeContainer of nodes
+ * \param defines Defines mapping to be used
+ */
+ void SetDefines (NodeContainer c, std::map<std::string, std::string> defines);
+
+ /**
+ * \brief Set defines to be used for a node.
+ * \param node Node for which the defines are to be set
+ * \param defines Defines mapping to be used
+ */
+ void SetDefines (Ptr<Node> node, std::map<std::string, std::string> defines);
+
+ /**
* \brief Set a Click routing table element for a group of nodes.
* \param c NodeContainer of nodes
* \param rt Click Routing Table element name
@@ -219,6 +233,11 @@
std::map < Ptr<Node>, std::string > m_nodeToClickFileMap;
/**
+ * \brief Node to Click defines mapping
+ */
+ std::map < Ptr<Node>, std::map<std::string, std::string> > m_nodeToDefinesMap;
+
+ /**
* \brief Node to Routing Table Element mapping
*/
std::map < Ptr<Node>, std::string > m_nodeToRoutingTableElementMap;
--- a/src/click/model/ipv4-click-routing.cc Thu Feb 07 10:47:08 2013 +0100
+++ b/src/click/model/ipv4-click-routing.cc Thu Feb 07 10:47:31 2013 +0100
@@ -65,6 +65,10 @@
m_ipv4 (0)
{
m_random = CreateObject<UniformRandomVariable> ();
+ m_simNode = new simclick_node_t;
+ timerclear (&m_simNode->curtime);
+
+ AddSimNodeToClickMapping ();
}
Ipv4ClickRouting::~Ipv4ClickRouting ()
@@ -83,11 +87,6 @@
m_nodeName = name.str ();
}
- m_simNode = new simclick_node_t;
- timerclear (&m_simNode->curtime);
-
- AddSimNodeToClickMapping ();
-
NS_ASSERT (m_clickFile.length () > 0);
// Even though simclick_click_create() will halt programme execution
@@ -138,6 +137,18 @@
}
void
+Ipv4ClickRouting::SetDefines (std::map<std::string, std::string> defines)
+{
+ m_defines = defines;
+}
+
+std::map<std::string, std::string>
+Ipv4ClickRouting::GetDefines (void)
+{
+ return m_defines;
+}
+
+void
Ipv4ClickRouting::SetClickRoutingTableElement (std::string name)
{
m_clickRoutingTableElement = name;
@@ -614,7 +625,7 @@
case SIMCLICK_SUPPORTS:
{
int othercmd = va_arg (val, int);
- retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_RANDOM_INT);
+ retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
break;
}
@@ -757,6 +768,48 @@
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_RANDOM: " << *randomValue << " " << maxValue << " " << ns3::Simulator::Now ());
break;
}
+
+ case SIMCLICK_GET_DEFINES:
+ {
+ char *buf = va_arg (val, char *);
+ size_t *size = va_arg (val, size_t *);
+ uint32_t required = 0;
+
+ // Try to fill the buffer with up to size bytes.
+ // If this is not enough space, write the required buffer size into
+ // the size variable and return an error code.
+ // Otherwise return the bytes actually writte into the buffer in size.
+
+ // Append key/value pair, seperated by \0.
+ std::map<std::string, std::string> defines = clickInstance->GetDefines ();
+ std::map<std::string, std::string>::const_iterator it = defines.begin ();
+ while (it != defines.end ())
+ {
+ size_t available = *size - required;
+ if (it->first.length() + it->second.length() + 2 <= available)
+ {
+ simstrlcpy(buf + required, available, it->first);
+ required += it->first.length() + 1;
+ available -= it->first.length() + 1;
+ simstrlcpy(buf + required, available, it->second);
+ required += it->second.length() + 1;
+ }
+ else
+ {
+ required += it->first.length() + it->second.length() + 2;
+ }
+ it++;
+ }
+ if (required > *size)
+ {
+ retval = -1;
+ }
+ else
+ {
+ retval = 0;
+ }
+ *size = required;
+ }
}
return retval;
}
--- a/src/click/model/ipv4-click-routing.h Thu Feb 07 10:47:08 2013 +0100
+++ b/src/click/model/ipv4-click-routing.h Thu Feb 07 10:47:31 2013 +0100
@@ -79,6 +79,12 @@
void SetClickFile (std::string clickfile);
/**
+ * \brief Click defines to be used by the node's Click Instance.
+ * \param defines mapping of defines for .click configuration file parsing
+ */
+ void SetDefines (std::map<std::string, std::string> defines);
+
+ /**
* \brief Name of the node as to be used by Click. Required for Click Dumps.
* \param name Name to be assigned to the node.
*/
@@ -132,6 +138,12 @@
public:
/**
+ * \brief Provides for SIMCLICK_GET_DEFINES
+ * \return The defines mapping for .click configuration file parsing
+ */
+ std::map<std::string, std::string> GetDefines (void);
+
+ /**
* \brief Provides for SIMCLICK_IFID_FROM_NAME
* \param ifname The name of the interface
* \return The interface ID which corresponds to ifname
@@ -247,6 +259,7 @@
private:
std::string m_clickFile;
+ std::map < std::string, std::string > m_defines;
std::string m_nodeName;
std::string m_clickRoutingTableElement;