doc/manual/attributes.texi
changeset 5431 01a657b8d1ef
parent 4755 04a9a7e9a624
child 6238 e2389ba92eae
equal deleted inserted replaced
5430:f69bac4906a5 5431:01a657b8d1ef
   123   ...
   123   ...
   124 @end verbatim
   124 @end verbatim
   125 
   125 
   126 This is defined in the node.cc file as follows:
   126 This is defined in the node.cc file as follows:
   127 
   127 
   128 @verbatim
   128 @smallformat
       
   129 @example
   129 TypeId 
   130 TypeId 
   130 Node::GetTypeId (void)
   131 Node::GetTypeId (void)
   131 {
   132 {
   132   static TypeId tid = TypeId ("ns3::Node")
   133   static TypeId tid = TypeId ("ns3::Node")
   133     .SetParent<Object> ()
   134     .SetParent<Object> ()
   146                    MakeUintegerAccessor (&Node::m_id),
   147                    MakeUintegerAccessor (&Node::m_id),
   147                    MakeUintegerChecker<uint32_t> ())
   148                    MakeUintegerChecker<uint32_t> ())
   148     ;
   149     ;
   149   return tid;
   150   return tid;
   150 }
   151 }
   151 @end verbatim
   152 @end example
   152 
   153 @end smallformat
   153 Look at the TypeId of an ns-3 @code{Object} class as an extended form of run 
   154 
   154 time type information (RTTI).  The C++ language includes simple kind of RTTI
   155 Consider the TypeId of an ns-3 @code{Object} class as an extended form of run 
       
   156 time type information (RTTI).  The C++ language includes a simple kind of RTTI
   155 in order to support @code{dynamic_cast} and @code{typeid} operators.
   157 in order to support @code{dynamic_cast} and @code{typeid} operators.
   156 
   158 
   157 The ``@code{.SetParent<Object> ()}'' call in the declaration above is used in 
   159 The ``@code{.SetParent<Object> ()}'' call in the declaration above is used in 
   158 conjunction with our object aggregation mechanisms to allow safe up- and
   160 conjunction with our object aggregation mechanisms to allow safe up- and
   159 down-casing in inheritance trees during @code{GetObject}.
   161 down-casting in inheritance trees during @code{GetObject}.
   160 
   162 
   161 The ``@code{.AddConstructor<Node> ()}'' call is used in conjunction with our
   163 The ``@code{.AddConstructor<Node> ()}'' call is used in conjunction with our
   162 abstract object factory mechanisms to allow us to construct C++ objects without
   164 abstract object factory mechanisms to allow us to construct C++ objects without
   163 forcing a user to know the concrete class of the object she is building.
   165 forcing a user to know the concrete class of the object she is building.
   164 
   166 
   181 without even knowing the concrete C++ type
   183 without even knowing the concrete C++ type
   182 
   184 
   183 @verbatim
   185 @verbatim
   184   ObjectFactory factory;
   186   ObjectFactory factory;
   185   const std::string typeId = "ns3::Node'';
   187   const std::string typeId = "ns3::Node'';
   186   factory.SetTypeId(typeId);
   188   factory.SetTypeId (typeId);
   187   Ptr<Object> node = factory.Create <Object> ();
   189   Ptr<Object> node = factory.Create <Object> ();
   188 @end verbatim
   190 @end verbatim
   189 
   191 
   190 Both of these methods result in fully initialized attributes being available 
   192 Both of these methods result in fully initialized attributes being available 
   191 in the resulting @code{Object} instances.
   193 in the resulting @code{Object} instances.
   257 and some type of global default value.
   259 and some type of global default value.
   258 
   260 
   259 In the ns-3 attribute system, these value definitions and accessor
   261 In the ns-3 attribute system, these value definitions and accessor
   260 functions are moved into the TypeId class; e.g.:  
   262 functions are moved into the TypeId class; e.g.:  
   261 
   263 
   262 @verbatim
   264 @smallformat
       
   265 @example
   263 NS_OBJECT_ENSURE_REGISTERED (DropTailQueue);
   266 NS_OBJECT_ENSURE_REGISTERED (DropTailQueue);
   264 
   267 
   265 TypeId DropTailQueue::GetTypeId (void) 
   268 TypeId DropTailQueue::GetTypeId (void) 
   266 {
   269 {
   267   static TypeId tid = TypeId ("ns3::DropTailQueue")
   270   static TypeId tid = TypeId ("ns3::DropTailQueue")
   274                    MakeUintegerChecker<uint32_t> ())
   277                    MakeUintegerChecker<uint32_t> ())
   275     ;
   278     ;
   276   
   279   
   277   return tid;
   280   return tid;
   278 }
   281 }
   279 @end verbatim
   282 @end example
       
   283 @end smallformat
   280 
   284 
   281 The AddAttribute() method is performing a number of things with this
   285 The AddAttribute() method is performing a number of things with this
   282 value:
   286 value:
   283 @itemize @bullet
   287 @itemize @bullet
   284 @item Binding the variable m_maxPackets to a string "MaxPackets"
   288 @item Binding the variable m_maxPackets to a string "MaxPackets"
   293 strings such as "MaxPackets" and TypeId strings.  In the next
   297 strings such as "MaxPackets" and TypeId strings.  In the next
   294 section, we will provide an example script that shows how users
   298 section, we will provide an example script that shows how users
   295 may manipulate these values.
   299 may manipulate these values.
   296 
   300 
   297 Note that initialization of the attribute relies on the macro
   301 Note that initialization of the attribute relies on the macro
   298 NS_OBJECT_ENSURE_REGISTERED (DropTailQueue) being called; if you leave
   302 @code{NS_OBJECT_ENSURE_REGISTERED} (DropTailQueue) being called; if you leave
   299 this out of your new class implementation, your attributes will not be 
   303 this out of your new class implementation, your attributes will not be 
   300 initialized correctly.
   304 initialized correctly.
   301 
   305 
   302 @subsection Basic usage
   306 While we have described how to create attributes, we still haven't
       
   307 described how to access and manage these values.  For instance, there is no 
       
   308 @code{globals.h} header file where these are stored; attributes are
       
   309 stored with their classes.  Questions that naturally arise are how
       
   310 do users easily learn about all of the attributes of their models, and
       
   311 how does a user access these attributes, or document their values 
       
   312 as part of the record of their simulation?
       
   313 
       
   314 @subsection Default values and command-line arguments
   303 
   315 
   304 Let's look at how a user script might access these values.  
   316 Let's look at how a user script might access these values.  
   305 This is based on the script found at @code{samples/main-attribute-value.cc},
   317 This is based on the script found at @code{samples/main-attribute-value.cc},
   306 with some details stripped out.
   318 with some details stripped out.
   307 @verbatim
   319 @verbatim
   339 
   351 
   340 Now, we will create a few objects using the low-level API; here,
   352 Now, we will create a few objects using the low-level API; here,
   341 our newly created queues will not have a m_maxPackets initialized to
   353 our newly created queues will not have a m_maxPackets initialized to
   342 100 packets but to 80 packets, because of what we did above with
   354 100 packets but to 80 packets, because of what we did above with
   343 default values.
   355 default values.
   344 @verbatim
   356 @smallformat
       
   357 @example
   345   Ptr<Node> n0 = CreateObject<Node> ();
   358   Ptr<Node> n0 = CreateObject<Node> ();
   346 
   359 
   347   Ptr<PointToPointNetDevice> net0 = CreateObject<PointToPointNetDevice> ();
   360   Ptr<PointToPointNetDevice> net0 = CreateObject<PointToPointNetDevice> ();
   348   n0->AddDevice (net0);
   361   n0->AddDevice (net0);
   349 
   362 
   350   Ptr<Queue> q = CreateObject<DropTailQueue> ();
   363   Ptr<Queue> q = CreateObject<DropTailQueue> ();
   351   net0->AddQueue(q);
   364   net0->AddQueue(q);
   352 @end verbatim
   365 @end example
       
   366 @end smallformat
   353 
   367 
   354 At this point, we have created a single node (Node 0) and a 
   368 At this point, we have created a single node (Node 0) and a 
   355 single PointToPointNetDevice (NetDevice 0) and added a 
   369 single PointToPointNetDevice (NetDevice 0) and added a 
   356 DropTailQueue to it.
   370 DropTailQueue to it.
   357 
   371 
   358 Now, we can manipulate the MaxPackets value of the already 
   372 Now, we can manipulate the MaxPackets value of the already 
   359 instantiated DropTailQueue.  Here are various ways to do that.
   373 instantiated DropTailQueue.  Here are various ways to do that.
   360 
   374 
   361 @subsubsection Pointer-based access
   375 @subsection Pointer-based access
   362 
   376 
   363 We assume that a smart pointer (Ptr) to a relevant network device is 
   377 We assume that a smart pointer (Ptr) to a relevant network device is 
   364 in hand; here, it is the net0 pointer. 
   378 in hand; in the current example, it is the @code{net0} pointer. 
   365 
   379 
   366 One way to change the value is to access a pointer to the
   380 One way to change the value is to access a pointer to the
   367 underlying queue and modify its attribute.
   381 underlying queue and modify its attribute.
   368  
   382  
   369 First, we observe that we can get a pointer to the (base class)
   383 First, we observe that we can get a pointer to the (base class)
   370 queue via the PointToPointNetDevice attributes, where it is called
   384 queue via the PointToPointNetDevice attributes, where it is called
   371 TxQueue 
   385 TxQueue 
   372 @verbatim
   386 @example
   373   PointerValue tmp;
   387   PointerValue tmp;
   374   net0->GetAttribute ("TxQueue", tmp);
   388   net0->GetAttribute ("TxQueue", tmp);
   375   Ptr<Object> txQueue = tmp.GetObject ();
   389   Ptr<Object> txQueue = tmp.GetObject ();
   376 @end verbatim
   390 @end example
   377 
   391 
   378 Using the GetObject function, we can perform a safe downcast
   392 Using the GetObject function, we can perform a safe downcast
   379 to a DropTailQueue, where MaxPackets is a member
   393 to a DropTailQueue, where MaxPackets is a member
   380 @verbatim
   394 @verbatim
   381   Ptr<DropTailQueue> dtq = txQueue->GetObject <DropTailQueue> ();
   395   Ptr<DropTailQueue> dtq = txQueue->GetObject <DropTailQueue> ();
   407   txQueue->SetAttribute("MaxPackets", UintegerValue (60));
   421   txQueue->SetAttribute("MaxPackets", UintegerValue (60));
   408   txQueue->GetAttribute ("MaxPackets", limit);
   422   txQueue->GetAttribute ("MaxPackets", limit);
   409   NS_LOG_INFO ("3.  txQueue limit changed: " << limit.Get () << " packets");
   423   NS_LOG_INFO ("3.  txQueue limit changed: " << limit.Get () << " packets");
   410 @end verbatim
   424 @end verbatim
   411 
   425 
   412 @subsubsection Namespace-based access
   426 @subsection Namespace-based access
   413 
   427 
   414 An alternative way to get at the attribute is to use the configuration namespace.
   428 An alternative way to get at the attribute is to use the configuration namespace.
   415 Here, this attribute resides on a known path in this namespace; this approach
   429 Here, this attribute resides on a known path in this namespace; this approach
   416 is useful if one doesn't have access to the underlying pointers and would like
   430 is useful if one doesn't have access to the underlying pointers and would like
   417 to configure a specific attribute with a single statement.  
   431 to configure a specific attribute with a single statement.  
   418 
   432 
   419 @verbatim
   433 @smallformat
       
   434 @example
   420   Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25));
   435   Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25));
   421   txQueue->GetAttribute ("MaxPackets", limit); 
   436   txQueue->GetAttribute ("MaxPackets", limit); 
   422   NS_LOG_INFO ("4.  txQueue limit changed through namespace: " << 
   437   NS_LOG_INFO ("4.  txQueue limit changed through namespace: " << 
   423     limit.Get () << " packets");
   438     limit.Get () << " packets");
   424 @end verbatim
   439 @end example
       
   440 @end smallformat
   425 
   441 
   426 We could have also used wildcards to set this value for all nodes and all net 
   442 We could have also used wildcards to set this value for all nodes and all net 
   427 devices (which in this simple example has the same effect as the previous Set())
   443 devices (which in this simple example has the same effect as the previous Set())
   428 @verbatim
   444 @smallformat
       
   445 @example
   429   Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15));
   446   Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15));
   430   txQueue->GetAttribute ("MaxPackets", limit); 
   447   txQueue->GetAttribute ("MaxPackets", limit); 
   431   NS_LOG_INFO ("5.  txQueue limit changed through wildcarded namespace: " << 
   448   NS_LOG_INFO ("5.  txQueue limit changed through wildcarded namespace: " << 
   432     limit.Get () << " packets");
   449     limit.Get () << " packets");
   433 @end verbatim
   450 @end example
   434 
   451 @end smallformat
   435 @subsubsection Object Name Service-based access
   452 
       
   453 @subsection Object Name Service-based access
   436 
   454 
   437 Another way to get at the attribute is to use the object name service facility.
   455 Another way to get at the attribute is to use the object name service facility.
   438 Here, this attribute is found using a name string.  This approach is useful if 
   456 Here, this attribute is found using a name string.  This approach is useful if 
   439 one doesn't have access to the underlying pointers and it is difficult to 
   457 one doesn't have access to the underlying pointers and it is difficult to 
   440 determine the required concrete configuration namespaced path.
   458 determine the required concrete configuration namespaced path.
   441 
   459 
   442 @verbatim
   460 @smallformat
       
   461 @example
   443   Names::Add ("server", serverNode);
   462   Names::Add ("server", serverNode);
   444   Names::Add ("server/eth0", serverDevice);
   463   Names::Add ("server/eth0", serverDevice);
   445 
   464 
   446   ...
   465   ...
   447 
   466 
   448   Config::Set ("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue (25));
   467   Config::Set ("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue (25));
   449 @end verbatim
   468 @end example
       
   469 @end smallformat
       
   470 
       
   471 @xref{Object names} for a fuller treatment of the ns-3 configuration namespace.
   450 
   472 
   451 @subsection Setting through constructors helper classes
   473 @subsection Setting through constructors helper classes
   452 
   474 
   453 Arbitrary combinations of attributes can be set and fetched from
   475 Arbitrary combinations of attributes can be set and fetched from
   454 the helper and low-level APIs; either from the constructors themselves:
   476 the helper and low-level APIs; either from the constructors themselves:
   464                                  "DeltaY", DoubleValue (20.0),
   486                                  "DeltaY", DoubleValue (20.0),
   465                                  "GridWidth", UintegerValue (20),
   487                                  "GridWidth", UintegerValue (20),
   466                                  "LayoutType", StringValue ("RowFirst"));
   488                                  "LayoutType", StringValue ("RowFirst"));
   467 @end verbatim
   489 @end verbatim
   468 
   490 
   469 @subsection Value classes
   491 @subsection Implementation details
       
   492 @subsubsection Value classes
   470 Readers will note the new FooValue classes which are subclasses of the
   493 Readers will note the new FooValue classes which are subclasses of the
   471 AttributeValue base class.  These can be thought of as
   494 AttributeValue base class.  These can be thought of as
   472 an intermediate class that can be used to convert from raw types to the
   495 an intermediate class that can be used to convert from raw types to the
   473 Values that are used by the attribute system.  Recall that this database is holding
   496 Values that are used by the attribute system.  Recall that this database is holding
   474 objects of many types with a single generic type.  Conversions to this
   497 objects of many types with a single generic type.  Conversions to this
   487 @itemize @bullet
   510 @itemize @bullet
   488 @item ATTRIBUTE_HELPER_HEADER
   511 @item ATTRIBUTE_HELPER_HEADER
   489 @item ATTRIBUTE_HELPER_CPP
   512 @item ATTRIBUTE_HELPER_CPP
   490 @end itemize
   513 @end itemize
   491 
   514 
   492 @subsection Initialization order
   515 @subsubsection Initialization order
   493 
   516 
   494 In general, the attribute code to assign values to the underlying
   517 In general, the attribute code to assign values to the underlying
   495 class member variables is executed after an object is constructed.
   518 class member variables is executed after an object is constructed.
   496 But what if you need the values assigned before the constructor
   519 But what if you need the values assigned before the constructor
   497 body executes, because you need them in the logic of the constructor?
   520 body executes, because you need them in the logic of the constructor?
   498 There is a way to do this, used for example in the class 
   521 There is a way to do this, used for example in the class 
   499 @code{ns3::ConfigStore}:  call @code{ObjectBase::ConstructSelf()}
   522 @code{ns3::ConfigStore}:  call @code{ObjectBase::ConstructSelf ()}
   500 as follows:
   523 as follows:
   501 
   524 
   502 @verbatim
   525 @verbatim
   503 ConfigStore::ConfigStore ()
   526 ConfigStore::ConfigStore ()
   504 {
   527 {
   544 
   567 
   545 Here, we discuss the impact on a user who wants to add a new class to
   568 Here, we discuss the impact on a user who wants to add a new class to
   546 ns-3; what additional things must be done to hook it into this system.
   569 ns-3; what additional things must be done to hook it into this system.
   547 
   570 
   548 We've already introduced what a TypeId definition looks like:
   571 We've already introduced what a TypeId definition looks like:
   549 @verbatim
   572 @smallformat
       
   573 @example
   550 TypeId
   574 TypeId
   551 RandomWalk2dMobilityModel::GetTypeId (void)
   575 RandomWalk2dMobilityModel::GetTypeId (void)
   552 {
   576 {
   553   static TypeId tid = TypeId ("ns3::RandomWalk2dMobilityModel")
   577   static TypeId tid = TypeId ("ns3::RandomWalk2dMobilityModel")
   554     .SetParent<MobilityModel> ()
   578     .SetParent<MobilityModel> ()
   566                    MakeTimeChecker ())
   590                    MakeTimeChecker ())
   567     // etc (more parameters).
   591     // etc (more parameters).
   568     ;
   592     ;
   569   return tid;
   593   return tid;
   570 }
   594 }
   571 @end verbatim
   595 @end example
       
   596 @end smallformat
   572 
   597 
   573 The declaration for this in the class declaration is one-line public
   598 The declaration for this in the class declaration is one-line public
   574 member method:
   599 member method:
   575 @verbatim
   600 @verbatim
   576  public:
   601  public:
   597 of writing 
   622 of writing 
   598 the conversions to/from strings and attribute values.  Most of this can be
   623 the conversions to/from strings and attribute values.  Most of this can be
   599 copy/pasted with macro-ized code.  For instance, consider class
   624 copy/pasted with macro-ized code.  For instance, consider class
   600 declaration for Rectangle in the @code{src/mobility/} directory:
   625 declaration for Rectangle in the @code{src/mobility/} directory:
   601 
   626 
   602 @verbatim
   627 @subsection Header file
       
   628 @smallformat
       
   629 @example
   603 /**
   630 /**
   604  * \brief a 2d rectangle
   631  * \brief a 2d rectangle
   605  */
   632  */
   606 class Rectangle
   633 class Rectangle
   607 {
   634 {
   610   double xMin;
   637   double xMin;
   611   double xMax;
   638   double xMax;
   612   double yMin;
   639   double yMin;
   613   double yMax;
   640   double yMax;
   614 };
   641 };
   615 @end verbatim
   642 @end example
       
   643 @end smallformat
   616  
   644  
   617 One macro call and two operators, must be added below the class declaration
   645 One macro call and two operators, must be added below the class declaration
   618 in order to turn a Rectangle into a value usable by the @code{Attribute}
   646 in order to turn a Rectangle into a value usable by the @code{Attribute}
   619 system:
   647 system:
   620 
   648 
   621 @verbatim
   649 @smallformat
       
   650 @example
   622 std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
   651 std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
   623 std::istream &operator >> (std::istream &is, Rectangle &rectangle);
   652 std::istream &operator >> (std::istream &is, Rectangle &rectangle);
   624 
   653 
   625 ATTRIBUTE_HELPER_HEADER (Rectangle);
   654 ATTRIBUTE_HELPER_HEADER (Rectangle);
   626 @end verbatim
   655 @end example
   627 
   656 @end smallformat
       
   657 
       
   658 @subsection Implementation file
   628 In the class definition (@code{.cc} file), the code looks like this:
   659 In the class definition (@code{.cc} file), the code looks like this:
   629 
   660 
   630 @verbatim
   661 @smallformat
       
   662 @example
   631 ATTRIBUTE_HELPER_CPP (Rectangle);
   663 ATTRIBUTE_HELPER_CPP (Rectangle);
   632 
   664 
   633 std::ostream &
   665 std::ostream &
   634 operator << (std::ostream &os, const Rectangle &rectangle)
   666 operator << (std::ostream &os, const Rectangle &rectangle)
   635 {
   667 {
   636   os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
   668   os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|"
       
   669      << rectangle.yMax;
   637   return os;
   670   return os;
   638 }
   671 }
   639 std::istream &
   672 std::istream &
   640 operator >> (std::istream &is, Rectangle &rectangle)
   673 operator >> (std::istream &is, Rectangle &rectangle)
   641  {
   674  {
   642   char c1, c2, c3;
   675   char c1, c2, c3;
   643   is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
   676   is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 
       
   677      >> rectangle.yMax;
   644   if (c1 != '|' ||
   678   if (c1 != '|' ||
   645       c2 != '|' ||
   679       c2 != '|' ||
   646       c3 != '|')
   680       c3 != '|')
   647     {
   681     {
   648       is.setstate (std::ios_base::failbit);
   682       is.setstate (std::ios_base::failbit);
   649     }
   683     }
   650   return is;
   684   return is;
   651 }
   685 }
   652 @end verbatim
   686 @end example
       
   687 @end smallformat
   653 
   688 
   654 These stream operators simply convert from a string representation of the
   689 These stream operators simply convert from a string representation of the
   655 Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the
   690 Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the
   656 modeler must specify these operators and the string syntactical representation 
   691 modeler must specify these operators and the string syntactical representation 
   657 of an instance of the new class.
   692 of an instance of the new class.
   677 @end verbatim
   712 @end verbatim
   678 
   713 
   679 Let's edit it to add the ConfigStore feature.  First, add an include statement 
   714 Let's edit it to add the ConfigStore feature.  First, add an include statement 
   680 to include the contrib module, and then add these lines:
   715 to include the contrib module, and then add these lines:
   681 
   716 
   682 @verbatim
   717 @smallformat
       
   718 @example
   683 #include "contrib-module.h"
   719 #include "contrib-module.h"
   684 ...
   720 ...
   685 int main (...)
   721 int main (...)
   686 {
   722 {
   687   // setup topology
   723   // setup topology
   691   config.ConfigureDefaults ();
   727   config.ConfigureDefaults ();
   692   config.ConfigureAttributes ();
   728   config.ConfigureAttributes ();
   693 
   729 
   694   Simulator::Run ();
   730   Simulator::Run ();
   695 }
   731 }
   696 @end verbatim
   732 @end example
       
   733 @end smallformat
   697 
   734 
   698 There are three attributes that govern the behavior of the ConfigStore:
   735 There are three attributes that govern the behavior of the ConfigStore:
   699 "Mode", "Filename", and "FileFormat".  The Mode (default "None") configures
   736 "Mode", "Filename", and "FileFormat".  The Mode (default "None") configures
   700 whether ns-3 should load configuration from a previously saved file
   737 whether ns-3 should load configuration from a previously saved file
   701 (specify "Mode=Load") or save it to a file (specify "Mode=Save").
   738 (specify "Mode=Load") or save it to a file (specify "Mode=Save").
   703 output data.  The FileFormat (default "RawText") governs whether
   740 output data.  The FileFormat (default "RawText") governs whether
   704 the ConfigStore format is Xml or RawText format.
   741 the ConfigStore format is Xml or RawText format.
   705 
   742 
   706 So, using the above modified program, try executing the following
   743 So, using the above modified program, try executing the following
   707 waf command and 
   744 waf command and 
   708 @verbatim
   745 @smallformat
   709 ./waf --command-template="%s --ns3::ConfigStore::Filename=csma-bridge-config.xml --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=Xml" --run scratch/csma-bridge
   746 @example
   710 @end verbatim
   747 ./waf --command-template="%s --ns3::ConfigStore::Filename=csma-bridge-config.xml
       
   748 --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=Xml" --run scratch/csma-bridge
       
   749 @end example
       
   750 @end smallformat
   711 After running, you can open the csma-bridge-config.xml file and it will
   751 After running, you can open the csma-bridge-config.xml file and it will
   712 display the configuration that was applied to your simulation; e.g.
   752 display the configuration that was applied to your simulation; e.g.
   713 @verbatim
   753 @smallformat
       
   754 @example
   714 <?xml version="1.0" encoding="UTF-8"?>
   755 <?xml version="1.0" encoding="UTF-8"?>
   715 <ns3>
   756 <ns3>
   716  <default name="ns3::V4Ping::Remote" value="102.102.102.102"/>
   757  <default name="ns3::V4Ping::Remote" value="102.102.102.102"/>
   717  <default name="ns3::MsduStandardAggregator::MaxAmsduSize" value="7935"/>
   758  <default name="ns3::MsduStandardAggregator::MaxAmsduSize" value="7935"/>
   718  <default name="ns3::EdcaTxopN::MinCw" value="31"/>
   759  <default name="ns3::EdcaTxopN::MinCw" value="31"/>
   721  <default name="ns3::QstaWifiMac::ProbeRequestTimeout" value="50000000ns"/>
   762  <default name="ns3::QstaWifiMac::ProbeRequestTimeout" value="50000000ns"/>
   722  <default name="ns3::QstaWifiMac::AssocRequestTimeout" value="500000000ns"/>
   763  <default name="ns3::QstaWifiMac::AssocRequestTimeout" value="500000000ns"/>
   723  <default name="ns3::QstaWifiMac::MaxMissedBeacons" value="10"/>
   764  <default name="ns3::QstaWifiMac::MaxMissedBeacons" value="10"/>
   724  <default name="ns3::QstaWifiMac::ActiveProbing" value="false"/>
   765  <default name="ns3::QstaWifiMac::ActiveProbing" value="false"/>
   725 ...
   766 ...
   726 @end verbatim
   767 @end example
       
   768 @end smallformat
       
   769 
   727 This file can be archived with your simulation script and output data.
   770 This file can be archived with your simulation script and output data.
   728 
   771 
   729 While it is possible to generate a sample config file and lightly
   772 While it is possible to generate a sample config file and lightly
   730 edit it to change a couple of values, there are cases where this
   773 edit it to change a couple of values, there are cases where this
   731 process will not work because the same value on the same object
   774 process will not work because the same value on the same object
   747 "input-defaults.xml", and write out the resulting attributes to a
   790 "input-defaults.xml", and write out the resulting attributes to a
   748 separate file called "output-attributes.xml".  (Note-- to get this
   791 separate file called "output-attributes.xml".  (Note-- to get this
   749 input xml file to begin with, it is sometimes helpful to run the
   792 input xml file to begin with, it is sometimes helpful to run the
   750 program to generate an output xml file first, then hand-edit that
   793 program to generate an output xml file first, then hand-edit that
   751 file and re-input it for the next simulation run).
   794 file and re-input it for the next simulation run).
   752 @verbatim
   795 @smallformat
       
   796 @example
   753 #include "contrib-module.h"
   797 #include "contrib-module.h"
   754 ...
   798 ...
   755 int main (...)
   799 int main (...)
   756 {
   800 {
   757 
   801 
   776   Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
   820   Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
   777   ConfigStore outputConfig;
   821   ConfigStore outputConfig;
   778   outputConfig.ConfigureAttributes ();
   822   outputConfig.ConfigureAttributes ();
   779   Simulator::Run ();
   823   Simulator::Run ();
   780 }
   824 }
   781 @end verbatim
   825 @end example
       
   826 @end smallformat
   782 
   827 
   783 @subsection GTK-based ConfigStore
   828 @subsection GTK-based ConfigStore
   784 
   829 
   785 There is a GTK-based front end for the ConfigStore.  This allows users
   830 There is a GTK-based front end for the ConfigStore.  This allows users
   786 to use a GUI to access and change variables.  Screenshots of this
   831 to use a GUI to access and change variables.  Screenshots of this
   792 @verbatim
   837 @verbatim
   793 sudo apt-get install libgtk2.0-0 libgtk2.0-dev
   838 sudo apt-get install libgtk2.0-0 libgtk2.0-dev
   794 @end verbatim
   839 @end verbatim
   795 To check whether it is configured or not, check the output of the
   840 To check whether it is configured or not, check the output of the
   796 ./waf configure step:
   841 ./waf configure step:
   797 @verbatim
   842 @smallformat
       
   843 @example
   798 ---- Summary of optional NS-3 features:
   844 ---- Summary of optional NS-3 features:
   799 Threading Primitives          : enabled
   845 Threading Primitives          : enabled
   800 Real Time Simulator           : enabled
   846 Real Time Simulator           : enabled
   801 GtkConfigStore                : not enabled (library 'gtk+-2.0 >= 2.12' not found)
   847 GtkConfigStore                : not enabled (library 'gtk+-2.0 >= 2.12' not found)
   802 @end verbatim
   848 @end example
       
   849 @end smallformat
   803 
   850 
   804 In the above example, it was not enabled, so it cannot be used until a
   851 In the above example, it was not enabled, so it cannot be used until a
   805 suitable version is installed and ./waf configure; ./waf is rerun.
   852 suitable version is installed and ./waf configure; ./waf is rerun.
   806 
   853 
   807 Usage is almost the same as the non-GTK-based version, but there
   854 Usage is almost the same as the non-GTK-based version, but there
   808 are no ConfigStore attributes involved:
   855 are no ConfigStore attributes involved:
   809 @verbatim
   856 @smallformat
       
   857 @example
   810   // Invoke just before entering Simulator::Run ()
   858   // Invoke just before entering Simulator::Run ()
   811   GtkConfigStore config;
   859   GtkConfigStore config;
   812   config.ConfigureDefaults ();
   860   config.ConfigureDefaults ();
   813   config.ConfigureAttributes ();
   861   config.ConfigureAttributes ();
   814 @end verbatim
   862 @end example
       
   863 @end smallformat
   815 
   864 
   816 Now, when you run the script, a GUI should pop up, allowing you to open
   865 Now, when you run the script, a GUI should pop up, allowing you to open
   817 menus of attributes on different nodes/objects, and then launch the
   866 menus of attributes on different nodes/objects, and then launch the
   818 simulation execution when you are done.  
   867 simulation execution when you are done.  
   819 
   868