1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  *
16  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
17  */
18 
19 #include "ns3/string.h"
20 #include "nsc-sysctl.h"
21 
22 #include "sim_interface.h"
23 
24 namespace ns3 {
25 
26 /**
27  * \ingroup nsctcp
28  *
29  * This object represent the underlying nsc stack attributes and
30  * provide a ns-3-like system to access them though sysctls
31  */
32 class NscStackStringAccessor : public AttributeAccessor
33 {
34 public:
35   /**
36    * \brief Constructor
37    * \param name name of the attribute
38    */
NscStackStringAccessor(std::string name)39   NscStackStringAccessor (std::string name) : m_name (name) {}
40 
41   virtual bool Set (ObjectBase * object, const AttributeValue &val) const;
42   virtual bool Get (const ObjectBase * object, AttributeValue &val) const;
43   virtual bool HasGetter (void) const;
44   virtual bool HasSetter (void) const;
45 private:
46   std::string m_name; //!< name of the attribute
47 };
48 
HasGetter(void) const49 bool NscStackStringAccessor::HasGetter (void) const
50 {
51   return true;
52 }
53 
HasSetter(void) const54 bool NscStackStringAccessor::HasSetter (void) const
55 {
56   return true;
57 }
58 
59 
Set(ObjectBase * object,const AttributeValue & val) const60 bool NscStackStringAccessor::Set (ObjectBase * object, const AttributeValue & val) const
61 {
62   const StringValue *value = dynamic_cast<const StringValue *> (&val);
63   if (value == 0)
64     {
65       return false;
66     }
67   Ns3NscStack *obj = dynamic_cast<Ns3NscStack *> (object);
68   if (obj == 0)
69     {
70       return false;
71     }
72   obj->Set (m_name, value->Get ());
73   return true;
74 }
75 
Get(const ObjectBase * object,AttributeValue & val) const76 bool NscStackStringAccessor::Get (const ObjectBase * object, AttributeValue &val) const
77 {
78   StringValue *value = dynamic_cast<StringValue *> (&val);
79   if (value == 0)
80     {
81       return false;
82     }
83   const Ns3NscStack *obj = dynamic_cast<const Ns3NscStack *> (object);
84   if (obj == 0)
85     {
86       return false;
87     }
88   value->Set (obj->Get (m_name));
89   return true;
90 }
91 
92 
93 TypeId
GetInstanceTypeId(void) const94 Ns3NscStack::GetInstanceTypeId (void) const
95 {
96   if (m_stack == 0)
97     {
98       // if we have no stack, we are a normal NscStack without any attributes.
99       return GetTypeId ();
100     }
101   std::string name = "ns3::Ns3NscStack<";
102   name += m_stack->get_name ();
103   name += ">";
104   TypeId tid;
105   if (TypeId::LookupByNameFailSafe (name, &tid))
106     {
107       // if the relevant TypeId has already been registered, no need to do it again.
108       return tid;
109     }
110   else
111     {
112       // Now, we register a new TypeId for this stack which will look
113       // like a subclass of the Ns3NscStack. The class Ns3NscStack is effectively
114       // mutating into a subclass of itself from the point of view of the TypeId
115       // system _here_
116       tid = TypeId (name.c_str ());
117       tid.SetParent<Ns3NscStack> ();
118       char buf[256];
119       for (int i=0; m_stack->sysctl_getnum (i, buf, sizeof(buf)) > 0; i++)
120         {
121           char value[256];
122           if (m_stack->sysctl_get (buf, value, sizeof(value)) > 0)
123             {
124               tid.AddAttribute (buf, "Help text",
125                                 StringValue (value),
126                                 Create<NscStackStringAccessor> (buf),
127                                 MakeStringChecker ());
128             }
129         }
130       return tid;
131     }
132 }
133 
134 std::string
Get(std::string name) const135 Ns3NscStack::Get (std::string name) const
136 {
137   char buf[512];
138   if (m_stack->sysctl_get (name.c_str (), buf, sizeof(buf)) <= 0)
139     { // name.c_str () is not a valid sysctl name, or internal NSC error (eg. error converting value)
140       return NULL;
141     }
142   return std::string (buf);
143 }
144 
145 void
Set(std::string name,std::string value)146 Ns3NscStack::Set (std::string name, std::string value)
147 {
148   int ret = m_stack->sysctl_set (name.c_str (), value.c_str ());
149   if (ret < 0)
150     {
151       NS_FATAL_ERROR ("setting " << name << " to " << value << "failed (retval " << ret << ")");
152     }
153 }
154 
155 NS_OBJECT_ENSURE_REGISTERED (Ns3NscStack);
156 
157 TypeId
GetTypeId(void)158 Ns3NscStack::Ns3NscStack::GetTypeId (void)
159 {
160   static TypeId tid = TypeId ("ns3::Ns3NscStack")
161     .SetParent<Object> ()
162   ;
163   return tid;
164 }
165 
166 } // namespace ns3
167