src/node/nsc-sysctl.cc
author Florian Westphal <fw@strlen.de>
Wed Jul 15 18:46:14 2009 +0200 (2009-07-15)
changeset 4685 ae536d9e0d6d
permissions -rw-r--r--
nsc: move nsc glue code from nsc-tcp-l4-protocol to node/nsc-glue.cc.

known problems:
- sim_interface.h is duplicated
- nsc-glue.cc adds hooks in node.cc, "hijacks" incoming packets
- nsc-glue exports NSCs INetStack (instead of wrapping it completely)
- nsc-tcp-l4-protocol and nsc-tcp-socket-impl make calls into nsc-glue
- nsc-tcp-socket-impl should really be "nsc-socket-core" (or something
like that)

needs fixing on nsc side:
- no support for multiple interfaces yet (also not yet supported
on nsc side)
- nsc initialisation still tied to IP (Adding an Interface and assigning the
IP address is a single step; it should be separate)

maybe there is more.

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